4

我正在尝试将 8-bpp 索引位图转换为 RGB 位图,但没有成功。

第一个问题是返回的调色板GetPalette()不包含 256 个唯一数字。

到目前为止,这是我的代码:

BitmapData bitmapData;
int paletteSize =b->GetPaletteSize();
ColorPalette colorPalette;
b->GetPalette(&colorPalette,paletteSize/4);
b->LockBits(new Gdiplus::Rect(0,0,b->GetWidth(),b->GetHeight()),0,b->GetPixelFormat(),&bitmapData);
char* scan0 = (char*)bitmapData.Scan0; 
width = b->GetWidth();              
height = b->GetHeight();                
stride =  bitmapData.Width*4;               
pBitmapData = new char[stride*height];          
DWORD B = 0x00FF0000;                               
DWORD G =0x0000FF00;                                    
DWORD R = 0x000000FF;                                       
int currentIndex=0;                                             
for(int i = 0 ; i < height; i++)                                            
{                                                                                   
    for(int j =0 ; j < width; j++)                                                                  
    {                                                                                                           
        std::stringstream ss;                                                                                               
        currentIndex = i*stride+j*3;                                                                                                    
        pBitmapData[currentIndex+1]= (colorPalette.Entries[scan0[i*width+j]]&&B)>>16;
        pBitmapData[currentIndex+2]= (colorPalette.Entries[scan0[i*width+j]]&&G)>>8;                                                                
        pBitmapData[currentIndex+3]= (colorPalette.Entries[scan0[i*width+j]]&&R);
    }                                                                                                                                                       
}                                                                                                                                                               
b->UnlockBits(&bitmapData); 

我怎样才能解决这个问题?

4

3 回答 3

1

为什么是榛子?当您使用 LockBits 时,您可以使用 PixelFormat24bppRGB 作为 LockBits 的参数三,因为系统无论如何都会复制数据(您永远无法直接访问 GDI+ 中的图像数据)。

这是我发现的一些错误(到目前为止):

int paletteSize =b->GetPaletteSize();
ColorPalette colorPalette;
b->GetPalette(&colorPalette,paletteSize/4);

为什么要除以四?GetPaletteSize 以字节为单位返回大小,而 GetPalette 等待以字节为单位的大小。ColorPalette 是一个占位符定义,是微软开发人员对我们所做的最黑暗的想法之一。它只定义了第一个颜色条目!

使用字节指针,如:

void *palette=new char[paletteSize];
b->GetPalette((ColorPalette *)palette,paletteSize);

采用

((ColorPalette *)palette)->Entries[i]

当您需要访问颜色时。

对不起,它真的和你直接使用调色板时看起来一样难看。不要忘记释放调色板和…………祝你好运。

于 2013-09-02T17:45:21.813 回答
1

正确填写和对齐 BITMAP RIFF 格式的各个部分非常重要。调色板类型位图的调色板不必包含 256 个条目:http: //msdn.microsoft.com/en-us/library/windows/desktop/dd183376%28v=vs.85%29.aspx

“8 位图最多有 256 种颜色,BITMAPINFO 的 bmiColors 成员最多包含256 个条目。在这种情况下,数组中的每个字节代表一个像素。”

然而重要的是,如果调色板中的条目少于 256 个,则位图不应索引到调色板结构之外。否则源格式不正确。

您想要转换 24 bpp 位图。这与 8bpp 有点不同。我建议您在十六进制编辑器中打开现有的 24bpp 和 8bpp 位图文件,查看结构的对齐方式和内容,并将其与您的内存布局进行比较。

于 2013-09-02T18:19:15.707 回答
1

这不应该:

currentIndex = i*stride+j*3;

是:

currentIndex = i*stride+j*4;

鉴于:

stride =  bitmapData.Width*4;

还:

(colorPalette.Entries[scan0[i*width+j]]&&B)>>16;

应该:

(colorPalette.Entries[scan0[i*width+j]] & B)>>16;

&&表示“如果左右为真”,单&表示“按位与”。

于 2013-09-02T18:25:13.523 回答