asmerge - demonstrates blending of multiple image using different algorithms
Contents
Description
After set of layers has been prepared - it can be passed to merge_layers() function, that will create new
ASImage of specifyed size, and then blend all the layers together to fill this image.
Example
merged_im = merge_layers( asv, layers, layers_num,
to_width, to_height,
ASA_ASImage, 0,
ASIMAGE_QUALITY_DEFAULT );
while( --layers_num >= 0 )
destroy_asimage( &(layers[layers_num].im) );
free( layers );
Name
asmerge - demonstrates blending of multiple image using different algorithms
libAfterImage/tutorials/ASMerge
Nameasmerge
Notes
After we've blended layers - we no longer need ASImageLayer array. So proceeding to clean it up, by
destroying overlay AsImages first, and then freeing array itself.
See Also
merge_asimage().
3rd Berkeley Distribution AfterStep v.2.2.12 asmerge(3x)
Source
#include "../afterbase.h" #include "../afterimage.h" #include "common.h"
char *burning_rose[] = {
"asmerge",
"rose512.jpg",
"add",
"back.xpm:512x386",
"hue",
"fore.xpm:512x386" };
void usage() {
printf( "Usage: asmerge [-h]|[image op1 image1 [op2 image2 [...]]]\n");
printf( "Where: image - is background image filename\n");
printf( " image1 - is first overlay's filename\n");
printf( " op1,op2,... - overlay operation."
" Supported operations are :\n");
list_scanline_merging( stdout,
" %-15.15s- %s\n"); }
int main(int argc, char* argv[]) {
Display *dpy = NULL;
ASVisual *asv ;
int screen = 0, depth = 0;
int to_width = 1, to_height = 1;
ASImageLayer *layers ;
int layers_num = 0, i;
ASImage *merged_im ;
/* see ASView.1 : */
set_application_name( argv[0] ); #if (HAVE_AFTERBASE_FLAG==1)
set_output_threshold(OUTPUT_LEVEL_DEBUG); #endif
if( argc == 2 && strncmp(argv[1],"-h", 2) == 0 )
{
usage();
return 0;
}
if( argc <= 3 )
{
show_error( "not enough arguments, please see usage:%s", " ");
usage() ;
printf( "Using the default, \"The Burning Rose\", composition :\n");
printf( "\n\trose512.jpg add back.xpm:512x386 hue "
"fore.xpm:512x386\n");
argv = &(burning_rose[0]) ;
argc = 6;
}
#ifndef X_DISPLAY_MISSING
dpy = XOpenDisplay(NULL);
_XA_WM_DELETE_WINDOW = XInternAtom( dpy, "WM_DELETE_WINDOW", False);
screen = DefaultScreen(dpy);
depth = DefaultDepth( dpy, screen ); #endif
/* see ASView.3 : */
asv = create_asvisual( dpy, screen, depth, NULL );
/* see ASMerge.1 : */
layers = safecalloc( argc/2, sizeof(ASImageLayer) );
for( i = 1 ; i < argc ; i++ )
{
int x = 0, y = 0;
unsigned int width, height ;
int geom_flags = 0 ;
char *separator;
char *filename ;
/* see ASMerge.2 */
if( i > 1 )
{
/* see blend_scanlines_name2func() : */
if((layers[layers_num].merge_scanlines =
blend_scanlines_name2func( argv[i] )) == NULL )
continue ;
if( ++i >= argc )
break;
}
if( (separator = strchr( argv[i], ':' )) != NULL )
{ /* see ASTile.1 : */
geom_flags = XParseGeometry( separator+1,
&x, &y, &width, &height);
filename = mystrndup( argv[i], separator-argv[i] );
}else
filename = argv[i] ;
layers[layers_num].im = file2ASImage( filename, 0xFFFFFFFF,
SCREEN_GAMMA, 100, getenv("IMAGE_PATH"), NULL );
if( filename != argv[i] )
free( filename );
if( layers[layers_num].im != NULL )
{
if( !get_flags(geom_flags, WidthValue) )
width = layers[layers_num].im->width ;
if( !get_flags(geom_flags, HeightValue) )
height = layers[layers_num].im->height ;
/* see ASMerge.3 : */
if( layers[layers_num].merge_scanlines == NULL )
layers[layers_num].merge_scanlines =
alphablend_scanlines ;
layers[layers_num].clip_width = width ;
layers[layers_num].clip_height = height ;
if( layers_num > 0 )
{
layers[layers_num].dst_x = x ;
layers[layers_num].dst_y = y ;
}else
{
to_width = width ;
to_height = height ;
if( width != layers[layers_num].im->width ||
height != layers[layers_num].im->height )
{
ASImage *scaled_bottom ;
/* see ASScale.2 : */
scaled_bottom = scale_asimage( asv,
layers[layers_num].im,
width, height,
False, 100,
ASIMAGE_QUALITY_DEFAULT );
destroy_asimage( &(layers[layers_num].im) );
layers[layers_num].im = scaled_bottom ;
}
}
++layers_num ;
}
}
if( layers_num <= 0 )
{
show_error( "there is no images to merge. Aborting");
return 2;
}
/* see ASMerge.4 */
merged_im = merge_layers( asv, layers, layers_num,
to_width, to_height, #ifndef X_DISPLAY_MISSING
ASA_XImage, #else
ASA_ASImage, #endif
0, ASIMAGE_QUALITY_DEFAULT );
while( --layers_num >= 0 )
destroy_asimage( &(layers[layers_num].im) );
free( layers );
if( merged_im )
{ #ifndef X_DISPLAY_MISSING
/* see ASView.4 : */
Window w = create_top_level_window( asv, DefaultRootWindow(dpy),
32, 32,
to_width, to_height,
1, 0, NULL,
"ASMerge", NULL );
if( w != None )
{
Pixmap p ;
XMapRaised (dpy, w);
/* see ASView.5 : */
p = asimage2pixmap( asv, DefaultRootWindow(dpy), merged_im,
NULL, True );
destroy_asimage( &merged_im );
/* see common.c: set_window_background_and_free() : */
p = set_window_background_and_free( w, p );
/* see common.c: wait_closedown() : */
}
wait_closedown(w);
dpy = NULL; #else
/* writing result into the file */
ASImage2file( merged_im, NULL, "asmerge.jpg", ASIT_Jpeg, NULL );
destroy_asimage( &merged_im ); #endif
} #ifdef DEBUG_ALLOCS
build_xpm_colormap(NULL);
print_unfreed_mem(); #endif
return 0 ; }
libAfterImage/tutorials/ASMerge.1 [4.1]
Synopsis
Step 4. Actual blending of the set of images.
