Question

I need to examine a gif image in a C program. I looked into the FreeImage library but I can't figure it out. Could someone give an example of using FreeImage to get into all the little details about a gif image such as frames, background, transparency, etc... And how to increment through the frames and get the animation's current image/pixels. The problem I'm having is that you load the image into a FIMULTIBITMAP type, while most of the functions take a FIBITMAP type. I'm not seeing how you're supposed to use the library with gifs.

Also, is there a simpler library?

Ferruccio said to use libGD. Here's what I found with this library.

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

I need all of the frames.

Below is kind of working. The problem is the image's width/height change to be smaller than the actual image. I think it's just showing what changed, but I'm not sure how to map that back onto the original image to make any use of it. Here's the Gif File.

Actually this library's not working like I assume it's supposed to work. For instance, I can't get the palette for the image. What I get is all zeros. Any suggestions on that?

#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);
}

Here's the output. Notice how the image's size changes.

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

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













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















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

.                       












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















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


.                       
 .                      












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



...                     












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

  .                     
 .                      
.                       












-----
Was it helpful?

Solution

In the code included in your question, once you lock the page, you can do:

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

The pointer that FreeImage_LockPage gives you is that frame's image. You should be able to use it in any of the other functions that take the FIBITMAP type. (but remember, in the code above, you opened it read-only)

You already know how many frames are in the animation, "count" gives you that. (zero based, of course) It is pretty simple.

OTHER TIPS

I've had good luck with LibGD.

If you are willing to use c++, ImageMagick has bindings to do this. It has a c api, but I don't see any functions to do that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top