You are on page 1of 26

The ImageMagick graphics library

A gentle introduction to Magick++


Rev 1.0.5
1 About this document
This document is an introductory tutorial to the free-software Magick++ ++ gra!hics li"rary# and
it thus covers only the "asic Magick++ methods for image mani!ulation. $or a com!lete reference
guide to the Magick++ li"rary the reader is advised to consult the original li"rary documentation#
as well as various a!!lication notes that address s!ecific functionalities %these are freely availa"le
on the internet&.
This document has "een written such that it gradually introduces the various conce!ts that the
Magick++ li"rary is "ased u!on' it starts with a "rief overview of the li"rary and how it is meant to
"e used as a com!onent inside an a!!lication# continues with descri"ing the meaning of a anvas
as the drawing area utili(ed "y the Magick++ li"rary# then it !resents some essential
characteristics of an )mage o"*ect %which is itself "ased on the conce!t of anvas&# and ends with
a detailed !resentation of a collection of methods that the )mage o"*ect !rovides for image
generation# mani!ulation# and storage.
+nly a limited set of Magick++ image mani!ulation methods is covered in this tutorial# "ut this set
does however !rovide the necessary image mani!ulation tools for a large num"er of a!!lications#
including we"-"ased server a!!lications that need to generate dynamic images for em"edding in
we" !ages %e.g. !ie charts# wire gra!hs# "ar gra!hs# annotated !ictures# etc&.
)M,+RTA-T'
The reader is assumed to be familiar with all the C++ terminology that is being used
throughout this document.
License
This document is Copyright (c) Information Technology Group www.itgroup.ro
(c) Alin Avasilcutei, Cornel Paslariu, ucian !ngureanu, "irgil #ager.
Permission is granted to copy, distribute and/or modify this document
under the terms of the G$! %ree &ocumentation icense, "ersion '.(
with no Invariant Sections, no Front-Cover Texts, no ac!-Cover Texts"
2 Introducing the Magick++ library
The Magick++ li"rary is a set of C++ wrapper classes that provides access to the ImageMagick
!ackage functionality from within a ++ a!!lication.
)mageMagick is a free software !ackage used for image mani!ulation# and it is availa"le for al the
ma*or o!erating systems' Linux !indows Mac"# $ and %&'$. )t includes a ./) for rendering
images# command line utilities for image !rocessing# and A,)s for many !rogramming languages'
Magick++ %++&# Magickore %&# Magick0and %&# hMagick %h&# 1Magick %1ava&# 2-Magick %2is!&#
,erlMagick %,erl&# Magick0and for ,3, %,3,&# ,ythonMagick %,ython&# TclMagick %Tcl4T5&.
-ote' )mageMagick is !rovided with automated installers for 2inu6# 0indows# and Mac+7 8
)mageMagick is released under a license that is com!ati"le with# "ut less restrictive than# the .-/
.eneral ,u"lic 2icense' significantly# ImageMagick may be included in and used by a software
package fully or in part with !ro!er attri"ution and with the )mageMagick license file attached.
The Magick++ li"rary can !erform the following classes of o!erations on images'
create new images# or read e6isting images#
edit images ' fli!# mirror# rotate# scale# transform images# ad*ust image colors# a!!ly
various s!ecial effects# or draw te6t# lines# !olygons# arcs# elli!ses and 9e(ier curves#
compose new images "ased on other images#
save images in a variety of formats# including .)$# 1,:.# ,-.# 7;.# and ,ost7cri!t.
Using the Magick++ library in an application
)n order to use the Magick++ li"rary in a ++ a!!lication one should first install the )mageMagick
!ackage %the automated installers may "e used&. +ne needs to include the relevant header files in
the a!!lication<s source%s&# and link the a!!lication "inary against the )mageMagick runtime li"s'
)n the source files' after <#inc$ude %&agic!''"h(< %in the a!!lication<s files# as re=uired&#
add the <using namespace &agic!)< statement# or add the !refi6 <&agic!**< to each
Magick++ class4enumeration name.
)n a .-/ environment the linker<s 2>$2A.7 can "e configured using the &agic!''-config
scri!t' +&agic!''-config --cppf$ags --cxxf$ags --$df$ags --$ibs+
N OT E : the ` character is the backquote character, it cannot be replaced with ' or " !
Fo r e x a m p l e , i n An j u t a 1 . 2. x (on a GN U OS) p a s t e t e l i n e a ! o " e i n t e # Se t t i n $ s % &' o m p i l e r
a n ( )i n * e r Se t t i n $ s % &O p t i o n s t a ! %& A( ( i t i o n a l Op t i o n s : )i n * e r Fl a $ s ()+F) A G S)# ! o x
0indows a!!lications can "e "uilt using a M7;?+ com!iler' they can "e derived from one
of the demo !ro*ects# must shi! with the )mageMagick >22s and must @initiali(e the li"raryA
prior to any Magick++ operation' Initia$i,e&agic!-path.to.Image&agic!./00s1)
2i"rary versions
)mageMagick and the Magick++ li"raries are advertised as "eing under develo!ment at the time
of writing this document. As such# this document contains information a"out the functionality
!rovided "y the li"rary Version 62!"# "ased on actually testing the li"rary A,) for this version.
)t has "een found during the tests that a num"er of advertised features work in an un!redicta"le
manner# or are inconsistent with the li"rary s!ecifications. A very hilarious e6am!le is the
>rawa"leRotation and >rawa"leTranslation o"*ects that re=uire <angle()* %instead of <angle<& and
<displacement()* %instead of <dis!lacement<& as arguments. )f this could "e regarded as some
hacker *oke made "y one of the li"rary im!lementers# more serious !ro"lems seem to e6ist' for
e6am!le# the a"ove two coordinate system transformations don<t work together at all %they give
nonsensical effects when drawing o"*ects on a canvas&.
IM#$%TA&T'
This document only presents features that were effectively tested on Magick++ version +.).,.-
' Images in the Magick++ library
)n o"*ect oriented gra!hics# an image %also known as a <digital image<& is descri"ed "y an ob.ect
featured with a self/rendering method. )n the Magick++ im!lementation each such image o"*ect
always has an associated canvas which actually holds the !icture data %or it may also "e an empty
canvas# which is not the same with a B"lankB canvas "ecause in the latter case the canvas actually
holds a "ackground color&.
(hat is a )an*as
A canvas can "e descri"ed from several !ers!ectives'
$rom visual !oint of view# a canvas re!resents a virtual surface where an application can
draw# !aint or !aste !ieces of image.
$rom the !oint of view of the internal re!resentation# the canvas is stored as an array of
pixels %also known as a <"itma!<&# with each !i6el "eing stored in an certain format %usually
"ased on the Red-.reen-9lue-Al!ha com!onents# "ut other !i6el formats may also "e
im!lemented&.
The +eometry class
A num"er of Magick++ methods use a !arameter of ty!e <.eometry< for s!ecifying %mostly& the
si(e of a rectangular o"*ect. The <.eometry< class is relatively com!le6 %actually reflecting the 811
geometry s!ecification&# "ut for the purpose of this tutorial it can "e thought of as "eing a
mechanism that encapsulates two dimensions 0x and y1 into a single ob.ect which is further used
"y Magick++ methods.
2eometry**2eometry-unsigned int x, unsigned int y1)
2eometry**2eometry-const String3 geometry1)
// examples:
2eometry g4-455,6551) // numeric constructor
2eometry g6-7855x955:1) // string constructor
#i,els in Magick++ library
The ,i6el,acket structure
The data format of the !i6el is of ty!e <2ixel2acket<. The <,i6el,acket< is a C structure used to
re!resent !i6els. The ,i6el,acket mem"ers are'
<red<
<green<
<"lue<
<o!acity< ' this ,i6el,acket mem"er defines the @o!acityA of the !i6el# thus allowing an
image to include trans!arency information %an e6am!le of image file format that is a"le of
!reserving the image trans!arency information is the ,-. format&
Cuanti(ing levels' the Cuantum ty!e and the Ma6R.9 constant
:ach mem"er of the ,i6el,acket structure is an unsigned integer num"er# and de!ending on how
the li"rary was com!iled it may "e im!lemented on D "its or 1? "its %i.e. the total si(e of a
,i6el,acket is EFDGHI "its or EF1?G?E "its&J thus# the num"er of =uanti(ing levels for each of the
,i6el,acket com!onents can "e IKDGI5? or IK1?G?55H?.
)n any case# Magick++ !rovides the a!!lications with the *Max345* constant which always
specifies the number of 6uanti7ing levels / 8 as availa"le on the !articular version of the li"rary
that is "eing used %e.g. for a li"rary version com!iled with D "its !er ,i6el,acket com!onent the
Ma6R.9 constant is I55&.
)n order to accommodate the im!lementation-s!ecific values of =uanti(ing levels# Magick++
!rovides the <Cuantum< data ty!e. This ty!e is an unsigned integer value that may "e
im!lemented as unsigned char# unsigned short int# etc# "ut it is always guaranteed to "e a"le of
holding all the =uanti(ing levels as availa"le on the !articular version of the li"rary that is "eing
used %i.e. it can always hold the <Ma6R.9< value&.
The ,i6el,acket structure mem"ers are of ty!e Cuantum# and are in range L0# Ma6R.9M'
struct Pixe$Pac!et ;
<uantum red)
<uantum green)
<uantum b$ue)
<uantum opacity)
=)
The olor class
The Magick++ li"rary !rovides a class <olor< that can "e assigned to# and from# ,i6el,acket data
structures# thus facilitating an o"*ect-oriented a!!roach for handling ,i6el,acket data structures.
The <olor< class is also used as argument ty!e "y a num"er of Magick++ methods that set the
color attri"utes of various gra!hical o!erations.
The following ta"le lists the most im!ortant olor methods'
// constructors
Co$or**Co$or-1)
Co$or**Co$or-const string3 co$or1) // the string 'color' is one of a set of "inbuilt"
// colors: "red", blue, "magenta", etc
Co$or**Co$or-<uantum red, // parameters in range 0 to MaxRG
<uantum green,
<uantum b$ue,
<uantum a$pha1) // alpha is transparenc!: 0"opa#ue, MaxRG"full! transparent
Co$or**Co$or-const Pixe$Pac!et3 pixe$1)
// getter functions
<uantum Co$or**red<uantum-1)
<uantum Co$or**green<uantum-1)
<uantum Co$or**b$ue<uantum-1)
<uantum Co$or**a$pha<uantum-1)
// setter functions
void Co$or**red<uantum-<uantum red1)
void Co$or**green<uantum-<uantum green1)
void Co$or**b$ue<uantum-<uantum b$ue1)
void Co$or**a$pha<uantum-<uantum a$pha1)
// con$ersion functions to and from %ixel%ac&et
Co$or**operator Pixe$Pac!et-1 const)
const Co$or3 Co$or**operator>-const Pixe$Pac!et3 pixe$1)
The Magick++ Image ob-ect
The )mage class
A Magick++ )mage is a s!ecial o"*ect that im!lements a num"er of characteristic features'
)t has methods for self/rendering on an out!ut interface %a com!uter screen# a file# etc&
)t has an associated canvas# where the canvas is the data storage area used to hold the
!icture data that the image o"*ect can render
)t has a set of s!ecific methods that allow various ways to access the canvas of the )mage
such that the !icture can "e modified
)t can "e used in con*unction with other )mage o"*ects in order to create new composite
images
The canvas format
The Magick++ )mage canvas is stored internally as a contiguous array of pixels# where each !i6el
is a structure of ty!e <,i6el,acket<.
-ote' There is no special *Canvas* type defined "y the Magick++ li"rary
Trans!arency
As it was already stated in the <,i6el,acket structure< section a"ove# the format of an individual
!i6el %of ty!e <,i6el,acket<& enca!sulates the three fundamental color com!onents <red<# <green<#
and <"lue<# !lus an e6tra <o!acity< information. The *opacity* component is used when combining
multiple image elements on the same canvas %the various Magick++ methods of drawing and
com"ining images are !resented in su"se=uent sections throughout this document&
:6am!les'
0hen a green line is drawn over a red "ackground# if the red "ackground is totally o!a=ue
and the green line has 50N o!acity then the resulting line will actually have a Bgrayish
yellowB color %note that this Bgrayish yellowB looks very different from a Btrue yellowB on
the screen&.
7imilarly# when !lacing a semitrans!arent image over an o!a=ue image# the resulting
image will "e a blending of the colors coming from "oth images %"ased on the o!acity
values involved in the !i6el-"y-!i6el "ending !rocess&.
-ote' if !asting a fully trans!arent image over a <su!!ort image<# the resulting image<s !i6els will
"e e6actly the !i6els of the <su!!ort image<# i.e. the opacity information of the pasted image is not
copied over the value of the opacity of the support image but rather a blending algorithm is used.
Important limitations for transparency/related operations9
-ot all image formats su!!ort trans!arency# and Magick++ itself has its own limitations when
loading4saving images that contain trans!arency.
Magick++ li"rary functions can load images that contain trans!arency information if their
format is .)$ or ,-.
Magick++ li"rary functions can preserve the trans!arency information if the save format is
,-.
reating an image
)mages are created using the )mage class contructors. A %!ossi"ly em!ty& canvas is automatically
created when an )mage o"*ect is created. The created )mage o"*ect uses its associated canvas for
storing the !icture data# and for !erforming the various gra!hical o!erations.
Image**Image-1)
Image**Image-const Image3 source.image1) // copy constructor
Image**Image-const 2eometry3 si,e, const Co$or3 co$or1)
Image**Image-const string3 fi$e.$ocation.or.?@01)
Image**Image-const $ob3 source.b$ob1) // lobs are discussed in a later section belo'
// create an empt!(can$as image
//this is )not) a "blan&" image, it's completel! empt! as its can$as has 0x0 dimnesions
Image empty.image-1)
// create a blan& image can$as 'ith *+0x+,0 si-e and ''hite' color as bac&ground:
Image b$an!.image- 2eometry-A95, 9B51, Co$or-&ax@2, &ax@2, &ax@2, 511)
// or also, b! using the automatic .// t!pe con$ersions for the arguments:
Image b$an!.image-CA95x9B5C, CwhiteC1)
// create an image from 0R1
Image ur$.image-Chttp*//www"serverDame"com/image"gifC1)
Image $oca$.fi$e.image-Cmy.image"gifC1) // here the 0R1 points to the local files!stem
// create an image from a lob 2details folollo' in the lob secttion belo'3
Image image.from.b$ob-my.b$ob1)
-ote' Magick++ documentation recommends automatic )mage varia"les %i.e. allocated on the
stack# via declaration of local varia"les& as the !refered way of creating )mage o"*ects# instead of
e6!licit allocation %via <new<&.
Accessing image attri"utes
// .an$as geometr!
unsigned int Image**co$umns-1) // returns an unsigned int representing the m!4image 'idth
unsigned int Image**rows-1) // returns an unsigned int representing the m!4image heigth
// the image 5ormat
// this attribute is )not) related to the internal representation of the image on can$as,
// 'hich is al'a!s a %ixel%ac&et arra!6
// it is automaticlall! set 'hen reading an image based on the image encoding
// or it can be set 'ithin the program
void Image**magic!-const string3 image.format1) // sets the m!4image format6
// the format string can be "G75", etc
string Image**magic!-1) // returns a string $alue representing the
// image format 2e8g8 G75, 9%:G, etc3
// ;otes:
// for a ne' image, this attribute is automaticall! set to a special 'Magic&// internal
// format' $alue of "<." 2.onstant image uniform color36 the rele$ance of this attribute
// is presented in follo'ing sections
Reading and writing images
Image**read-const string3 fi$ename1)
Image**write-const string3 fi$ename1)
Image**write-$obE b$ob1) // 'riting to lobs is discussed in the lobs section belo'
// Reading the contents of a dis& file into an image ob=ect can be performed
// if the default 7mage costructor 'as used
// :xample:
Image my.image-1) // create an )empt!) image using the default 7mage constructor
my.image"read-Ca2IFImageFi$e"gifC1) // read a G75 image file from dis&6
// the image format is automaticall! set to G75
// >riting an 7mage ob=ect to a dis& file:
// the format of the image file is either specified b! the file extension,
// or if the file extension is missing then the 'rite format is ta&en from the image's
// "format" attribute 2see the '7mage::magic&23' method abo$e3
// :xample:
my.image"magic!-CpngC1) // set the "format" attribute of m!4image to %;G
my.image"write-Cfi$e.name.no.extensionC1) // 'rite to dis& an image file 2based on
// m!4image can$as36 the image is sa$ed to the
// file file4name4no4extension in %;G format
my.image"write-Cfi$e.name.exp$icit.extension"gifC1) // 'rite to dis& an image file 2based
// on m!4image can$as36 the format of
// file4name4explicit4extension is
// G75, and )not) %;G
// ;?@: : 'riting 'm!4image' to dis& $ia 'Magic&::'rite23' in a G75 file format doesn't
// change the m!4image format 2i8e8 the "format" attribute m!4image format remains %;G3
)M,+RTA-T' if an <)mage< o"*ect is saved in a format which does not su!!ort the full color
set of the image to "e saved# then the <)mage''write%&< method will alter the image that is
"eing saved. 7uch a situation can "e avoided "y first making a co!y of the image to "e
saved# and then saving the co!y in the desired format'
// example: sa$e 'm!4image' b! means of a temporar! cop!
// in order to pre$ent the original from being altered
Image temp.image-my.image1) // ma&e a cop! of the image to be sa$ed
temp.image"write-7gif.version"gif:1) // sa$e the cop! oin G75 format
.etting direct access to the canvas !i6els
// set or get the color for the pixel at position 2x,!3 on the can$as
void Image**pixe$Co$or-unsigned int x, unsigned int y, const Co$or3 co$or1)
Co$or Image**pixe$Co$or-unsigned int x, unsigned int y1)
// :xample: setting pixels
Image my.image-CA95x9B5C, CwhiteC1) // start 'ith creating a 'hite(bac&ground can$as
my.image"pixe$Co$or-F5,F5,Co$or-CredC11) // set the pixel at position 2A0,A03 to red
my.image"pixe$Co$or-F,F,Co$or-&ax@2,5,5,&ax@2/611) // set semitransparent red at 2A,A3
// :xample 2continued from abo$e3: reading pixels
Co$or pixe$.samp$e) // create a color pixel ob=ect
pixe$.samp$e > my.image"pixe$Co$or-F,F1) // set pixel4sample 'ith the $alue read form
// pixel position 2A,A3
The ,i6el ache' getting indirect access to an image canvas
The !i6els %of ty!e <,i6el,acket<& constituting the canvas of an )mage o"*ect can "e also accessed
using a s!ecial method that involves the creation of an <image !i6el cache< which# as its name
suggests# is a tem!orary %cache& works!ace where a num"er of gra!hical o!erations can "e
!erformed without having to u!date the image itself after each such o!eration.
The data type !rovided "y the Magick++ li"rary in order to assist the creation and mani!ulation of
an image !i6el cache is <,i6els<# and re!resents a rectangular window %a view& into the actual
image !i6els %the image may "e in memory# memory-ma!!ed from a disk file# or entirely on disk&.
The way the !i6els are stored inside the image !i6el cache is identical with the way they are
stored for a canvas# i.e. a contiguous array of ,i6el,acket structures.
)n order to use the image !i6el cache one must'
reate a !i6el cache associated with an image "y using the ,i6els constructor %it takes an
image reference as argument&
+"tain a region from the e6isting image via the ,i6els class <get%&< methodJ this method
returns a ,i6el,acketF value which !oints to the first !i6el in the !i6el cache
At this stage# the !i6els from the cache can "e read and4or written via direct access to the
com!osing ,ie6l,acket structures
$inally# any changes made to the !i6el cache must "e concluded with a <sync%&< function
that u!dates the actual image with the changes that were made in the !i6el cache.
-ote' The main "enefit of the <,i6els< class is that it !rovides efficient access to raw image pixels.
>e!ending on the ca!a"ilities of the o!erating system# and the relationshi! of the window to the
image# the !i6el cache may "e a co!y of the !i6els in the selected window# or it may "e the actual
image !i6els. )n any case calling sync%& insures that the "ase image is u!dated with the contents
of the modified !i6el cache.
Pixe$s**Pixe$s-const Image3 image1 // create a pixel cache and connect it to an image
Pixe$Pac!etE Pixe$s**get-unsigned int start.x, unsigned int start.y,
unsigned int si,e.x, unsigned int si,e.y1 // cache a rectangular image area
// ;otes:
// ) before creating a %ixels cache from an image, the image must be "loc&ed"
// using the '7mage::modif!7mage23' method
// ) after finali-ing the operations on the %ixels cache the image must be updated
// 'ith the '%ixels::s!nc23' method
// :xample of using an image pixel cache
Image my.image-CA95x9B5C, CwhiteC1) // 'e'll use the 'm!4image' ob=ect in this example
my.image"modifyImage-1) // :nsure that there is onl! one reference to
// underl!ing image6 if this is not done, then the
// image pixels )ma!) remain unmodified8 BCCCD
Pixe$s my.pixe$.cache-my.image1) // allocate an image pixel cache associated 'ith m!4image
Pixe$Pac!etE pixe$s) // 'pixels' is a pointer to a %ixel%ac&et arra!
// define the $ie' area that 'ill be accessed $ia the image pixel cache
int start4x " E0, start4! " F0, si-e4x " F00, si-e4! " E006
// return a pointer to the pixels of the defined pixel cache
pixels " m!4pixel4cache8get2start4x, start4!, si-e4x, si-e4!36
// set the color of the first pixel from the pixel cache to blac& 2x"E0, !"F0 on m!4image3
Epixe$s > Co$or-Cb$ac!C1)
// set to green the pixel F00 from the pixel cache:
// this pixel is located at x"0, !"E in the pixel cache 2x"E0, !"FE on m!4image3
)-pixe$s'6551 > Co$or-CgreenC1)
// no' that the operations on m!4pixel4cache ha$e been finali-ed
// ensure that the pixel cache is transferred bac& to m!4image
my.pixe$.cache"sync-1)
9lo"s' storing encoded images in memory
:ncoded images %e.g. 1,:.# .)$# etc& are most often written-to and read-from a disk file %"y using
the )mage o"*ect<s methods for saving4reading images in various formats to4from file&# "ut they
may also reside in memory. :ncoded images in memory are also known 5L"5s - 9inary 2arge
+"*ects. Magick++ !rovides the <9lo"< class for re!resenting images that are stored in memory in
encoded format.
$ob**$ob-1)
$ob**$ob-voidE data, unsigned int si,e1) // explicitl! specifies a memor! area to be
// associated 'ith the ne' lob ob=ect
$ob**operator>-const $ob3 b$ob1)
// :xamples of using lobs in con=uction 'ith 7mages
$ob my.b$ob) // create a blob
Image my.image-Cmy.image"gifC1) // create an image form a G75 image file
my.image"magic!-CGPH2C1) // set 9%:G output format
my.image"write-3my.b$ob1) // encode 'm!4image' in 9%:G format,
// and store the encoded image in m!4blob
Image image.from.b$ob-my.b$ob1) // create an image from the 9%:G blob
// 2use the lob(based 7mage constructor3
image.from.b$ob"magic!-C&PC1) // set the image format to bitmap
image.from.b$ob"write-Cimage.from.b$ob"bmpC1) // sa$e the image on dis& in M% format
" .ra/able ob-ects
The Magick++ drawing mechanism is "ased on creating *drawable ob.ects* which are afterwards
placed on the canvas using s!ecific methodsJ these methods s!ecify the !osition where the
drawa"le o"*ects are to "e !laced# the trans!arency of the drawing o!erations# etc. Thus# the
Magick++ li"rary takes an ob.ect/oriented approach to drawing %where the o"*ects are the
drawa"le o"*ects&# as o!!osed to other gra!hical li"raries that only !rovide drawing functions that
directly modify the !i6els on a canvas.
This cha!ter incrementally introduces the conce!ts "ehind the Magick++ drawing mechanism#
together with a selected set of drawa"le o"*ects.
0oundation concepts o1 the Magick++ dra/ing mechanism
The generic >rawa"le class
The <>rawa"le< class is a "ase class from which all drawa"le o"*ect classes are derived. All
gra!hical o"*ect classes %such as <>rawa"le2ine<# <>rawa"leArc<# <>rawa"le9e(ier<# etc& are derived
from the "ase <>rawa"le9ase< class.
The oordinate class
The <oordinate< structure re!resents a !air of %6#y& coodinates# and a <oordinate list< re!resents a
list of o"*ects of <oordinate< ty!e %i.e. a listOoordinateP&. 7ome of the constructors of the
>rawa"le classes acce!t and4or re=uire as argument a oordinate# or a oordinate list.
The default values for the system of coordinates< %0#0& !osition is the to! left corner of the image
canvas where the drawings are !erformed# while the default rotation angle for drawings is 0.
-ote' Magick++ !rovides a method for modifying "oth the origin of the draw system of
coordinates and the rotation angle from their default values. At the time of writing this
document# this li"rary feature has serious im!lementation "ugs and thus it was chosen not
to "e included here. As a !urely informative reference# this feature relies on a cou!le of
@control o"*ectsA called <>rawa"leRotation%&< and <>rawa"leTranslation%&<
Ty!es of drawa"le o"*ects
There are two categories of drawa"le o"*ects# "ased on what effect they !roduce on an image
canvas when they are drawn' the @Rendera"le o"*ectsA and the @ontrol o"*ectsA
Rendera"le o"*ects
This class of o"*ects effectively modify a specific set of pixels on the canvas according to their
geometryJ an e6am!le of such an o"*ect is <>rawa"le2ine<
ontrol o"*ects
+"*ects of this kind do not produce an immediate effect on the canvas when they are drawn# "ut
rather they control the way in which Rendered o"*ects are drawn. $or e6am!le# such a control
o"*ect is <>rawa"le7trokeolor< which controls the color that will "e used to draw the outline of the
Rendered o"*ects that are drawn %details on the control mechanism are !resented in the
!aragra!hs "elow&
.ravityTy!e
The .ravityTy!e is a enumeration ty!e that is used for s!ecifying the !osition of a gra!hical o"*ect
within the "ounds of an )mageJ it has the following values' <-orth0est.ravity<# <-orth.ravity<#
<-orth:ast.ravity<# <0est.ravity<# <enter.ravity<# <:ast.ravity<# <7outh0est.ravity<#
<7outh.ravity<# <7outh:ast.ravity<. The default value for gravity is -orth0est.ravity %i.e. the
u!!er-left corner&.
.ra/ing on an Image can*as
;ll the drawable ob.ects can be drawn on an Image*s canvas using the *Image99draw01* method#
and this is the recommended way to !erform drawing o!erations. The <)mage''draw%&< method is
s!ecially !rovided for this !ur!ose# and it can take as arguments a list of Coordinates# individual
<rawable o"*ects# or a list of <rawable o"*ects.
The draw%& method
The drawa"le o"*ects that the draw%& method acce!ts as arguments can "e "oth <Rendering
o"*ects< and <ontrol o"*ects<.
>rawa"le o"*ects may "e drawn *one/by/one* via successive invocations of the
)mage''draw%>rawa"le& method for each o"*ect to "e drawn# or may "e drawn *all/at/once*
"y !assing a listO>rawa"leP o"*ects to the )mage''draw%& method.
// dra' a pol!gon shape b! using its nodes' coordinates
void Image**draw -const $ist%Coordinate(3 po$ygon.node.$ist1)
// dra' one shape or text on a can$as using a single Gra'able ob=ect
void Image**draw -const /rawab$e3 drawab$e.obIect1)
// dra' shapes or text on a can$as using a list of Gra'able ob=ects
void Image**draw -const $ist%/rawab$e(3 drawab$e.obIect.$ist1)
2etting up the dra/34 parameters
A num"er of draw !arameters-related settings can and4or must "e made "efore starting to
!erform a se=uence of draw o!erations# e.g. setting u! a @!enA color %a.k.a. <7troke color<&
!arameter "efore actually drawing a gra!hic sha!e# etc. The s!ecifics of how these !arameters
are "eing set u! de!end on whether a <one-"y-one< or <all-at-once< drawing method is used %these
two drawing methods are e6em!lified in the !aragra!hs "elow&.
)M,+RTA-T' It is highly advisable not to rely upon any implicit default values for the draw
settings as they can produce very counterintuitive results. Instead always explicitly set up
all the draw characteristics through the use of the corresponding formatting ob.ects and(or
methods.
>rawing o"*ects one-"y-one
)n this drawing scenario the settings are made to the Image ob.ect that will be drawn upon# and
then a series of draw o!erations are !erfomed on the )mage canvas. The )mage class methods
that su!!ort setting the draw o!tions are listed "elow'
Image**stro!eCo$or-const Co$or3 co$or1) // set the outline color 2i8e8 the color of
// the countour of the shape3
Image**fi$$Co$or-const Co$or3 co$or1) // set the fill color 2see also the note on
// dra'ing open contours belo'3
Image**stro!eJidth-doub$e width1) // set the 'idth to use 'hen dra'ing lines
// or ob=ect outlines
Image**stro!eKntiK$ias-boo$ mode1) // enable or disable dra' anti(aliasing for
// outlines6 default is enabled
Image**font-const String3 font.name1) // set the font face for text operations on the
// canvas -detai$s on the font.name format be$ow1
// :xample:
my.image"stro!eCo$or-CredC1) // this 'ill set the outline color to red for the
// ob=ects that 'ill be subse#uentl! dra'n
my.image"stro!eKntiK$ias-fa$se1) // this 'ill disable the anti(aliasing for the outlines
// that 'ill be be subse#uentl! dra'n
&otes9
the drawing settings listed a"ove remain set until new drawing setting will "e made.
"ecause it is highly unadvisable to use implicit default values# this method should only "e
used for draw o!erations that do not de!end on any other settings e6ce!t the a"ove
>rawing o"*ects all-at-once
)n this drawing scenario a list of drawable ob.ects is generated and then !assed "ulk to the draw
method. )n this case one has to "uild a set of special =formatting= control ob.ects that determine
the !arameters of the B"ulk drawB o!eration. $or !erforming the actual draw on a canvas one has
to insert the formatting ob.ects first followed by the rendering ob.ects into a listO>rawa"leP# and
then !ass this list to the draw method.
)M,+RTA-T' The draw attributes 0i.e. the >formatting? ob.ects1 at the beginning of the
draw list determine the draw characteristics for all drawable ob.ects from the list. hanging
the drawing attri"utes within the same draw list will generally result in erroneous out!ut.
$or drawing several sha!es# each with its own drawing attri"utes# always use separate
drawing lists one for each set of draw attributes.
Te6t formatting o"*ects
These o"*ects determine the font face and si(e when Bdrawing te6tB on the canvas
/rawab$eFont**/rawab$eFont-const string3 font.name1 // 'font4name' is a string containing
// a full! #ualified < font name
// 5ollo'ing is a listing of se$eral font names generall! a$ailable on 1inux s!stems
// 2full! #ualified < font names3
// C-E-he$vetica-Lmedium/bo$dM-Lr/oM-norma$-E-E-LB5/455/465/495/4B5M-NF-NF-E-E-isoBBFO-4C
// P typica$ usage si,e is 465
// C-misc-fixed-Lmedium/bo$dM-Lr/oM-Lnorma$/semicondensedM-E-E-L455/465/495/655M-NF-NF-E-E-
isoBBFO-4C)
// P typica$ usage si,e is 465, and for this si,e a$$ combinations are va$id
// P for a$$ other si,es the combinations are restricted, but the Q-medium-r-norma$-Q
// font variants wor! for a$$ si,es
// :xample of setting up a Gra'able5ont ob=ect
/rawab$eFont-C-E-he$vetica-medium-r-norma$-E-E-465-E-E-E-E-isoBBFO-4C1)
$ormatting o"*ects for +utlines %i.e. contours&
These o"*ects determine the draw characteristics for drawa"le o"*ects< contours 0see also the note
on drawing open contours below1
// Het color to use 'hen dra'ing lines or ob=ect outlines
// 2see also the note on dra'ing open contours belo'3
/rawab$eStro!eCo$or**/rawab$eStro!eCo$or-const Co$or3 co$or1)
// Het 'idth to use 'hen dra'ing lines or ob=ect outlines8
/rawab$eStro!eJidth**/rawab$eStro!eJidth-doub$e width1)
// :nable/disable the anti(aliasing 'hen dra'ing lines or ob=ect outline
// 2 to disable, use 'false' as parameter3
/rawab$eStro!eKntia$ias**/rawab$eStro!eKntia$ias-boo$ mode1)
$ormatting o"*ects for $ill o!erations
These o"*ects determine the fill color and o!acity that will "e used when a fill o!eration is re=uired
// Hpecif! dra'ing ob=ect fill color 'here filling is possible
/rawab$eFi$$Co$or**/rawab$eFi$$Co$or-const Co$or3 co$or1)
Important note about drawing lines text and open contours
,rior to a draw o!eration one always has to set the fill color to fully transparent %i.e.
<olor%6#6#6#Ma6R.9&< & for any Bo!enB drawa"le o"*ect %i.e. straight lines text and contours that
are not closed&. This is necessary even for simple open countours such as a polyline formed of two
lines at a certain angle# "ecause otherwise the triangle determined "y the two lines !lus the
imaginary line that connects their non-common e6tremities would "e filled "y the fill color %unless
set to fully trans!arent&. Also# even when drawing a simple straight line# if the fill color is not set to
fully trans!arent# then drawing the line over certain "ackground colors can cause im!revisi"le
results.
:6am!le'
the left image "elow "elow !resents the result of drawing a two/segment polyline when not
setting a fully trans!arent fill color %the fill color has taken a Magick++ default value# which
was in this case fully-o!a=ue "lack&# and the right image !resents the result of drawing the
same two-segment !olyline when the fill color was e6!licitly set to fully trans!arent.
Illustration of the way Magick++ performs fill on open contours
$ormatting o"*ects for setting the >rawing ,attern for +utlines
To set a non-continuous !attern for line drawing# Magick++ !rovides the <>rawa"le>ashArray<
class. The >rawa"le>ashArray constructor take as argument a 7ero/terminated array of doubles
that defines the stroke line !attern# i.e. s!ecifies the lengths of alternating dashes and ga!s
%"lanks& in !i6els.
9efore setting the <dashQ!atternQarray<# one needs to set the 7trokeolor - and o!tionally the
7troke0idth - for dashes# and the $illolor for ga!s. The width for @illColor is always 8 pixel# and
Magick++ doesn<t !rovide any way to set other value for it %see Ind line in the e6am!le "elow&.
/rawab$e/ashKrray**/rawab$e/ashKrray-doub$e dash.pattern.array1)
// :xample for setting dra' patterns
// @he dash4pattern arra!s 'hich define the lines from the image belo' are:
doub$e dash.array.Bstro!e.Bfi$$LM > ;B,B,5=) // defines the Est 2blue3 line pattern
doub$e dash.array.4Fstro!e.Bfi$$.Bstro!e.Bfi$$LM > ;4F,B,B,B,5=) // Fnd line 2red(blue3
doub$e dash.array.65stro!e.4Ffi$$.Fstro!e.4Ffi$$LM > ;65,4F,F,4F,5=) //Ird line 2green3
// @he dra'n lines ha$e the follo'ing "dashing patterns":
// the first line: ,dash4pixels ( ,gap4pixels, and 0 indicating the end of the pattern8
// the second line: EAdash4pixels ( ,gap4pixels ( ,dash4pixels ( ,gap4pixels, and 0 2end3
// the third line: F0dash4pixels ( EAgap4pixels ( Adash4pixels ( EAgap4pixels, and 0 2end3
// @he portion of the source code that determines the dra' pattern for the first t'o
// of the abo$e lines is listed belo':
$ist%/rawab$e( b$ue.dashed.$ine, red.b$ue.dashed.$ine)
// setting controls for Est line
b$ue.dashed.$ine"push.bac!-/rawab$eStro!eCo$or-Cb$ueC11)
b$ue.dashed.$ine"push.bac!-/rawab$eStro!eJidth-611)
b$ue.dashed.$ine"push.bac!-/rawab$eFi$$Rpacity-5"511)
b$ue.dashed.$ine"push.bac!-/rawab$e/ashKrray-dash.array.Bstro!e.Bfi$$11)
// setting controls for Fnd line
red.b$ue.dashed.$ine"push.bac!-/rawab$eStro!eCo$or-CredC11)
red.b$ue.dashed.$ine"push.bac!-/rawab$eFi$$Co$or-Cb$ueC11)
red.b$ue.dashed.$ine"push.bac!-/rawab$eStro!eJidth-611)
red.b$ue.dashed.$ine"push.bac!-/rawab$e/ashKrray-dash.array.4Fstro!e.Bfi$$.Bstro!e.Bfi$$11)
%enderable ob-ects
This section !resents a selection of "asic rendering o"*ect ty!es which can "e used as the "asic
"uilding "locks for a large set of gra!hical a!!lications.
2ine and ,olyline
To draw a line%segment&4!olyline on the canvas# use a <>rawa"le2ine<4 <>rawa"le,olyline< o"*ect in
con*unction with the <draw%&< method. A !olyline is defined "y at least three !oints.
// the 'Gra'able1ine' class constructor protot!pe
/rawab$e0ine**/rawab$e0ine-doub$e start.x, doub$e start.y, doub$e end.x, doub$e end.y1)
// the 'Gra'able%ol!line' class constructor protot!pe
/rawab$ePo$y$ine**/rawab$ePo$y$ine-const $ist%Coordinate(3 coordinates1)
// :xample:
$ist%Coordinate( po$y$ine.coordinate.$ist)
po$y$ine.coordinate.$ist"push.bac!-Coordinate-455,45511)
po$y$ine.coordinate.$ist"push.bac!-Coordinate-4F5,4F511)
po$y$ine.coordinate.$ist"push.bac!-Coordinate-655,45511)
my.image"draw - /rawab$ePo$y$ine-po$y$ine.coordinate.$ist11)
,olygons
To draw !olygon sha!es on the canvas# the Magick++ li"rary !rovides a generic
<>rawa"le,olygon< class and a s!eciali(ed classes to draw rectangles' <>rawa"leRectangle<.
The <>rawa"le,olygon< constructor needs a list of Coordinates as !arameter. >e!ending on
the num"er of elements in the listOoordinateP# the <>rawa"le,olygon< o"*ect might
descri"e a triangle %H elements in listOoordinateP&# =uadrilateral %E elements&# etc.
The <>rawa"leRectangle< constructor needs the coordinates of the to!-left and "ottom-right
corner of the rectangle
/rawab$ePo$ygon**/rawab$ePo$ygon-const $ist%Coordinate(3 po$ygon.coordinates1
/rawab$e@ectang$e**/rawab$e@ectang$e-doub$e top.$eft.x, doub$e top.$eft.y,
doub$e bottom.right.x, doub$e bottom.right.y1
// :xample:
$ist%/rawab$e( obIects.to.draw) // push in list the rendering ob=ects and the
// associated dra' formatting ob=ects
$ist%Coordinate( coords.of.triang$e) // push in list the coordinates of a triangle
coords.of.triang$e"push.bac!-Coordinate-5,511)
coords.of.triang$e"push.bac!-Coordinate-65,45511)
coords.of.triang$e"push.bac!-Coordinate-95,511)
// create a triangle and push it in the dra'able ob=ects list
obIects.to.draw"push.bac!-/rawab$ePo$ygon-coords.of.triang$e11)
// create a rectangle and push it in the dra'able ob=ects list
obIects.to.draw"push.bac!-/rawab$e@ectang$e-455,455, 6F5,65511)
// perform the actual dra' on m!4image 2the list of ob=ects4to4dra' are dra'n3
my.image"draw-obIects.to.draw1)
9e(ier curves
To draw curves on the canvas# the Magick++ li"rary !rovides the >rawa"le9e(ier o"*ect.
The >rawa"le9e(ier constructor has a list of Coordinate as argument ty!e' >rawa"le9e(ier%const
listOoordinatePR coordinateQlist&. The !oints in the list determine the way in which the curve is
drawn in the following way'
the first !oint# !1# s!ecifies the !osition from which the curve will start
the second !oint# !I# is used in con*unction with the first !oint !1 to determine the angle at
which the curve starts# and how how fast the curve will diverge from the start tangent
the oriented segment L!1#!IM determines the start angle %i.e. the curve will start from
!1 "y "eing tangent to the L!1#!IM segment&
the length of the segment L!1#!IM determines how fast the curve will diverge from the
start tangent in order to reach its ending !oint
the third !oint# !H# is used in con*unction with the fourth !oint !E to determine the angle at
which the curve ends# and how how fast the curve will a!!roaches the end tangent
the oriented segment L!H#!EM determines the ending angle %i.e. the curve will end in !E
"y "eing tangent to the L!H#!EM segment&
the length of the segment L!H#!EM determines how fast the curve will converge to the
end tangent in order to reach its ending !oint
the fourth !oint# !E# s!ecifies the final !osition at which the curve will end
The Magick++ li"rarly only im!lements !ro!erly the cu"ic "e(ier curves %as descri"ed a"ove&J
higher order 9e(ier curves must "e o"tained "y *oining multi!le u"ic 9e(ier curves.
$ollowing is a code e6am!le for drawing two 9e(ier curves# with the difference "etween them only
residing in the !ositioning of one of the control !oints %namely ,I&'
/rawab$ee,ier**/rawab$ee,ier-cont $ist%Coordinate(3 be,ier.coords.and.contro$.points1
// :xamples:
// @he code for the 1:5@(side cur$e belo'
$ist%Coordinate( $eft.cubic.be,ier.coord)
$eft.cubic.be,ier.coord"push.bac!-Coordinate-F5,4F511) // %E from image
$eft.cubic.be,ier.coord"push.bac!-Coordinate-4F5,6511) // %F from image
$eft.cubic.be,ier.coord"push.bac!-Coordinate-4F5,65511) // %I from image
$eft.cubic.be,ier.coord"push.bac!-Coordinate-6F5,65511) // %+ from image
my.image"draw- /rawab$ee,ier-$eft.cubic.be,ier.coord11)// dra' the left(side cur$e
// @he code for the R7GJ@(side cur$e belo'
$ist%Coordinate( right.cubic.be,ier.coord)
right.cubic.be,ier.coord"push.bac!-Coordinate-F5,4F511) // %E from image 2same as abo$e3
right.cubic.be,ier.coord"push.bac!-Coordinate-NF,45511) // %F: G755:R:;@ 5R?M .0RK: L?K:
right.cubic.be,ier.coord"push.bac!-Coordinate-4F5,65511)// %I from image 2same as abo$e3
right.cubic.be,ier.coord"push.bac!-Coordinate-6F5,65511)// %+ from image 2same as abo$e3
my.image"draw- /rawab$ee,ier-right.cubic.be,ier.coord11)// dra' the right(side cur$e
ircles# :lli!ses# Arcs
To draw arcs# full circles# elli!ses# etc# the Magick++ li"rary !rovides the >rawa"leArc o"*ect'
>rawa"leArc%dou"le 6Qto!Qleft# yQto!Qleft# 6Q"ottomQright# yQ"ottomQright# startQangle#
endQangle&J
The way the arcs are drawn on the canvas can "e understood via the following algorithm'
first a virtual %i.e. invisi"le& rectangle is drawn according to the 6QF and yQF !arameters
ne6t a full virtual %i.e. invisi"le& elli!se is drawn inside the rectangle descri"ed a"ove
finally# the actual visi"le !ortion %i.e. the arc& is effectively drawn on the canvas over the
virtual eli!se# in reverse/trigonometric direction# using angle-"ased start and end !ositionsJ
the startQangle and endQangle are "oth measured from the center of the ellipse in reverse/
trigonometric direction.
/rawab$eKrc**/rawab$eKrc-doub$e x.top.$eft, doub$e y.top.$eft,
doub$e x.bottom.right, doub$e y.bottom.right,
start.ang$e, end.ang$e1)
// :xamples
// dra' a bottom(half or a circle at the top left of the can$as 2top(left image belo'3:
my.image"draw-/rawab$eKrc-5, -455, 655, 455, 5, 4B511)
// dra' a right(half or a circle at the top left of the can$as 2bottom(right image belo'3:
my.image"draw-/rawab$eKrc--455, 5, 455, 655, 6N5, O511)
Te6t
,lacing a te6t on a canvas ca "e made using two "asic methods' drawing the te6t inside a canvas#
or annotating a full image
/sing the )mage <draw%&< method'
0hen using the <)mage''draw%&< method for drawing te6t an an image canvas# a <>rawa"leTe6t<
o"*ect must "e created and used in con*unction with the draw%& method. The <>rawa"leTe6t o"*ect
contains "oth the information regarding the characters that are to "e @!rintedA on the canvas# and
the !recise !osition on the canvas where the te6t must "e !laced.
-ote' The !osition s!ecified for drawing re!resents the "ottom-left corner of the imaginary
"o6 that surrounds the te6t
/rawab$eText**/rawab$eText-doub$e x, doub$e y, const string3 text.to.write1
// :xample:
Image my.image- 2eometry-865,6651, Co$or-CwhiteC11)
$ist%/rawab$e( text.draw.$ist)
// set the text font: the font is specified $ia a string representing
// a full! #ualified < font name 2'ildcards ')' are allo'ed3
text.draw.$ist"push.bac!-
/rawab$eFont-C-misc-fixed-medium-o-semicondensedS48-E-E-E-c-A5-isoBBFO-4C11)
// set the text to be dra'n at specified position: x"E0E, !"A0 this case
text.draw.$ist"push.bac!- /rawab$eText-454, F5, Ctext to write on the canvasC11)
// set the text color 2the fill color must be set to transparent3
text.draw.$ist"push.bac!- /rawab$eStro!eCo$or-Co$or-Cb$ac!C111)
text.draw.$ist"push.bac!- /rawab$eFi$$Co$or-Co$or-5, 5, 5, &ax@2111)
// dra' the "text to 'rite on the can$as" string on the can$as 'ith the abo$e settings
my.image"draw- text.draw.$ist1)
// ;ote: the red mar&ing point in belo' image is located at position 2E00,A03
Annotating an image using the )mage <annotate%&< method
The <)mage''annotate%&< method allows !lacing te6t inside an image<s canvas "y only s!ecifying
the !osition relative to the image center at which the te6t will "e !laced# with said !osition "eing
s!ecified via BgravityB %which is a !arameter of ty!e .ravityTy!e&
Image**annotate-const string3 annotation, 2ravityType position1
// :xample:
Image my.image- 2eometry-865,6651, Co$or-CwhiteC11)
// set the text rendering font 2the color is determined b! the "current" image setting3
my.image"font-C-E-bitstream charter-medium-r-norma$-E-E-E-E-E-E-E-isoBBFO-4C1)
// dra' text 'ith different gra$it! position
my.image"annotate-CDorthJest gravity annotationC, DorthJest2ravity1)
my.image"annotate-CSouthHast gravity annotationC, SouthHast2ravity1)
my.image"annotate-CCenter gravity annotationC, Center2ravity1)
&ote9 as it can be seen in the image above the Magick++
library apparently has some bugs when annotating at the
bottom if the image
! +lobal image operations
$*erlaying images
Magick++ su!!orts image overlaying via the )mage o"*ect<s <Image99composite01< method. This
method !laces an <imageQtoQoverlay< over a given <su!!ortQimage<'
support.image"composite-image.to.over$ay, parameters1
The composition method
This !arameter is of ty!e om!osite+!erator %which is im!lemented as an enum&.
The following list !resents a selection of essential com!osition methods'
The )nom!osite+! is the default value for the om!osite+!erator %i.e. when the
om!osite+!erator is omitted&# and it instructs the following com!osition algorithm'
$irst# the <su!!ortQimage< is com!letely cleared and its canvas is made trans!arent
-e6t# the <imageQtoQoverlay< is !laced over the <su!!ortQimage< canvas at a
s!ecified !osition. As a result# the <su!!ortQimage< canvas will only contain exactly
the <imageQtoQoverlay< surrounded by transparent area on the <su!!ortQimage<
canvas
The +verom!osite+! value s!ecifies that the resulting com!osition image contains the
original <su!!ortQimage< over which the <imageQtoQoverlay< is blended according the
individual <imageQtoQoverlay< and <su!!ortQimage< !i6els< trans!arency %i.e. Al!ha
values&.
The +utom!osite+! value determines a com!osition algorithm that sim!ly cuts out an
area from the <su!!ortQimage< and leaves that area com!letely trans!arentJ the si(e
and sha!e of the cut-out area are determined "y the <imageQtoQoverlay<
The positioning of the image to "e overlayed with res!ect to the su!!ort image.
This !ositioning information can "e !assed to the <com!osite%&< method in two ways'
the +ffset with res!ect to the su!!ort image system of coordinates
the .ravity with res!ect to the su!!ort image
// .omposite?perator belo' can be: 7n.omposite?p, ?$er.omposite?p, ?ut.omposite?p
Image**composite-const Image3 image.to.over$ay, int x, int y, CompositeRperator method1
Image**composite-const Image3 image.to.over$ay, 2ravityType pos, CompositeRperator method1
// :xample
// 0se the '?$er' method to place image4to4o$erla! o$er support4image at position 2E0,E03
support.image"composite-image.to.over$ay, 45, 45, RverCompositeRp1)
5,tract a 6sub7image6 1rom another image
Magick++ su!!orts the e6traction of a Bsu"-imageB from another image via two )mage methods'
<cho!%&< and *cro!%&<.
Image**chop-2eometry-doub$e x, doub$e y11) // see detai$s be$ow
Image**crop-2eometry-doub$e x, doub$e y11) // see detai$s be$ow
9oth cho!%& and cro!%& methods resi7e the image canvas that they operate on "y kee!ing only a
certain region of the original# and sim!ly discarding the rest. The region that will "e retained is
s!ecific to each method.
9oth <cho!%&< and <cro!%&< methods take only one argument which is of ty!e <.eometry<
-ote' because these methods modify the original image ob.ect for which they are invoked
they should be used on a copy of the original image in order to preserve the original image
The cho!%& method
2et us consider an image <myQimage< with .eometry%originalQsi(eQ6# originalQsi(eQy&# and let us
assume a call is made to myQimage.cho!% .eometry%6# y&&. )n this case# after the chop01 operation
myAimage has changed as follows'
the top/left corner %i.e. the 0#0 !oint& is the !oint %6#y& of the original image
the new si(e of myQimage is %originalQsi(eQ6-6# originalQsi(eQy-y&
Thus# the image si(e after a <cho!%&< o!eration is reduced to %originalQsi(eQ6-6# originalQsi(eQy-y&#
and the %0#0& !oint of the cho!!ed image corres!onds to the %6#y& !oint of the original image'
The cro!%& method
let us consider an image myQimage with .eometry%originalQsi(eQ6# originalQsi(eQy&# and let us
assume a call is made to myQimage.cro!% .eometry%6# y&&. )n this case# after the crop01 operation
myAimage has changed as follows'
the bottom/right corner is "e the !oint %6#y& of the original image
the new si(e of myQimage is %6#y&
Thus# the image si(e after a <cro!%&< o!eration is reduced to %6#y&# and the %0#0& !oint of the
cro!!ed image corres!onds to the %0#0& !oint of the original image'
:6tracting a region from within an image
The following e6am!le illustrates a way of com"ining image copying chopping and cropping# for
e6tracting a Bsu"-imageB of si(e %I00#I00& from a source image# starting with the !osition
%100#100& in the source image %i.e. the resulting image will be a copy of the region 008BB8BB1
0)BB)BB11 from the original image&'
// let us assume a source4image from 'source4image8gif' file that has +00x+00 resolution
Image source.image-Csource.image"gifC1)
// to a$oid altering the source4image, ma&e a cop! of it and operate on the cop!
Image sub.image-source.image1)
// chop the sub4image: after chop23, the sub4image 'ill contain the
// 2E00, E00, +00, +003 area from source4image 2chopped image3
sub.image"chop-2eometry-455,45511)
// crop the sub4image: after crop23, the sub4image 'ill contain the
// 2E00, E00, I00, I003 area from source4image 2chopped and cropped image3
sub.image"crop-2eometry-655,65511) // after this point in the code, 'sub4image'
// contains the desired area from 'source4image'
copy of original image image after chopping image after chopping and cropping
+lobal image modi1ications
Resi(ing an image
Magick++ !rovides the )mage''(oom%& method for image resi(ing. This method resi(es the image
with a given !ositive <(oomQfactor< value' if BC7oomAfactorO1# the image will (oom out %i.e. it will
"e shrunk&J if 7oomAfactorP1# the image will (oom in %i.e. it will "e magnified&.
-ote' After a (oom o!eration# the image will have the same si(eQ6'si(eQy ratio as "efore the
o!eration.
Image**,oom-const 2eometry3 new.geometry1)
// :xample:
// start 'ith an image of *00xI00 pixels 2si-e4x:si-e4! ratio is F:E3
// the image 'ill first be magnified in b! a factor of F, and then shrun& b! a factor
// of F 2thus regaining its original dimensions3
doub$e si,e.x > A55, si,e.y > 855, ,oom.in.factor > 6, ,oom.out.factor > 5"F)
Image my.image- 2eometry-si,e.x,si,e.y1, Co$or-CwhiteC11)
// -oom in 'm!4image' 'ith the '-oom4in4factor'
// after -oom in, the ne' 'm!4image' si-e 'ill be : EF00x*00
my.image",oom- 2eometry-si,e.xE,oom.in.factor, si,e.yE,oom.in.factor11)
// -oom out 'm!4image' 'ith the '-oom4out4factor'
// after -oom out, the ne' 'm!4image' si-e 'ill be brought bac& to *00xI00
my.image",oom- 2eometry-si,e.xE,oom.out.factor, si,e.yE,oom.out.factor11)
Rotating an image
The <)mage''rotate%&< method rotates an entire image with a given angle. The image canvas is
enlarged if this is re=uired for containing the rotated imageJ however# the image canvas is never
shrunk# even if the rotated image could fit in a smaller canvas than the original.
)f the image canvas after a rotation is larger than the original# the areas that do not corres!ond to
the rotated original image are filled with fully/opa6ue white in the current Magick++ version.
Image**rotate-doub$e ang$e1) // the angle is specified in counter(trigonometric degrees
// :xample
Image my.image-2eometry-655,6551, Co$or-7Cyan:11) // H#uare image: .!an bac&ground
;code to draw a ye$$ow box= // image E
my.image"rotate-9F1) // image F
my.image"rotate-9F1) // image I
-ote'
the dashed lines surrounding the above images are not part of the images themselvesJ
they have "een manually added only to show the image "oundaries as the image is rotated
olor modifications on an image# or an image area
The method for changing the glo"al coloring of an image# or of a !ortion of the image# is to create
a !i6el cache for the desired region and then se=uentially alter the individual com!onents for each
of the !i6els %<red<# <green<# <"lue<# and <o!acity<&. At the end of the !rocess the image will have to
"e u!date via the !i6el "uffer<s <,i6el''sync%&< method %see the also <!i6el cache< section a"ove&.
-ote' these o!erations can also "e !erformed directly on the image# "ut they will "e less
efficient than using a !i6el cache if the num"er of !i6els involved is relatively large %the
actual efficiency im!rovement when using a !i6el cache heavily de!ends on the Magick++
im!lementation&
9lurring an image
To a!!ly a "lur effect to an entire image canvas# Magick++ !rovides the .aussian distri"ution-
"ased <)mage''"lur%&< method. The "lur filter acts on each !i6el of the canvas# setting its value to a
weighted average of its surrounding !i6els within a given radius.
Image**b$ur-const doub$e radius, const doub$e sigma1) // 'radius' defines the region
// around the pixel that is a$eraged
// 'sigma' represents the 'a! the
// surrounding pixels are 'eighted
// the images belo' present the blur effect 'hen using $arious $alues for radius and sigma
// the first image is the base image on 'hich the blur filter 'ill be applied
// the follo'ing code 'ill generate the effect seen in the other images
my.image"b$ur-6, 5"F1)
6 8rie1ly displaying an image
)t is sometimes necessary %es!ecially during an a!!lication<s develo!ment !hase& to "riefly check
the results of the image !rocessing algorithms that are "eing im!lemented. $or this !ur!ose# the
Magick++ li"rary !rovides the <)mage''dis!lay%&< method which !o!s u! a window containing the
image on the dis!lay# and halts !rogram e6ecution until the window is manually closed.
)M,+RTA-T' the image may be altered when it is displayed via <)mage''dis!lay%&<J in order
to !revent such situations always use a copy of the image intended for visuali(ationS
Image**disp$ay-1) //displa! a pop(up 'indo' containing the image6 @J7H MLM L1@:R @J: 7MLG:
//example: displa! an image $ia a temporar! cop! in order to pre$ent altering the original
Image temp.image-my.image1) temp.image"disp$ay-1) // displa! 'm!4image' in a pop(up 'indo'
9 )oding style
The Magick++ documentation has two im!ortant recommendations with res!ect to the coding
style to "e used when develo!ing an a!!lication# and they refer to how the various Magick++
o"*ects should "e created and what general coding rules should "e followed.
5,ceptions
0henever a Magick++ o!eration fails# an e6ce!tion is automatically thrown. There are two
im!ortant "ase classes of e6ce!tions in Magick++# and "oth are derived from the standard ++
e6ce!tion class' <Magick'':rror< and <Magick''0arning<.
.enerally# an :rror is thrown when a Magick++ o!eration failed in a way that would affect future
o!erations in an un!redicta"le way# while a 0arning generally allows the continuation of
!rocessing. $urthermore# each of :rror and 0arning are themselves "ase classes for a more
detailed e6ce!tion class tree that can accurately !in!oint the !ro"lem that has occurred.
// coding st!le example for using the Magic&// exceptions
try ;
my.image"read-my.image.fi$e1) // tr! to read an image from a file
=
catch -Hrror3 my.error1 ;
// because ':rror' is deri$ed from the standard .// exception, it has a ''hat23' method
std**cout %% 7a &agic!'' error occurred* : %% my.error"what-1 %% std**end$)
=
catch - """ 1 ;
std**cout %% 7an unhand$ed error has occurred) exiting app$ication": %% std**end$)
exit-41)
=
-ote' two important types of errors that might "e correcta"le "y user intervention during
the e6ecution of an a!!lication are <:rror$ile+!en< which signals that an attem!t to o!en a
file has failed# and <:rrororru!t)mage< which s!ecifies that an image file is corru!tJ also# an
im!ortant system error is <:rrorResource2imit< which signals that a system resource has
"een e6hausted %e.g. the system has run out of memory&.
$or a detailed list of Magick++ :rror and 0arning ty!es see the Magick++ documentation.
Variables
)t is recommended to use automatic varia"les when instantiating Magick++ o"*ects and lists of
o"*ects %as o!!osed to creating the o"*ects on the hea! via the <new< o!erator&. This
recommendation is intended to increase the ro"ustness of the a!!lication "y making use of the
++ automatic @stack unrollingA mechanism which !ro!erly destroys the o"*ects declared within a
code "lock when e6ecution leaves that code "lock %including when an e6ce!tion occurs&.
: 0urther reading
The )mageMagick !ro*ect home !age is located at )mageMagick.org
The Magick++ li"rary home !age is located at )mageMagick.org4Magick++
The Magick++ reference is located at )mageMagick.org4Magick++4>ocumentation.html

You might also like