libvips/examples/annotate-animated.c
2022-09-08 17:05:10 +01:00

106 lines
2.4 KiB
C

/* Draw something on every frame of an animated image.
*
* compile with:
*
* gcc -g -Wall annotate-animated.c `pkg-config vips --cflags --libs`
*
* run with:
*
* annotate-animated ~/pics/3198.gif[n=-1] x.webp
*/
#include <vips/vips.h>
static int
annotate_image( VipsObject *context, VipsImage *image, VipsImage **out )
{
int page_height = vips_image_get_page_height( image );
int n_pages = image->Ysize / page_height;
VipsImage **overlay = (VipsImage **)
vips_object_local_array( context, n_pages );
VipsImage **page = (VipsImage **)
vips_object_local_array( context, n_pages );
VipsImage **annotated = (VipsImage **)
vips_object_local_array( context, n_pages );
/* Red as RGBA.
*/
double red[] = { 255, 0, 0, 255 };
double transparent[] = { 0, 0, 0, 0 };
int i;
/* Split the image into frames.
*/
for( i = 0; i < n_pages; i++ )
if( vips_crop( image, &page[i],
0, page_height * i, image->Xsize, page_height, NULL ) )
return( -1 );
/* Make an overlay ... a solid red square, with a transparent hole.
*/
if(
!(overlay[0] = vips_image_new_from_image( page[0],
red, VIPS_NUMBER( red ) )) ||
vips_draw_rect( overlay[0],
transparent, VIPS_NUMBER( transparent ),
10, 10, overlay[0]->Xsize - 20, overlay[0]->Ysize - 20,
"fill", TRUE,
NULL ) )
return( -1 );
/* Draw the overlay on every page.
*/
for( i = 0; i < n_pages; i++ )
if( vips_composite2( page[i], overlay[0], &annotated[i],
VIPS_BLEND_MODE_OVER, NULL ) )
return( -1 );
/* Reassemble the frames.
*/
if( vips_arrayjoin( annotated, out, n_pages,
"across", 1,
NULL ) )
return( -1 );
return( 0 );
}
int
main( int argc, char **argv )
{
VipsImage *image;
VipsObject *context;
VipsImage *x;
if( VIPS_INIT( argv[0] ) )
vips_error_exit( NULL );
if( argc != 3 )
vips_error_exit( "usage: %s xxx.gif[n=-1] yyy.gif", argv[0] );
if( !(image = vips_image_new_from_file( argv[1],
"access", VIPS_ACCESS_SEQUENTIAL,
NULL )) )
vips_error_exit( NULL );
context = VIPS_OBJECT( vips_image_new() );
if( annotate_image( context, image, &x ) ) {
g_object_unref( image );
g_object_unref( context );
vips_error_exit( NULL );
}
g_object_unref( image );
g_object_unref( context );
image = x;
if( vips_image_write_to_file( image, argv[2], NULL ) ) {
g_object_unref( image );
vips_error_exit( NULL );
}
g_object_unref( image );
return( 0 );
}