在 C++ CxImage 库中保存 GIF 有一点问题。我也在 CxImage 论坛上发布了这个,但它们似乎已经死了,所以我希望在这里找到使用 CxImage 并且可能遇到过这个问题的人。
我正在使用版本 7.01(最新)。
当我保存 GIF 时,它总是显示为 17x15 像素,大多数软件无法显示。(Internet Explorer、Windows Explorer、Photoshop 7.0、Irfanview)。其他软件可以处理这个问题(MSPaint、MSOffice 照片编辑器和 CxImage 本身)。
我已经深入挖掘,发现它是在 ximagif.cpp 的第 698 行的 CxImageGIF::EncodeRGB 中引起的:
const int32_t cellw = 17; // <-- This is where the dimensions shown in Win Explorer come from
const int32_t cellh = 15; // <--
CxImageGIF tmp;
for (int32_t y=0;y<head.biHeight;y+=cellh){
for (int32_t x=0;x<head.biWidth;x+=cellw){
if ((head.biWidth -x)<cellw) w=head.biWidth -x; else w=cellw;
if ((head.biHeight-y)<cellh) h=head.biHeight-y; else h=cellh;
if (w!=tmp.GetWidth() || h!=tmp.GetHeight()) tmp.Create(w,h,8);
if (IsTransparent()){
tmp.SetTransIndex(0);
tmp.SetPaletteColor(0,GetTransColor());
}
uint8_t i;
for (uint32_t j=0;j<h;j++){
for (uint32_t k=0;k<w;k++){
i=(uint8_t)(1+k+cellw*j);
tmp.SetPaletteColor(i,GetPixelColor(x+k,head.biHeight-y-h+j));
tmp.SetPixelIndex(k,j,tmp.GetNearestIndex(tmp.GetPaletteColor(i)));
}
}
tmp.SetOffset(x,y);
tmp.EncodeExtension(fp);
tmp.EncodeBody(fp,true);
}
}
逻辑屏幕描述符设置为正确的图像大小,但显然,图像被编码为 15x17 的小数据块。
根据我对 GIF 标准的了解,可以这样做,但似乎很多程序没有正确理解这一点,并假设每个块都是一整帧。也许我错了,我昨晚刚读到关于 GIF 标准的那部分
看起来这通常用于动画,并且 CxImage 将此帧的帧时间正确设置为 0。但是,一些程序会使用默认的 GIF 超时逐块绘制图像。
我尝试通过将 cellw 和 cellh 分别设置为 head.biWidth 和 head.biHeight 来修改代码以使其在一个块中编码每一帧,但无济于事。有没有人遇到过这个问题?
即使您不使用CxImage,但熟悉GIF89a,也许您可以确认我对GIF标准的解释是正确的?我很难相信微软和/或 Adobe 不会编写可以根据标准正确解码任何 GIF 图像的代码。我也很难相信用于图像处理的最佳可用 C++ 库之一会不正确或异常地编码常见的文件格式,如 GIF。