我想将gif帧提取到原始BGRA数据,我使用giflib来解析格式。我有第一帧(我认为它就像一个视频中的关键帧)看起来很好,第二帧(实际上是15帧,但让我们简化它)看起来像差异帧。这是样本:
使用diff数据恢复第二个完整帧似乎很简单,但问题是:我不知道什么颜色索引意味着“未更改”。差异帧上的黑色像素实际上是黑色 - 其颜色映射中的索引是255,即rgb(0,0,0)。我打印了整个颜色表,没有找到任何其他黑色条目。如果感兴趣,那是here。 “BackgroundColor”索引是193,所以它也没有任何意义。
所以,我不能将“黑色”与“不”颜色分开。如果第二帧真的包含一些新的黑色像素(它确实包含左眼在动画上移动)会怎么样?但是程序应该以不同的方式处理它:获得“no”颜色的前一帧颜色并获得“black”颜色的rgb(0,0,0)。
UPD:这是我的代码。省略了子帧处理和内存清理。在这里,我认为“no”颜色索引在colortable中是最后的。它实际上适用于我的测试文件,但我不确定它是否会起作用。
DGifSlurp(image);
int* master = malloc(image->SWidth * image->SHeight * sizeof(int));
for (int i = 0; i < image->ImageCount; i++) {
SavedImage* frame = &image->SavedImages[i];
ColorMapObject* cmap = frame->ImageDesc.ColorMap ? frame->ImageDesc.ColorMap : image->SColorMap;
int nocoloridx = cmap->ColorCount - 1;
IplImage* mat = cvCreateImage(cvSize(frame->ImageDesc.Width, frame->ImageDesc.Height), IPL_DEPTH_8U, 4);
mat->imageData = malloc(frame->ImageDesc.Width * frame->ImageDesc.Height * 4);
for (int y = 0; y < frame->ImageDesc.Height; y++)
for (int x = 0; x < frame->ImageDesc.Width; x++) {
int offset = y * frame->ImageDesc.Width + x;
int coloridx = frame->RasterBits[offset];
if (coloridx == nocoloridx) {
coloridx = master[offset];
} else {
master[offset] = coloridx;
}
GifColorType color = cmap->Colors[coloridx];
cvSetComponent(mat, x, y, 0, color.Blue);
cvSetComponent(mat, x, y, 1, color.Green);
cvSetComponent(mat, x, y, 2, color.Red);
cvSetComponent(mat, x, y, 3, 100);
}
cvNamedWindow("t", CV_WINDOW_AUTOSIZE);
cvShowImage("t", mat);
cvWaitKey(0);
}