【问题标题】:Image libraries and gif images图像库和 gif 图像
【发布时间】:2010-11-04 16:07:34
【问题描述】:

我需要在 C 程序中检查 gif 图像。我查看了 FreeImage 库,但无法弄清楚。有人可以举一个使用 FreeImage 来了解有关 gif 图像的所有小细节的示例,例如帧、背景、透明度等......以及如何通过帧递增并获取动画的当前图像/像素。我遇到的问题是您将图像加载到 FIMULTIBITMAP 类型中,而大多数函数都采用 FIBITMAP 类型。我不明白你应该如何使用带有 gif 的库。

另外,有没有更简单的库?

Ferruccio 说要使用 libGD。这是我在这个库中找到的。

/* These read the first frame only */
BGD_DECLARE(gdImagePtr) gdImageCreateFromGif (FILE * fd);

我需要所有的框架。

下面是一种工作。问题是图像的宽度/高度变化小于实际图像。我认为它只是显示了更改的内容,但我不确定如何将其映射回原始图像以进行任何使用。这是Gif File

实际上,这个库并没有像我认为的那样工作。例如,我无法获取图像的调色板。我得到的都是零。对此有何建议?

#include <stdio.h>
#include <string.h>
#include <FreeImage.h>

int main(int argc, char *argv) {
        FIMULTIBITMAP *src;
        src = FreeImage_OpenMultiBitmap(FIF_GIF, "clock_logo_ani.gif", FALSE, TRUE, FALSE, GIF_DEFAULT);

        int count = FreeImage_GetPageCount(src);
        int page, i, row, col, background, transparent;
        RGBQUAD bkcolor;
        BYTE pixel;

        char buffer[25*16 + 16];

        RGBQUAD *palette;

        background = 0;
        for(page = 0; page < count; page++) {
            FIBITMAP *dib = FreeImage_LockPage(src, page);
            if(dib) {
                printf("%dx%d\n", FreeImage_GetHeight(dib), FreeImage_GetWidth(dib));
                FreeImage_GetBackgroundColor(dib, &bkcolor);
                background = (&bkcolor)->rgbReserved;
                transparent = FreeImage_GetTransparentIndex(dib);
                memset(buffer, ' ', sizeof(char) * 24 * 16 + 17 * sizeof(char));
                for( row = 0; row < 16; row++ ) {
                        for( col = 0; col < 24; col++ ) {
                                if ( FreeImage_GetPixelIndex(dib, col, row, &pixel) ) {
                                        if((int)pixel != 0)
                                                buffer[row * 25 + col] = '.';
                                }

                        }
                }
                for (row = 0; row < 16; row++)
                        buffer[row * 25 + 25] = '\n';
                buffer[row * 25] = '\0';
                printf("-----\n%s\n-----\n", buffer);
                FreeImage_UnlockPage(src, dib, FALSE);
            }
        }

        FreeImage_CloseMultiBitmap(src, GIF_DEFAULT);
}

这是输出。注意图像大小的变化。

16x24
-----
           ...           
        ..   ..         
       .       .        
      .         .       
     .           .      
     .           .      
    .             .     
    .      ...    .     
    .      .      .     
     .     .     .      
     .     .     .      
      .    .    .       
       .       .        
        ..   ..         
          ...           

-----
4x4
-----
 .                       
 .                      
  .                     













-----
4x3
-----
...                      















-----
4x3
-----
  .                      
.                       

.                       












-----
4x4
-----
.                        















-----
4x4
-----


.                       
 .                      












-----
4x4
-----



...                     












-----
4x4
-----

  .                     
 .                      
.                       












-----

【问题讨论】:

    标签: c image gif


    【解决方案1】:

    在您的问题中包含的代码中,一旦锁定页面,您就可以:

    bool isTransparent=FreeImage_IsTransparent(dib);
    RGBQUAD* bkcolor;
    bool didIGetBackgroundCorrectly=FreeImage_GetBackgroundColor(dib, bkcolor);
    

    FreeImage_LockPage 为您提供的指针是该帧的图像。您应该能够在任何其他采用 FIBITMAP 类型的函数中使用它。 (但请记住,在上面的代码中,您以只读方式打开它)

    您已经知道动画中有多少帧,“计数”会告诉您。 (当然是从零开始)这很简单。

    【讨论】:

    • 您知道为什么这些帧的大小可能与实际图像不同吗?我已经用一些新代码更新了这个问题。
    • 您应该能够创建比图像更小的框架。 gif 优化器可以通过设置透明度来保留前一帧的一部分,让当前帧(较小的矩形)仅覆盖已更改的区域。查看 Wikipedia 关于图形交换格式的条目并向下滚动到他们对动画 GIF 文件格式的讨论。
    • 我理解那部分,但我不明白的是我如何知道 gif 的哪些部分发生了变化以覆盖较小的图像。
    • 好的,我不得不使用 GIF_PLAYBACK 而不是 GIF_DEFAULT。现在它给了我完整的图像。
    • 我要做的是使用 Freeimage 进行解码,但还要解析二进制文件本身以查看各种帧的位置。查看维基百科的文章;看到从字节 0x329 和字节 0x329D 开始了吗?这些告诉您该框架放置在图像上的位置。在文章中,第 1 帧是一个完整的帧:(0,0) 到 (400,400)。下一帧可能包含类似 (10,20) 到 (100,100) 的内容,这意味着第 2 帧覆盖了第 2 帧的矩形部分,依此类推。
    【解决方案2】:

    如果您愿意使用 c++,ImageMagick 有绑定来执行此操作。它有一个 c api,但我没有看到任何函数可以做到这一点。

    【讨论】:

    • 不,它必须是 C。我忘记了 ImageMagick。我不怀疑您已经彻底检查过了,但我仍在检查是否有任何 C 绑定可以满足我的要求。 :)
    【解决方案3】:

    LibGD 我运气不错。

    【讨论】:

    • 我认为它不适合我的目的。我已经用原因编辑了问题。
    猜你喜欢
    • 2020-08-30
    • 1970-01-01
    • 2011-01-09
    • 2016-01-04
    • 2015-11-21
    • 2017-09-15
    • 2023-04-04
    • 2011-02-01
    • 2011-08-21
    相关资源
    最近更新 更多