Gdiplus :: Bitmap到BYTE数组?

时间:2010-07-27 00:52:04

标签: c++ gdi+ bitmap

这是我的尝试(丑陋的GDI + GDI混合......)

// ...
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 个答案:

答案 0 :(得分:7)

您可以使用Bitmap::LockBits来访问原始数据数组。 Here您可以阅读有关如何使用Bitmap::LockBits的信息。

答案 1 :(得分:5)

以下代码获取图片的所有像素:

#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 :(得分:2)

您是否尝试在创建位图时提供字节:

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

Gdiplus::Bitmap  cBitmap(width, height, stride, PixelFormat32bppRGB, bytes);

答案 3 :(得分:2)

以下是使用标头GdiPlusBitmap.h中定义的GDIPlus Bitmap.LockBits方法进行的方法:

请注意,由于位图通常是DWORD对齐的,因此可能需要丢弃对齐所需的未使用数据,因为正确评论了malat。

    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;
    }