1asmerge(1)               AfterStep X11 window manager               asmerge(1)
2
3
4

NAME

6       asmerge - demonstrates blending of multiple image using different algo‐
7       rithms libAfterImage/tutorials/ASMerge
8

NAMEASMerge

SYNOPSIS

11       Scaling and blending of arbitrary number of images
12       using libAfterImage.
13

DESCRIPTION

15       We will attempt to interpret command line arguments as sequence of
16       image filenames, geometries and blending types. We'll then try and
17       load all the images, scaling first one to requested size, and
18       blending others at specifyed locations of the first image.
19       We then display the result in simple window.
20       After that we would want to wait, until user closes our window.
21
22       New steps described in this tutorial are :
23       Step 1. Layers.
24       Step 2. Merging methods.
25       Step 3. Layer parameters.
26       Step 4. Actual blending of the set of images.
27

SEE ALSO

29       Tutorial 1: ASView  - explanation of basic steps needed to use
30                             libAfterImage and some other simple things.
31       Tutorial 2: ASScale - image scaling basics.
32       Tutorial 3: ASTile  - image tiling and tinting
33

SOURCE

35       Source :
36       #include "../afterbase.h"
37       #include "../afterimage.h"
38       #include "common.h"
39
40       char *burning_rose[] =
41       {
42           "asmerge",
43           "rose512.jpg",
44           "add",
45           "back.xpm:512x386",
46           "hue",
47           "fore.xpm:512x386"
48       };
49
50       void usage()
51       {
52           printf( "Usage: asmerge [-h]|[image op1 image1 [op2 image2 [...]]]0);
53           printf( "Where: image  - is background image filename0);
54           printf( "       image1 - is first overlay's filename0);
55           printf( "       op1,op2,... - overlay operation."
56                   " Supported operations are :0);
57           list_scanline_merging( stdout,
58                   "         %-15.15s- %s0);
59       }
60
61       int main(int argc, char* argv[])
62       {
63           ASVisual *asv ;
64           int screen = 0, depth = 0;
65           int to_width = 1, to_height = 1;
66           ASImageLayer *layers ;
67           int layers_num = 0, i;
68           ASImage *merged_im ;
69
70           /* see ASView.1 : */
71           set_application_name( argv[0] );
72       #if (HAVE_AFTERBASE_FLAG==1)
73           set_output_threshold(OUTPUT_LEVEL_DEBUG);
74       #endif
75           if( argc == 2 && strncmp(argv[1],"-h", 2) == 0 )
76           {
77               usage();
78               return 0;
79           }
80           if( argc <= 3 )
81           {
82               show_error( "not enough arguments, please see usage:%s", " ");
83               usage() ;
84               printf( "Using the default,
85               printf( "rose512.jpg add back.xpm:512x386 hue "
86                       "fore.xpm:512x3860);
87               argv = &(burning_rose[0]) ;
88               argc = 6;
89           }
90
91       #ifndef X_DISPLAY_MISSING
92           dpy = XOpenDisplay(NULL);
93           _XA_WM_DELETE_WINDOW = XInternAtom( dpy, "WM_DELETE_WINDOW", False);
94           screen = DefaultScreen(dpy);
95           depth = DefaultDepth( dpy, screen );
96       #endif
97           /* see ASView.3 : */
98           asv = create_asvisual( dpy, screen, depth, NULL );
99
100           /* see ASMerge.1 : */
101           layers = safecalloc( argc/2, sizeof(ASImageLayer) );
102
103           for( i = 1 ; i < argc ; i++ )
104           {
105               int x = 0, y = 0;
106               unsigned int width, height ;
107               int geom_flags = 0 ;
108               char *separator;
109               char *filename ;
110               /* see ASMerge.2 */
111               if( i > 1 )
112               {
113                   /* see blend_scanlines_name2func() : */
114                   if((layers[layers_num].merge_scanlines =
115                        blend_scanlines_name2func( argv[i] )) == NULL )
116                       continue ;
117                   if( ++i >= argc )
118                       break;
119               }
120               if( (separator = strchr( argv[i], ':' )) != NULL )
121               {   /* see ASTile.1 : */
122                   geom_flags = XParseGeometry( separator+1,
123                                                &x, &y, &width, &height);
124                   filename = mystrndup( argv[i], separator-argv[i] );
125               }else
126                   filename = argv[i] ;
127               layers[layers_num].im = file2ASImage( filename, 0xFFFFFFFF,
128                                                     SCREEN_GAMMA, 100, getenv("IMAGE_PATH"), NULL );
129               if( filename != argv[i] )
130                   free( filename );
131               if( layers[layers_num].im != NULL )
132               {
133                   if( !get_flags(geom_flags, WidthValue) )
134                       width = layers[layers_num].im->width  ;
135                   if( !get_flags(geom_flags, HeightValue) )
136                       height = layers[layers_num].im->height ;
137                   /* see ASMerge.3 : */
138                   if( layers[layers_num].merge_scanlines == NULL )
139                       layers[layers_num].merge_scanlines =
140                           alphablend_scanlines ;
141                   layers[layers_num].clip_width = width ;
142                   layers[layers_num].clip_height = height ;
143                   if( layers_num > 0 )
144                   {
145                       layers[layers_num].dst_x = x ;
146                       layers[layers_num].dst_y = y ;
147                   }else
148                   {
149                       to_width = width ;
150                       to_height = height ;
151                       if( width != layers[layers_num].im->width ||
152                           height != layers[layers_num].im->height )
153                       {
154                           ASImage *scaled_bottom ;
155                           /* see ASScale.2 : */
156                           scaled_bottom = scale_asimage( asv,
157                                                          layers[layers_num].im,
158                                                          width, height,
159                                                          False, 100,
160                                                       ASIMAGE_QUALITY_DEFAULT );
161                           destroy_asimage( &(layers[layers_num].im) );
162                           layers[layers_num].im = scaled_bottom ;
163                       }
164                   }
165                   ++layers_num ;
166               }
167           }
168
169           if( layers_num <= 0 )
170           {
171               show_error( "there is no images to merge. Aborting");
172               return 2;
173           }
174
175           /* see ASMerge.4 */
176           merged_im = merge_layers( asv, layers, layers_num,
177                                     to_width, to_height,
178       #ifndef X_DISPLAY_MISSING
179                                     ASA_XImage,
180       #else
181                                     ASA_ASImage,
182       #endif
183                                     0, ASIMAGE_QUALITY_DEFAULT );
184           while( --layers_num >= 0 )
185               destroy_asimage( &(layers[layers_num].im) );
186           free( layers );
187
188           if( merged_im )
189           {
190       #ifndef X_DISPLAY_MISSING
191           /* see ASView.4 : */
192               Window w = create_top_level_window( asv, DefaultRootWindow(dpy),
193                                                   32, 32,
194                                                   to_width, to_height,
195                                                   1, 0, NULL,
196                                                   "ASMerge", NULL );
197               if( w != None )
198               {
199                   Pixmap p ;
200
201                   XMapRaised   (dpy, w);
202                   /* see ASView.5 : */
203                   p = asimage2pixmap( asv, DefaultRootWindow(dpy), merged_im,
204                                   NULL, True );
205
206                   destroy_asimage( &merged_im );
207                   /* see common.c: set_window_background_and_free() : */
208                   p = set_window_background_and_free( w, p );
209                   /* see common.c: wait_closedown() : */
210                   wait_closedown(w);
211               }
212               if( dpy )
213                   XCloseDisplay (dpy);
214       #else
215               /* writing result into the file */
216               ASImage2file( merged_im, NULL, "asmerge.jpg", ASIT_Jpeg, NULL );
217               destroy_asimage( &merged_im );
218       #endif
219           }
220       #ifdef DEBUG_ALLOCS
221           build_xpm_colormap(NULL);
222           print_unfreed_mem();
223       #endif
224           return 0 ;
225       }
226

SYNOPSIS

228       Step 1. Layers.
229

DESCRIPTION

231       libAfterImage performs blending/merging of different images, using
232       arrays of ASImageLayer structures, with first element representing
233       the bottommost image. Each structure specifies exact position on
234       resulting image where overlay should be blended to, tint of the
235       overlay, size, to which overlay should be tiled, overlay's origin,
236       and overlay's background color. Arbitrary number of layers can be
237       merged whithin single run.
238
239       Accordingly all that is needed to merge bunch of images is to create
240       array of ASImageLayer structures and fill it up appropriately.
241

EXAMPLE

243           layers = safecalloc( argc/2, sizeof(ASImageLayer) );
244

SYNOPSIS

246       Step 2. Merging methods.
247

DESCRIPTION

249       Each layer can be merged in using its own method. There are about 15
250       different methods implemented in libAfterImage, and user app can
251       implement other methods of its own. To specify method all that is
252       needed is to set merge_scanlines member of ASImageLayer to pointer
253       to the function, implementing specific method.
254
255       libAfterImage provides facility to parse method name strings into
256       actuall function pointers. That could be used to simplifi scripting,
257       etc.
258

EXAMPLE

260              if((layers[layers_num].merge_scanlines =
261                  blend_scanlines_name2func( argv[i] )) == NULL )
262                  continue ;
263       NOTE
264       All layers MUST have valid merge_scanlines pointer, even the
265       bottommost layer, despite the fact that it has nothing to be merged
266       with. If merge_scanlines is set to NULL - this layer will be ignored.
267       That could be used to turn on/off particular layers.
268

SYNOPSIS

270       Step 3. Layer parameters.
271

DESCRIPTION

273       Several ASImageLayer members are mandatory and cannot be set to 0.
274       Such as : im - image to be merged; clip_width, clip_height - this will
275       be used to tile the image; merge_scanlines - must be set to a pointer
276       to the function implementing merging method. If any of this is set
277       to 0  - then layer will be ignored. The rest of the parameters are
278       optional. Note thou that tint parameter will tint overlay's RGB
279       components and alpha component, as the result it could be used to
280       make opaque images - semitransparent.
281

EXAMPLE

283           if( layers[layers_num].merge_scanlines == NULL )
284               layers[layers_num].merge_scanlines =
285                   alphablend_scanlines ;
286           layers[layers_num].clip_width = width ;
287           layers[layers_num].clip_height = height ;
288           if( layers_num > 0 )
289           {
290               layers[layers_num].dst_x = x ;
291               layers[layers_num].dst_y = y ;
292           }
293

SYNOPSIS

295       Step 4. Actual blending of the set of images.
296

DESCRIPTION

298       After set of layers has been prepared - it can be passed to
299       merge_layers() function, that will create new ASImage of specifyed
300       size, and then blend all the layers together to fill this image.
301

EXAMPLE

303               merged_im = merge_layers( asv, layers, layers_num,
304                                         to_width, to_height,
305                                         ASA_ASImage, 0,
306                                         ASIMAGE_QUALITY_DEFAULT );
307               while( --layers_num >= 0 )
308                   destroy_asimage( &(layers[layers_num].im) );
309               free( layers );
310

NOTES

312       After we've blended layers - we no longer need ASImageLayer array.
313       So proceeding to clean it up, by destroying overlay AsImages first,
314       and then freeing array itself.
315

SEE ALSO

317       merge_asimage().
318
319
320
3213rd Berkeley Distribution      AfterStep v.2.2.6                    asmerge(1)
Impressum