1// This may look like C code, but it is really -*- C++ -*-
2//
3// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
4//
5// Simple demo program for Magick++
6//
7// Concept and algorithms lifted from PerlMagick demo script written
8// by John Christy.
9//
10// Max run-time size 60MB (as compared with 95MB for PerlMagick) under SPARC Solaris
11//
12
13#include <Magick++.h>
14#include <string>
15#include <iostream>
16#include <list>
17
18using namespace std;
19
20using namespace Magick;
21
22int main( int /*argc*/, char ** argv)
23{
24
25  // Initialize ImageMagick install location for Windows
26  InitializeMagick(*argv);
27
28  try {
29
30    string srcdir("");
31    if(getenv("SRCDIR") != 0)
32      srcdir = getenv("SRCDIR");
33
34    // Common font to use.
35    string font = "Helvetica";
36
37    list<Image> montage;
38
39    {
40      //
41      // Read model & smile image.
42      //
43      cout << "Read images ..." << endl;
44
45      Image model( srcdir + "model.miff" );
46      model.label( "Magick++" );
47      model.borderColor( "black" );
48      model.backgroundColor( "black" );
49
50      Image smile( srcdir + "smile.miff" );
51      smile.label( "Smile" );
52      smile.borderColor( "black" );
53
54      //
55      // Create image stack.
56      //
57      cout << "Creating thumbnails..." << endl;
58
59      // Construct initial list containing seven copies of a null image
60      Image null;
61      null.size( Geometry(70,70) );
62      null.read( "NULL:black" );
63      list<Image> images( 7, null );
64
65      Image example = model;
66
67      // Each of the following follow the pattern
68      //  1. obtain reference to (own copy of) image
69      //  2. apply label to image
70      //  3. apply operation to image
71      //  4. append image to container
72
73      cout << "  add noise ..." << endl;
74      example.label( "Add Noise" );
75      example.addNoise( LaplacianNoise );
76      images.push_back( example );
77
78      cout << "  add noise (blue) ..." << endl;
79      example.label( "Add Noise\n(Blue Channel)" );
80      example.addNoiseChannel( BlueChannel, PoissonNoise );
81      images.push_back( example );
82
83      cout << "  annotate ..." << endl;
84      example = model;
85      example.label( "Annotate" );
86      example.density( "72x72" );
87      example.fontPointsize( 18 );
88      example.font( font );
89      example.strokeColor( Color() );
90      example.fillColor( "gold" );
91      example.annotate( "Magick++", "+0+20", NorthGravity );
92      images.push_back( example );
93
94      cout << "  blur ..." << endl;
95      example = model;
96      example.label( "Blur" );
97      example.blur( 0, 1.5 );
98      images.push_back( example );
99
100      cout << "  blur red channel ..." << endl;
101      example = model;
102      example.label( "Blur Channel\n(Red Channel)" );
103      example.blurChannel( RedChannel, 0, 3.0 );
104      images.push_back( example );
105
106      cout << "  border ..." << endl;
107      example = model;
108      example.label( "Border" );
109      example.borderColor( "gold" );
110      example.border( Geometry(6,6) );
111      images.push_back( example );
112
113      cout << "  channel ..." << endl;
114      example = model;
115      example.label( "Channel\n(Red Channel)" );
116      example.channel( RedChannel );
117      images.push_back( example );
118
119      cout << "  charcoal ..." << endl;
120      example = model;
121      example.label( "Charcoal" );
122      example.charcoal( );
123      images.push_back( example );
124
125      cout << "  composite ..." << endl;
126      example = model;
127      example.label( "Composite" );
128      example.composite( smile, "+35+65", OverCompositeOp);
129      images.push_back( example );
130
131      cout << "  contrast ..." << endl;
132      example = model;
133      example.label( "Contrast" );
134      example.contrast( false );
135      images.push_back( example );
136
137      cout << "  convolve ..." << endl;
138      example = model;
139      example.label( "Convolve" );
140      {
141        // 3x3 matrix
142        const double kernel[] = { 1, 1, 1, 1, 4, 1, 1, 1, 1 };
143        example.convolve( 3, kernel );
144      }
145      images.push_back( example );
146
147      cout << "  crop ..." << endl;
148      example = model;
149      example.label( "Crop" );
150      example.crop( "80x80+25+50" );
151      images.push_back( example );
152
153      cout << "  despeckle ..." << endl;
154      example = model;
155      example.label( "Despeckle" );
156      example.despeckle( );
157      images.push_back( example );
158
159      cout << "  draw ..." << endl;
160      example = model;
161      example.label( "Draw" );
162      example.fillColor(Color());
163      example.strokeColor( "gold" );
164      example.strokeWidth( 2 );
165      example.draw( DrawableCircle( 60,90, 60,120 ) );
166      images.push_back( example );
167
168      cout << "  edge ..." << endl;
169      example = model;
170      example.label( "Detect Edges" );
171      example.edge( );
172      images.push_back( example );
173
174      cout << "  emboss ..." << endl;
175      example = model;
176      example.label( "Emboss" );
177      example.emboss( );
178      images.push_back( example );
179
180      cout << "  equalize ..." << endl;
181      example = model;
182      example.label( "Equalize" );
183      example.equalize( );
184      images.push_back( example );
185
186      cout << "  explode ..." << endl;
187      example = model;
188      example.label( "Explode" );
189      example.backgroundColor( "#000000FF" );
190      example.implode( -1 );
191      images.push_back( example );
192
193      cout << "  flip ..." << endl;
194      example = model;
195      example.label( "Flip" );
196      example.flip( );
197      images.push_back( example );
198
199      cout << "  flop ..." << endl;
200      example = model;
201      example.label( "Flop" );
202      example.flop();
203      images.push_back( example );
204
205      cout << "  frame ..." << endl;
206      example = model;
207      example.label( "Frame" );
208      example.frame( );
209      images.push_back( example );
210
211      cout << "  gamma ..." << endl;
212      example = model;
213      example.label( "Gamma" );
214      example.gamma( 1.6 );
215      images.push_back( example );
216
217      cout << "  gaussian blur ..." << endl;
218      example = model;
219      example.label( "Gaussian Blur" );
220      example.gaussianBlur( 0.0, 1.5 );
221      images.push_back( example );
222
223      cout << "  gaussian blur channel ..." << endl;
224      example = model;
225      example.label( "Gaussian Blur\n(Green Channel)" );
226      example.gaussianBlurChannel( GreenChannel, 0.0, 1.5 );
227      images.push_back( example );
228
229      cout << "  gradient ..." << endl;
230      Image gradient;
231      gradient.size( "130x194" );
232      gradient.read( "gradient:#20a0ff-#ffff00" );
233      gradient.label( "Gradient" );
234      images.push_back( gradient );
235
236      cout << "  grayscale ..." << endl;
237      example = model;
238      example.label( "Grayscale" );
239      example.quantizeColorSpace( GRAYColorspace );
240      example.quantize( );
241      images.push_back( example );
242
243      cout << "  implode ..." << endl;
244      example = model;
245      example.label( "Implode" );
246      example.implode( 0.5 );
247      images.push_back( example );
248
249      cout << "  level ..." << endl;
250      example = model;
251      example.label( "Level" );
252      example.level( 0.20*QuantumRange, 0.90*QuantumRange, 1.20 );
253      images.push_back( example );
254
255      cout << "  level red channel ..." << endl;
256      example = model;
257      example.label( "Level Channel\n(Red Channel)" );
258      example.levelChannel( RedChannel, 0.20*QuantumRange, 0.90*QuantumRange, 1.20 );
259      images.push_back( example );
260
261      cout << "  median filter ..." << endl;
262      example = model;
263      example.label( "Median Filter" );
264      example.medianFilter( );
265      images.push_back( example );
266
267      cout << "  modulate ..." << endl;
268      example = model;
269      example.label( "Modulate" );
270      example.modulate( 110, 110, 110 );
271      images.push_back( example );
272
273      cout << "  monochrome ..." << endl;
274      example = model;
275      example.label( "Monochrome" );
276      example.quantizeColorSpace( GRAYColorspace );
277      example.quantizeColors( 2 );
278      example.quantizeDither( false );
279      example.quantize( );
280      images.push_back( example );
281
282      cout << "  motion blur ..." << endl;
283      example = model;
284      example.label( "Motion Blur" );
285      example.motionBlur( 0.0, 7.0,45 );
286      images.push_back( example );
287
288      cout << "  negate ..." << endl;
289      example = model;
290      example.label( "Negate" );
291      example.negate( );
292      images.push_back( example );
293
294      cout << "  normalize ..." << endl;
295      example = model;
296      example.label( "Normalize" );
297      example.normalize( );
298      images.push_back( example );
299
300      cout << "  oil paint ..." << endl;
301      example = model;
302      example.label( "Oil Paint" );
303      example.oilPaint( );
304      images.push_back( example );
305
306      cout << "  ordered dither 2x2 ..." << endl;
307      example = model;
308      example.label( "Ordered Dither\n(2x2)" );
309      example.randomThreshold(2,2);
310      images.push_back( example );
311
312      cout << "  ordered dither 3x3..." << endl;
313      example = model;
314      example.label( "Ordered Dither\n(3x3)" );
315      example.randomThreshold(3,3);
316      images.push_back( example );
317
318      cout << "  ordered dither 4x4..." << endl;
319      example = model;
320      example.label( "Ordered Dither\n(4x4)" );
321      example.randomThreshold(4,4);
322      images.push_back( example );
323
324      cout << "  ordered dither red 4x4..." << endl;
325      example = model;
326      example.label( "Ordered Dither\n(Red 4x4)" );
327      example.randomThresholdChannel(RedChannel,4,4);
328      images.push_back( example );
329
330      cout << "  plasma ..." << endl;
331      Image plasma;
332      plasma.size( "130x194" );
333      plasma.read( "plasma:fractal" );
334      plasma.label( "Plasma" );
335      images.push_back( plasma );
336
337      cout << "  quantize ..." << endl;
338      example = model;
339      example.label( "Quantize" );
340      example.quantize( );
341      images.push_back( example );
342
343      cout << "  quantum operator ..." << endl;
344      example = model;
345      example.label( "Quantum Operator\nRed * 0.4" );
346      example.evaluate( RedChannel,MultiplyEvaluateOperator,0.40 );
347      images.push_back( example );
348
349      cout << "  raise ..." << endl;
350      example = model;
351      example.label( "Raise" );
352      example.raise( );
353      images.push_back( example );
354
355      cout << "  reduce noise ..." << endl;
356      example = model;
357      example.label( "Reduce Noise" );
358      example.reduceNoise( 1.0 );
359      images.push_back( example );
360
361      cout << "  resize ..." << endl;
362      example = model;
363      example.label( "Resize" );
364      example.zoom( "50%" );
365      images.push_back( example );
366
367      cout << "  roll ..." << endl;
368      example = model;
369      example.label( "Roll" );
370      example.roll( "+20+10" );
371      images.push_back( example );
372
373      cout << "  rotate ..." << endl;
374      example = model;
375      example.label( "Rotate" );
376      example.rotate( 45 );
377      example.transparent( "black" );
378      images.push_back( example );
379
380      cout << "  scale ..." << endl;
381      example = model;
382      example.label( "Scale" );
383      example.scale( "60%" );
384      images.push_back( example );
385
386      cout << "  segment ..." << endl;
387      example = model;
388      example.label( "Segment" );
389      example.segment( 0.5, 0.25 );
390      images.push_back( example );
391
392      cout << "  shade ..." << endl;
393      example = model;
394      example.label( "Shade" );
395      example.shade( 30, 30, false );
396      images.push_back( example );
397
398      cout << "  sharpen ..." << endl;
399      example = model;
400      example.label("Sharpen");
401      example.sharpen( 0.0, 1.0 );
402      images.push_back( example );
403
404      cout << "  shave ..." << endl;
405      example = model;
406      example.label("Shave");
407      example.shave( Geometry( 10, 10) );
408      images.push_back( example );
409
410      cout << "  shear ..." << endl;
411      example = model;
412      example.label( "Shear" );
413      example.shear( 45, 45 );
414      example.transparent( "black" );
415      images.push_back( example );
416
417      cout << "  spread ..." << endl;
418      example = model;
419      example.label( "Spread" );
420      example.spread( 3 );
421      images.push_back( example );
422
423      cout << "  solarize ..." << endl;
424      example = model;
425      example.label( "Solarize" );
426      example.solarize( );
427      images.push_back( example );
428
429      cout << "  swirl ..." << endl;
430      example = model;
431      example.backgroundColor( "#000000FF" );
432      example.label( "Swirl" );
433      example.swirl( 90 );
434      images.push_back( example );
435
436      cout << "  threshold ..." << endl;
437      example = model;
438      example.label( "Threshold" );
439      example.threshold( QuantumRange/2.0 );
440      images.push_back( example );
441
442      cout << "  threshold random ..." << endl;
443      example = model;
444      example.label( "Random\nThreshold" );
445      example.randomThreshold( (0.3*QuantumRange),
446        (0.85*QuantumRange) );
447      images.push_back( example );
448
449      cout << "  unsharp mask ..." << endl;
450      example = model;
451      example.label( "Unsharp Mask" );
452      //           radius_, sigma_, amount_, threshold_
453      example.unsharpmask( 0.0, 1.0, 1.0, 0.05);
454      images.push_back( example );
455
456      cout << "  wave ..." << endl;
457      example = model;
458      example.label( "Wave" );
459      example.alpha( true );
460      example.backgroundColor( "#000000FF" );
461      example.wave( 25, 150 );
462      images.push_back( example );
463
464      //
465      // Create image montage.
466      //
467      cout <<  "Montage images..." << endl;
468
469      for_each( images.begin(), images.end(), fontImage( font ) );
470      for_each( images.begin(), images.end(), strokeColorImage( Color("#600") ) );
471
472      MontageFramed montageOpts;
473      montageOpts.geometry( "130x194+10+5>" );
474      montageOpts.gravity( CenterGravity );
475      montageOpts.borderColor( "green" );
476      montageOpts.borderWidth( 1 );
477      montageOpts.tile( "7x4" );
478      montageOpts.backgroundColor( "#ffffff" );
479      montageOpts.font( font );
480      montageOpts.pointSize( 18 );
481      montageOpts.fillColor( "#600" );
482      montageOpts.strokeColor( Color() );
483      montageOpts.fileName( "Magick++ Demo" );
484      montageImages( &montage, images.begin(), images.end(), montageOpts );
485    }
486
487    Image& montage_image = montage.front();
488    {
489      // Create logo image
490      cout << "Adding logo image ..." << endl;
491      Image logo( "logo:" );
492      logo.zoom( "45%" );
493
494      // Composite logo into montage image
495      Geometry placement(0,0,(montage_image.columns()/2)-(logo.columns()/2),0);
496      montage_image.composite( logo, placement, OverCompositeOp );
497    }
498
499    for_each( montage.begin(), montage.end(), depthImage(8) );
500    for_each( montage.begin(), montage.end(), alphaImage( false ) );
501    for_each( montage.begin(), montage.end(), compressTypeImage( RLECompression) );
502
503    cout << "Writing image \"demo_out.miff\" ..." << endl;
504    writeImages(montage.begin(),montage.end(),"demo_out_%d.miff");
505
506    // Uncomment following lines to display image to screen
507    //    cout <<  "Display image..." << endl;
508    //    montage_image.display();
509
510  }
511  catch( exception &error_ )
512    {
513      cout << "Caught exception: " << error_.what() << endl;
514      return 1;
515    }
516
517  return 0;
518}
519