Gdiplus :: Bitmap到BYTE数组?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gdiplus :: Bitmap到BYTE数组?相关的知识,希望对你有一定的参考价值。

这是我的尝试(丑陋的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,但我真的不明白怎么做。我试过了,但是我失败了,所以我也不打算发布那个尝试。

答案

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

另一答案

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

#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;
}
另一答案

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

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

Gdiplus::Bitmap  cBitmap(width, height, stride, PixelFormat32bppRGB, bytes);
另一答案

以下是使用标头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;
    }

以上是关于Gdiplus :: Bitmap到BYTE数组?的主要内容,如果未能解决你的问题,请参考以下文章

Gdiplus::Bitmap::FromHICON 失败

保存的 Gdiplus::Bitmap 始终具有 Alpha 通道 (RGBA/ARGB)

为啥我的 Gdiplus::Bitmap 不能保存文件

C++ GDIPlus 位图锁定位结果 WrongState(8)

C# byte数组转成Bitmap对象

Android-DrawableBitmapbyte[]资源文件相互转换