我正在使用FreeImage 3.15.4 library来分析PNG图像。我基本上试图构建一个简单的数据结构,包括所有颜色的调色板以及由像素组成的每像素数据的数组版本。
问题是FreeImage_GetBits
似乎正在返回指向无效数据的指针,我不知道为什么。我能够正确读取PNG文件的宽度和高度,但FreeImage_GetBits
指向的数据只是垃圾数据,看起来有些奇怪。无论我运行多少次程序,它都会在同一个地方死掉,当下面代码中的iPix
等于131740时。我在std :: find调用中访问位[131740]时出现C0000005错误。实际和报告的PNG图像大小为524288。
此外,我已经尝试使用我自己构建的较小图像的代码,并且它们工作正常。我正在使用的PNG是我的第三方,并且似乎没有任何损坏(Photoshop打开它,DirectX可以正常处理和使用它)
有什么想法吗?
这是数据声明:
struct Color
{
char b; // Blue
char g; // Green
char r; // Red
char a; // Alpha value
bool operator==( const Color& comp )
{
if ( a == comp.a &&
r == comp.r &&
g == comp.g &&
b == comp.b )
return TRUE;
else
return FALSE;
}
};
typedef std::vector<Color> ColorPalette; // Array of colors forming a palette
这是执行颜色索引的代码:
// Read image data with FreeImage
unsigned int imageSize = FreeImage_GetWidth( hImage ) * FreeImage_GetHeight( hImage );
unsigned char* pData = new unsigned char[imageSize];
// Access bits via FreeImage
FREE_IMAGE_FORMAT fif;
FIBITMAP* hImage;
fif = FreeImage_GetFIFFromFilename( fileEntry.name.c_str() );
if( fif == FIF_UNKNOWN )
{
return false;
}
hImage = FreeImage_Load( fif, filename );
BYTE* pPixelData = NULL;
pPixelData = FreeImage_GetBits( hImage );
if ( pPixelData == NULL )
{
return false;
}
Color* bits = (Color*)pPixelData;
ColorPalette palette;
for ( unsigned int iPix = 0; iPix < imageSize; ++iPix )
{
ColorPalette::iterator it;
if( ( it = std::find( palette.begin(), palette.end(), bits[iPix] ) ) == palette.end() )
{
pData[iPix] = palette.size();
palette.push_back( bits[iPix] );
}
else
{
unsigned int index = it - palette.begin();
pData[iPix] = index;
}
}
答案 0 :(得分:1)
有问题的PNG图像使用索引颜色模式,原始像素数据确实返回为8bpp。正确的做法是将此数据视为每像素8位,并将每个8位值视为可以使用FreeImage_GetPalette
检索的颜色调色板的索引。替代方案是我最终做出的选择,就是在这些索引颜色模式PNG图像上调用FreeImage_ConvertTo32Bits
,然后通过与相同32位图像格式相同的代码路径传递所有内容。
非常简单的转换,但现在是:
// Convert non-32 bit images
if ( FreeImage_GetBPP( hImage ) != 32 )
{
FIBITMAP* hOldImage = hImage;
hImage = FreeImage_ConvertTo32Bits( hOldImage );
FreeImage_Unload( hOldImage );
}