【问题标题】:How can I convert a GDI 8-bpp indexed bitmap to an RGB Bitmap?如何将 GDI 8-bpp 索引位图转换为 RGB 位图?
【发布时间】:2013-09-03 02:36:48
【问题描述】:

我正在尝试将 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); 

我该如何解决这个问题?

【问题讨论】:

  • 那么你能描述一下出了什么问题吗?
  • 除了结果位图不正确之外什么都没有
  • 好的,那么什么是不正确的?该死的迂腐的人这些程序员... ;)
  • 抱歉,返回的结果位图是黑色且失真的 :)

标签: c++ gdi


【解决方案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;

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

【讨论】:

  • 现在位图变成了蓝色,太漂亮了!
  • 天哪!我做了什么 !实际上它变得非常接近,但蓝色仍然是主要颜色,我认为现在 Pallate 有问题,我欠你一个棺材 :)
  • 您希望它是什么颜色?红色的?有时 MS 图像以相反的顺序 (BGR) 存储 RGB...
  • 是的,但背景是全黑的,但它显示为黑色
  • 嗯,黑色在所有领域都是零,所以零蓝色与零红色交换使零完全相同。我不确定,但如果你有“红色而不是蓝色”,那么我希望你需要交换处理红色和蓝色的行。
【解决方案2】:

正确填写和对齐 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 位图文件,看看结构是如何对齐的以及那里有什么,然后将它与你的内存布局进行比较。

【讨论】:

    【解决方案3】:

    为什么是榛子?当您使用 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]
    

    当您需要访问颜色时。

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

    【讨论】:

    • 用 PixelFormant24bppRGb 锁定一个 8bbpindexed 返回垃圾扫描0
    • 这很奇怪。但这就是我使用调色板编写以下解决方案的原因。我检查了您的其余代码,并没有发现任何进一步的错误。嗯,你的步幅计算看起来有点奇怪,但它应该可以工作。
    • 而不是 ((ColorPalette *)palette)->ARGB[i] 你的意思是 ((ColorPalette *)palette)->Entries ?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    • 2013-01-01
    • 2012-07-17
    • 2019-05-23
    • 1970-01-01
    • 2021-07-11
    相关资源
    最近更新 更多