在gif帧之间应用补丁

时间:2014-11-16 15:04:27

标签: c diff gif giflib

我想将gif帧提取到原始BGRA数据,我使用giflib来解析格式。我有第一帧(我认为它就像一个视频中的关键帧)看起来很好,第二帧(实际上是15帧,但让我们简化它)看起来像差异帧。这是样本:

key frame diff frame

使用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);
    }

0 个答案:

没有答案