Gdiplus :: Растровое изображение в массив BYTE? - PullRequest
8 голосов
/ 27 июля 2010

Вот моя попытка (безобразный GDI + и GDI mix ...)

// ...
BYTE               pixels[BMP_WIDTH * BMP_HEIGHT * BMP_BPP];
HBITMAP            hBitmap;
Gdiplus::Bitmap    cBitmap(BMP_WIDTH, BMP_HEIGHT, PixelFormat32bppRGB);
Gdiplus::Graphics  cGraphics(&cBitmap);
Gdiplus::Pen       cPen(Gdiplus::Color(255, 255, 0, 0));

cGraphics.DrawRectangle(&cPen, 0, 0, cBitmap.GetWidth() - 1, cBitmap.GetHeight() - 1);

// and here it get's real ugly, I'd like to change that...
cBitmap.GetHBITMAP(Gdiplus::Color(255, 255, 255), &hBitmap);
GetBitmapBits(hBitmap, sizeof(pixels), pixels);
// ...

Кто-то сказал мне использовать LockBits, но я действительно не понял, как. Я попробовал это сделать, но потерпел неудачу, поэтому я не собираюсь публиковать и эту попытку.

Ответы [ 4 ]

7 голосов
/ 27 июля 2010

Вы можете использовать Bitmap::LockBits, чтобы получить доступ к необработанному массиву данных. Здесь вы можете прочитать о том, как использовать Bitmap::LockBits.

5 голосов
/ 23 сентября 2016

Следующий код получает все пиксели изображения:

#include <vector>
using namespace std;

    vector<vector<UINT>> get_pixels(const wchar_t * name, int &Width, int &Height) {


    Bitmap* bitmap = new Bitmap(name);
    Width = bitmap->GetWidth();
    Height = bitmap->GetHeight();

    BitmapData* bitmapData = new BitmapData;

    Rect rect(0, 0, Width, Height);

    bitmap->LockBits(&rect, ImageLockModeRead, PixelFormat32bppARGB , bitmapData);


    UINT*  pixels = (UINT*)bitmapData->Scan0;


    vector<vector<UINT>>  result_pixels(Width, vector<UINT>(Height));

    INT iStride =abs(bitmapData->Stride);

    for (UINT col = 0; col < Width; ++col)
        for (UINT row = 0; row < Height; ++row)
        {


            unsigned int curColor = pixels[row * iStride / 4 + col];
            int b = curColor & 0xff;
            int g = (curColor & 0xff00) >> 8;
            int r = (curColor & 0xff0000) >> 16;
            int a = (curColor & 0xff000000) >> 24;




            result_pixels[col][row] = RGB(r, g, b);

        }


    bitmap->UnlockBits(bitmapData);

    return result_pixels;
}
2 голосов
/ 15 ноября 2013

Вот как я бы это сделал, используя метод GDIPlus Bitmap.LockBits , определенный в заголовке GdiPlusBitmap.h:

Обратите внимание, что поскольку растровые изображения обычно выровнены по DWORD, вы можете отказаться от этогонеиспользованные данные, которые были необходимы для выравнивания, как правильно прокомментировал малат ..

    Gdiplus::BitmapData bitmapData;
    Gdiplus::Rect rect(0, 0, bitmap.GetWidth(), bitmap.GetHeight());

    //get the bitmap data
    if(Gdiplus::Ok == bitmap.LockBits(
                        &rect, //A rectangle structure that specifies the portion of the Bitmap to lock.
                        Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeWrite, //ImageLockMode values that specifies the access level (read/write) for the Bitmap.
                        bitmap.GetPixelFormat(),// PixelFormat values that specifies the data format of the Bitmap.
                        &bitmapData //BitmapData that will contain the information about the lock operation.
                        ))
    {
         //get the lenght of the bitmap data in bytes
         int len = bitmapData.Height * std::abs(bitmapData.Stride);

         BYTE* buffer = new BYTE[len];
         memcpy(bitmapData.Scan0, buffer, len);//copy it to an array of BYTEs

         //... 

         //cleanup
         bitmap.UnlockBits(&bitmapData);        
         delete []buffer;
    }
2 голосов
/ 27 июля 2010

Вы пытались указать байты при создании растрового изображения:

int width = BMP_WIDTH;
int height = BMP_HEIGHT;
int stride = 4 * width;
BYTE bytes[stride * height];

Gdiplus::Bitmap  cBitmap(width, height, stride, PixelFormat32bppRGB, bytes);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...