从字节数组创建CImage
I need to create a CImage from a byte array (actually, its an array of unsigned char
, but I can cast to whatever form is necessary). The byte array is in the form "RGBRGBRGB...". The new image needs to contain a copy of the image bytes, rather than using the memory of the byte array itself.
我试过很多不同的方式实现这一点 - 包括通过各种HBITMAP创建函数,试图使用BitBlt - 到目前为止没有什么工作。
I have tried many different ways of achieving this -- including going through various HBITMAP creation functions, trying to use BitBlt -- and nothing so far has worked.
要测试函数是否工作,它应该通过这个测试:
To test whether the function works, it should pass this test:
BYTE* imgBits;
int width;
int height;
int Bpp; // BYTES per pixel (e.g. 3)
getImage(&imgBits, &width, &height, &Bpp); // get the image bits
// This is the magic function I need!!!
CImage img = createCImage(imgBits, width, height, Bpp);
// Test the image
BYTE* data = img.GetBits(); // data should now have the same data as imgBits
createCImage的所有实现()
到目前为止,结果是 data
指向一个空的(零填充)数组。
All implementations of createCImage()
so far have ended up with data
pointing to an empty (zero filled) array.
感谢大家,我设法在你的帮助下解决它。它主要涉及@tinman和@ Roel的建议,使用 SetDIBitsToDevice()
,但它涉及一些额外的bit-twiddling和内存管理,所以我想我会分享我
Thanks everyone, I managed to solve it in the end with your help. It mainly involved @tinman and @Roel's suggestion to use SetDIBitsToDevice()
, but it involved a bit of extra bit-twiddling and memory management, so I thought I'd share my end-point here.
在下面的代码中,我假设 width
, height c>和
Bpp
(每个像素字节),数据
是指向RGB像素值数组的指针。
In the code below, I assume that width
, height
and Bpp
(Bytes per pixel) are set, and that data
is a pointer to the array of RGB pixel values.
// Create the header info
bmInfohdr.biSize = sizeof(BITMAPINFOHEADER);
bmInfohdr.biWidth = width;
bmInfohdr.biHeight = -height;
bmInfohdr.biPlanes = 1;
bmInfohdr.biBitCount = Bpp*8;
bmInfohdr.biCompression = BI_RGB;
bmInfohdr.biSizeImage = width*height*Bpp;
bmInfohdr.biXPelsPerMeter = 0;
bmInfohdr.biYPelsPerMeter = 0;
bmInfohdr.biClrUsed = 0;
bmInfohdr.biClrImportant = 0;
BITMAPINFO bmInfo;
bmInfo.bmiHeader = bmInfohdr;
bmInfo.bmiColors[0].rgbBlue=255;
// Allocate some memory and some pointers
unsigned char * p24Img = new unsigned char[width*height*3];
BYTE *pTemp,*ptr;
pTemp=(BYTE*)data;
ptr=p24Img;
// Convert image from RGB to BGR
for (DWORD index = 0; index < width*height ; index++)
{
unsigned char r = *(pTemp++);
unsigned char g = *(pTemp++);
unsigned char b = *(pTemp++);
*(ptr++) = b;
*(ptr++) = g;
*(ptr++) = r;
}
// Create the CImage
CImage im;
im.Create(width, height, 24, NULL);
HDC dc = im.GetDC();
SetDIBitsToDevice(dc, 0,0,width,height,0,0, 0, height, p24Img, &bmInfo, DIB_RGB_COLORS);
im.ReleaseDC();
delete[] p24Img;