首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从Byte数组创建CImage

从Byte数组创建CImage
EN

Stack Overflow用户
提问于 2011-07-14 09:47:11
回答 4查看 15.9K关注 0票数 2

我需要从一个字节数组创建一个CImage (实际上,它是一个unsigned char数组,但我可以转换成任何需要的形式)。字节数组的形式是“RGBRGBRGB.”。新映像需要包含图像字节的副本,而不是使用字节数组本身的内存。

我尝试过很多不同的方法来实现这一点--包括完成各种HBITMAP创建功能,尝试使用BitBlt --到目前为止还没有什么效果。

要测试该函数是否工作,它应该通过此测试:

代码语言:javascript
复制
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结束。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-07-20 09:26:02

谢谢大家,我终于在你们的帮助下解决了这个问题。它主要涉及@tinman和@Roel关于使用SetDIBitsToDevice()的建议,但它涉及到一些额外的位旋转和内存管理,所以我想在这里分享我的终结点。

在下面的代码中,我假设设置了widthheightBpp (每个像素的Bytes),并且data是指向RGB像素值数组的指针。

代码语言:javascript
复制
// 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;
票数 1
EN

Stack Overflow用户

发布于 2011-07-14 12:36:25

CImage非常灵活地支持DIBs,并且有一个SetPixel()方法,因此您大概可以这样做(前面是未编译的、未经测试的代码):

代码语言:javascript
复制
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));
    }
}

也许不是最有效的方法,但我认为这是最简单的方法。

票数 1
EN

Stack Overflow用户

发布于 2011-07-18 15:31:41

使用memcpy复制数据,然后根据需要进行SetDIBits或SetDIBitsToDevice。不过,请注意,原始图像数据的扫描线是在4字节的边界上对齐的(IIRC,我这么做已经有几年了),所以您从GetDIBits获得的数据永远不会与原始数据完全相同(很可能,取决于图像大小)。

因此,您很可能需要通过scanline实现memcpy scanline。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6691292

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档