C++ 如何将GDI 8-bpp索引位图转换为RGB位图?

C++ 如何将GDI 8-bpp索引位图转换为RGB位图?,c++,gdi,C++,Gdi,我正在尝试将8-bpp索引位图转换为RGB位图,但尚未成功 第一个问题是GetPalette()返回的调色板不包含256个唯一的数字 这是我目前的代码: BitmapData bitmapData; int paletteSize =b->GetPaletteSize(); ColorPalette colorPalette; b->GetPalette(&colorPalette,paletteSize/4); b->LockBits(new Gdiplus::Rec

我正在尝试将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); 
BitmapData BitmapData;
int paletesize=b->getpaletesize();
调色板调色板;
b->GetPalette(&colorPalette,paletteSize/4);
b->LockBits(新的Gdiplus::Rect(0,0,b->GetWidth(),b->GetHeight()),0,b->GetPixelFormat(),和位图数据);
char*scan0=(char*)bitmapData.scan0;
宽度=b->GetWidth();
高度=b->GetHeight();
步幅=位图数据。宽度*4;
pBitmapData=新字符[步幅*高度];
DWORD B=0x00FF0000;
DWORD G=0x0000FF00;
DWORD R=0x000000FF;
int currentIndex=0;
对于(int i=0;i>16;
pBitmapData[currentIndex+2]=(colorplate.Entries[scan0[i*width+j]]和&G)>>8;
pBitmapData[currentIndex+3]=(colorPalette.Entries[scan0[i*width+j]]和&R);
}                                                                                                                                                       
}                                                                                                                                                               
b->解锁位(&bitmapData);

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

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

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

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

使用字节指针,如:

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

当您需要访问颜色时

很抱歉,当您直接使用调色板时,它确实和看起来一样难看。 别忘了释放调色板和…
…祝你好运。

正确填写并对齐位图RIFF格式的各个部分非常重要。调色板类型位图的调色板不必包含256个条目:

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

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

您想要转换一个24 bpp的位图。这和8bpp有点不同。我建议您在hex editor中打开一个现有的24bpp和8bpp位图文件,查看结构对齐的精确程度以及存在的内容,并将其与内存布局进行比较。

这不应该:

currentIndex = i*stride+j*3;
是:

鉴于:

stride =  bitmapData.Width*4;
此外:

应该是:

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

&
表示“如果左侧和右侧为真”,单
&
表示“按位和”

那么ju能描述出哪里出了问题吗?除了结果位图不正确外,什么都不正确?该死的书呆子这些程序员…;)很抱歉,返回的结果位图为黑色且失真:)锁定一个8bbp索引的PixelFormant24bppRGb返回垃圾扫描0个奇数。但这就是我用调色板写下面的解决方案的原因。我检查了您的其余代码,在第一次查看时没有发现任何进一步的错误。嗯,你的步幅计算看起来有点奇怪,但它应该可以工作。而不是((颜色调色板*)调色板)->ARGB[i]你的意思是((颜色调色板*)调色板)->条目?现在位图变成了蓝色,这非常漂亮!天哪!我所做的一切!事实上,它变得非常接近,但蓝色仍然是主要颜色,我想现在有一个问题与苍白,我欠你一个棺材:)你希望它是什么颜色?红色有时MS图像以相反的顺序存储RGB(BGR)…是的,但背景是完全黑色的,但它出现在blackWell中,黑色在所有字段中都是零,因此零蓝色与零红色交换使零完全相同。我不确定,但如果你有“红色而不是蓝色”,那么我希望你需要交换红色和蓝色的交易行。
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;