我需要从一个字节数组创建一个CImage (实际上,它是一个unsigned char数组,但我可以转换成任何需要的形式)。字节数组的形式是“RGBRGBRGB.”。新映像需要包含图像字节的副本,而不是使用字节数组本身的内存。
我尝试过很多不同的方法来实现这一点--包括完成各种HBITMAP创建功能,尝试使用BitBlt --到目前为止还没有什么效果。
要测试该函数是否工作,它应该通过此测试:
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结束。
发布于 2011-07-20 09:26:02
谢谢大家,我终于在你们的帮助下解决了这个问题。它主要涉及@tinman和@Roel关于使用SetDIBitsToDevice()的建议,但它涉及到一些额外的位旋转和内存管理,所以我想在这里分享我的终结点。
在下面的代码中,我假设设置了width、height和Bpp (每个像素的Bytes),并且data是指向RGB像素值数组的指针。
// 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;发布于 2011-07-14 12:36:25
CImage非常灵活地支持DIBs,并且有一个SetPixel()方法,因此您大概可以这样做(前面是未编译的、未经测试的代码):
CImage img;
img.Create(width, height, 24 /* bpp */, 0 /* No alpha channel */);
int nPixel = 0;
for(int row = 0; row < height; row++)
{
for(int col = 0; col < width; col++)
{
BYTE r = imgBits[nPixel++];
BYTE g = imgBits[nPixel++];
BYTE b = imgBits[nPixel++];
img.SetPixel(row, col, RGB(r, g, b));
}
}也许不是最有效的方法,但我认为这是最简单的方法。
发布于 2011-07-18 15:31:41
使用memcpy复制数据,然后根据需要进行SetDIBits或SetDIBitsToDevice。不过,请注意,原始图像数据的扫描线是在4字节的边界上对齐的(IIRC,我这么做已经有几年了),所以您从GetDIBits获得的数据永远不会与原始数据完全相同(很可能,取决于图像大小)。
因此,您很可能需要通过scanline实现memcpy scanline。
https://stackoverflow.com/questions/6691292
复制相似问题