lundi 6 mai 2024

Reading Animated GIF Files with Rebol-Opencv

GIF (Graphics Interchange Format) is used to store multiple bitmap images in a single file for exchange between platforms and systems. In terms of number of files in existence, GIF is perhaps the most widely used format for storing multi-bit graphics and image data.

GIF is different from many other common bitmap formats in the sense that it is stream-based. It consists of a series of data packets, called blocks, along with additional protocol information. Because of this arrangement, GIF files must be read as if they are a continuous stream of data. The various blocks and sub-blocks of data defined by GIF may be found almost anywhere within the file. This uncertainty makes it difficult to encapsulate every possible arrangement of GIF data in the form of data structures.

In the past, I spent a lot of time, with the help of Toomas Vooglaid (https://github.com/toomasv/LZW), writing functions to enable Red at Rebol 3 to decode these GIF files. We now have a much simpler solution with Rebol-OpenCV. Just think of the GIF file as a simple video. 

This a sample of code :

#!/usr/local/bin/r3
Rebol [
]
cv: import opencv ;--import Rebol-OpenCV extension
with cv [
    movie: VideoCapture %../../image/dance.gif ;--use your gif file
    unless movie [quit]
    ;--get some information about the gif file
    print ["Width :" w: get-property :movie CAP_PROP_FRAME_WIDTH]
    print ["Height:" h: get-property :movie CAP_PROP_FRAME_HEIGHT]
    print ["FPS   :" fps: get-property :movie CAP_PROP_FPS]
    print ["Frames:" nbFrames: to integer! get-property :movie CAP_PROP_FRAME_COUNT]
    print "ESC to close animation"
    delay: 1.5 / fps
    count: 0
    frame: read :movie ;--first image 
    imshow :frame 
    forever [
        read/into :movie :frame ;--no need to create a new matrix for each frame
        setWindowTitle "Image" join "Frame: " count + 1 ;--Redbol languages are one-based
        imshow :frame 
        wait delay        
        count: count + 1
        ;--when we are at the end of the gif go back to first image
        if count = nbFrames [set-property :movie CAP_PROP_POS_FRAMES 0 count: 0]
        k: pollKey           
    if k = 27 [break]  
    ]  
    waitKey 0
    print "closing.."
    destroyAllWindows
    free :movie ;--we must free the memory: no GC for VideoCapture 
    print "done"
]

And a sample result







Aucun commentaire:

Enregistrer un commentaire