Powered by Pair ImageMagick logo
Image Magick
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages

ImageMagick-6.1.1/Magick++/lib/Image.cpp

Go to the documentation of this file.
00001 // This may look like C code, but it is really -*- C++ -*- 00002 // 00003 // Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003 00004 // 00005 // Implementation of Image 00006 // 00007 00008 #define MAGICK_IMPLEMENTATION 1 00009 00010 #include "Magick++/Include.h" 00011 #include <string> 00012 #include <string.h> 00013 #include <errno.h> 00014 #include <math.h> 00015 00016 using namespace std; 00017 00018 #include "Magick++/Image.h" 00019 #include "Magick++/Functions.h" 00020 #include "Magick++/Pixels.h" 00021 #include "Magick++/Options.h" 00022 #include "Magick++/ImageRef.h" 00023 00024 #define AbsoluteValue(x) ((x) < 0 ? -(x) : (x)) 00025 00026 MagickDLLDeclExtern const char *Magick::borderGeometryDefault = "6x6+0+0"; 00027 MagickDLLDeclExtern const char *Magick::frameGeometryDefault = "25x25+6+6"; 00028 MagickDLLDeclExtern const char *Magick::raiseGeometryDefault = "6x6+0+0"; 00029 00030 static bool magick_initialized=false; 00031 00032 // 00033 // Explicit template instantiations 00034 // 00035 00036 // 00037 // Friend functions to compare Image objects 00038 // 00039 00040 MagickDLLDecl int Magick::operator == ( const Magick::Image& left_, 00041 const Magick::Image& right_ ) 00042 { 00043 // If image pixels and signature are the same, then the image is identical 00044 return ( ( left_.rows() == right_.rows() ) && 00045 ( left_.columns() == right_.columns() ) && 00046 ( left_.signature() == right_.signature() ) 00047 ); 00048 } 00049 MagickDLLDecl int Magick::operator != ( const Magick::Image& left_, 00050 const Magick::Image& right_ ) 00051 { 00052 return ( ! (left_ == right_) ); 00053 } 00054 MagickDLLDecl int Magick::operator > ( const Magick::Image& left_, 00055 const Magick::Image& right_ ) 00056 { 00057 return ( !( left_ < right_ ) && ( left_ != right_ ) ); 00058 } 00059 MagickDLLDecl int Magick::operator < ( const Magick::Image& left_, 00060 const Magick::Image& right_ ) 00061 { 00062 // If image pixels are less, then image is smaller 00063 return ( ( left_.rows() * left_.columns() ) < 00064 ( right_.rows() * right_.columns() ) 00065 ); 00066 } 00067 MagickDLLDecl int Magick::operator >= ( const Magick::Image& left_, 00068 const Magick::Image& right_ ) 00069 { 00070 return ( ( left_ > right_ ) || ( left_ == right_ ) ); 00071 } 00072 MagickDLLDecl int Magick::operator <= ( const Magick::Image& left_, 00073 const Magick::Image& right_ ) 00074 { 00075 return ( ( left_ < right_ ) || ( left_ == right_ ) ); 00076 } 00077 00078 // 00079 // Image object implementation 00080 // 00081 00082 // Construct from image file or image specification 00083 Magick::Image::Image( const std::string &imageSpec_ ) 00084 : _imgRef(new ImageRef) 00085 { 00086 try 00087 { 00088 // Initialize, Allocate and Read images 00089 read( imageSpec_ ); 00090 } 00091 catch ( const Warning & /*warning_*/ ) 00092 { 00093 // FIXME: need a way to report warnings in constructor 00094 } 00095 catch ( const Error & /*error_*/ ) 00096 { 00097 // Release resources 00098 delete _imgRef; 00099 throw; 00100 } 00101 } 00102 00103 // Construct a blank image canvas of specified size and color 00104 Magick::Image::Image( const Geometry &size_, 00105 const Color &color_ ) 00106 : _imgRef(new ImageRef) 00107 { 00108 // xc: prefix specifies an X11 color string 00109 std::string imageSpec("xc:"); 00110 imageSpec += color_; 00111 00112 try 00113 { 00114 // Set image size 00115 size( size_ ); 00116 00117 // Initialize, Allocate and Read images 00118 read( imageSpec ); 00119 } 00120 catch ( const Warning & /*warning_*/ ) 00121 { 00122 // FIXME: need a way to report warnings in constructor 00123 } 00124 catch ( const Error & /*error_*/ ) 00125 { 00126 // Release resources 00127 delete _imgRef; 00128 throw; 00129 } 00130 } 00131 00132 // Construct Image from in-memory BLOB 00133 Magick::Image::Image ( const Blob &blob_ ) 00134 : _imgRef(new ImageRef) 00135 { 00136 try 00137 { 00138 // Initialize, Allocate and Read images 00139 read( blob_ ); 00140 } 00141 catch ( const Warning & /*warning_*/ ) 00142 { 00143 // FIXME: need a way to report warnings in constructor 00144 } 00145 catch ( const Error & /*error_*/ ) 00146 { 00147 // Release resources 00148 delete _imgRef; 00149 throw; 00150 } 00151 } 00152 00153 // Construct Image of specified size from in-memory BLOB 00154 Magick::Image::Image ( const Blob &blob_, 00155 const Geometry &size_ ) 00156 : _imgRef(new ImageRef) 00157 { 00158 try 00159 { 00160 // Read from Blob 00161 read( blob_, size_ ); 00162 } 00163 catch ( const Warning & /*warning_*/ ) 00164 { 00165 // FIXME: need a way to report warnings in constructor 00166 } 00167 catch ( const Error & /*error_*/ ) 00168 { 00169 // Release resources 00170 delete _imgRef; 00171 throw; 00172 } 00173 } 00174 00175 // Construct Image of specified size and depth from in-memory BLOB 00176 Magick::Image::Image ( const Blob &blob_, 00177 const Geometry &size_, 00178 const unsigned int depth_ ) 00179 : _imgRef(new ImageRef) 00180 { 00181 try 00182 { 00183 // Read from Blob 00184 read( blob_, size_, depth_ ); 00185 } 00186 catch ( const Warning & /*warning_*/ ) 00187 { 00188 // FIXME: need a way to report warnings in constructor 00189 } 00190 catch ( const Error & /*error_*/ ) 00191 { 00192 // Release resources 00193 delete _imgRef; 00194 throw; 00195 } 00196 } 00197 00198 // Construct Image of specified size, depth, and format from in-memory BLOB 00199 Magick::Image::Image ( const Blob &blob_, 00200 const Geometry &size_, 00201 const unsigned int depth_, 00202 const std::string &magick_ ) 00203 : _imgRef(new ImageRef) 00204 { 00205 try 00206 { 00207 // Read from Blob 00208 read( blob_, size_, depth_, magick_ ); 00209 } 00210 catch ( const Warning & /*warning_*/ ) 00211 { 00212 // FIXME: need a way to report warnings in constructor 00213 } 00214 catch ( const Error & /*error_*/ ) 00215 { 00216 // Release resources 00217 delete _imgRef; 00218 throw; 00219 } 00220 } 00221 00222 // Construct Image of specified size, and format from in-memory BLOB 00223 Magick::Image::Image ( const Blob &blob_, 00224 const Geometry &size_, 00225 const std::string &magick_ ) 00226 : _imgRef(new ImageRef) 00227 { 00228 try 00229 { 00230 // Read from Blob 00231 read( blob_, size_, magick_ ); 00232 } 00233 catch ( const Warning & /*warning_*/ ) 00234 { 00235 // FIXME: need a way to report warnings in constructor 00236 } 00237 catch ( const Error & /*error_*/ ) 00238 { 00239 // Release resources 00240 delete _imgRef; 00241 throw; 00242 } 00243 } 00244 00245 // Construct an image based on an array of raw pixels, of specified 00246 // type and mapping, in memory 00247 Magick::Image::Image ( const unsigned int width_, 00248 const unsigned int height_, 00249 const std::string &map_, 00250 const StorageType type_, 00251 const void *pixels_ ) 00252 : _imgRef(new ImageRef) 00253 { 00254 try 00255 { 00256 read( width_, height_, map_.c_str(), type_, pixels_ ); 00257 } 00258 catch ( const Warning & /*warning_*/ ) 00259 { 00260 // FIXME: need a way to report warnings in constructor 00261 } 00262 catch ( const Error & /*error_*/ ) 00263 { 00264 // Release resources 00265 delete _imgRef; 00266 throw; 00267 } 00268 } 00269 00270 // Default constructor 00271 Magick::Image::Image( void ) 00272 : _imgRef(new ImageRef) 00273 { 00274 } 00275 00276 // Destructor 00277 /* virtual */ 00278 Magick::Image::~Image() 00279 { 00280 bool doDelete = false; 00281 { 00282 Lock( &_imgRef->_mutexLock ); 00283 if ( --_imgRef->_refCount == 0 ) 00284 doDelete = true; 00285 } 00286 00287 if ( doDelete ) 00288 { 00289 delete _imgRef; 00290 } 00291 _imgRef = 0; 00292 } 00293 00294 // Local adaptive threshold image 00295 // http://www.dai.ed.ac.uk/HIPR2/adpthrsh.htm 00296 // Width x height define the size of the pixel neighborhood 00297 // offset = constant to subtract from pixel neighborhood mean 00298 void Magick::Image::adaptiveThreshold ( const unsigned int width_, 00299 const unsigned int height_, 00300 const unsigned int offset_ ) 00301 { 00302 ExceptionInfo exceptionInfo; 00303 GetExceptionInfo( &exceptionInfo ); 00304 MagickLib::Image* newImage = 00305 AdaptiveThresholdImage( constImage(), width_, height_, offset_, &exceptionInfo ); 00306 replaceImage( newImage ); 00307 throwException( exceptionInfo ); 00308 } 00309 00310 // Add noise to image 00311 void Magick::Image::addNoise( const NoiseType noiseType_ ) 00312 { 00313 ExceptionInfo exceptionInfo; 00314 GetExceptionInfo( &exceptionInfo ); 00315 MagickLib::Image* newImage = 00316 AddNoiseImage ( image(), 00317 noiseType_, 00318 &exceptionInfo ); 00319 replaceImage( newImage ); 00320 throwException( exceptionInfo ); 00321 } 00322 00323 // Affine Transform image 00324 void Magick::Image::affineTransform ( const DrawableAffine &affine_ ) 00325 { 00326 ExceptionInfo exceptionInfo; 00327 GetExceptionInfo( &exceptionInfo ); 00328 00329 AffineMatrix _affine; 00330 _affine.sx = affine_.sx(); 00331 _affine.sy = affine_.sy(); 00332 _affine.rx = affine_.rx(); 00333 _affine.ry = affine_.ry(); 00334 _affine.tx = affine_.tx(); 00335 _affine.ty = affine_.ty(); 00336 00337 MagickLib::Image* newImage = 00338 AffineTransformImage( image(), &_affine, &exceptionInfo); 00339 replaceImage( newImage ); 00340 throwException( exceptionInfo ); 00341 } 00342 00343 // Annotate using specified text, and placement location 00344 void Magick::Image::annotate ( const std::string &text_, 00345 const Geometry &location_ ) 00346 { 00347 annotate ( text_, location_, NorthWestGravity, 0.0 ); 00348 } 00349 // Annotate using specified text, bounding area, and placement gravity 00350 void Magick::Image::annotate ( const std::string &text_, 00351 const Geometry &boundingArea_, 00352 const GravityType gravity_ ) 00353 { 00354 annotate ( text_, boundingArea_, gravity_, 0.0 ); 00355 } 00356 // Annotate with text using specified text, bounding area, placement 00357 // gravity, and rotation. 00358 void Magick::Image::annotate ( const std::string &text_, 00359 const Geometry &boundingArea_, 00360 const GravityType gravity_, 00361 const double degrees_ ) 00362 { 00363 modifyImage(); 00364 00365 DrawInfo *drawInfo 00366 = options()->drawInfo(); 00367 00368 drawInfo->text = const_cast<char *>(text_.c_str()); 00369 00370 char boundingArea[MaxTextExtent]; 00371 00372 drawInfo->geometry = 0; 00373 if ( boundingArea_.isValid() ){ 00374 if ( boundingArea_.width() == 0 || boundingArea_.height() == 0 ) 00375 { 00376 FormatString( boundingArea, "+%u+%u", 00377 boundingArea_.xOff(), boundingArea_.yOff() ); 00378 } 00379 else 00380 { 00381 strcpy( boundingArea, string(boundingArea_).c_str()); 00382 } 00383 drawInfo->geometry = boundingArea; 00384 } 00385 00386 drawInfo->gravity = gravity_; 00387 00388 AffineMatrix oaffine = drawInfo->affine; 00389 if ( degrees_ != 0.0) 00390 { 00391 AffineMatrix affine; 00392 affine.sx=1.0; 00393 affine.rx=0.0; 00394 affine.ry=0.0; 00395 affine.sy=1.0; 00396 affine.tx=0.0; 00397 affine.ty=0.0; 00398 00399 AffineMatrix current = drawInfo->affine; 00400 affine.sx=cos(DegreesToRadians(fmod(degrees_,360.0))); 00401 affine.rx=sin(DegreesToRadians(fmod(degrees_,360.0))); 00402 affine.ry=(-sin(DegreesToRadians(fmod(degrees_,360.0)))); 00403 affine.sy=cos(DegreesToRadians(fmod(degrees_,360.0))); 00404 00405 drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx; 00406 drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx; 00407 drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy; 00408 drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy; 00409 drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty 00410 +current.tx; 00411 } 00412 00413 AnnotateImage( image(), drawInfo ); 00414 00415 // Restore original values 00416 drawInfo->affine = oaffine; 00417 drawInfo->text = 0; 00418 drawInfo->geometry = 0; 00419 00420 throwImageException(); 00421 } 00422 // Annotate with text (bounding area is entire image) and placement gravity. 00423 void Magick::Image::annotate ( const std::string &text_, 00424 const GravityType gravity_ ) 00425 { 00426 modifyImage(); 00427 00428 DrawInfo *drawInfo 00429 = options()->drawInfo(); 00430 00431 drawInfo->text = const_cast<char *>(text_.c_str()); 00432 00433 drawInfo->gravity = gravity_; 00434 00435 AnnotateImage( image(), drawInfo ); 00436 00437 drawInfo->gravity = NorthWestGravity; 00438 drawInfo->text = 0; 00439 00440 throwImageException(); 00441 } 00442 00443 // Blur image 00444 void Magick::Image::blur( const double radius_, const double sigma_ ) 00445 { 00446 ExceptionInfo exceptionInfo; 00447 GetExceptionInfo( &exceptionInfo ); 00448 MagickLib::Image* newImage = 00449 BlurImage( image(), radius_, sigma_, &exceptionInfo); 00450 replaceImage( newImage ); 00451 throwException( exceptionInfo ); 00452 } 00453 00454 // Add border to image 00455 // Only uses width & height 00456 void Magick::Image::border( const Geometry &geometry_ ) 00457 { 00458 RectangleInfo borderInfo = geometry_; 00459 ExceptionInfo exceptionInfo; 00460 GetExceptionInfo( &exceptionInfo ); 00461 MagickLib::Image* newImage = 00462 BorderImage( image(), &borderInfo, &exceptionInfo); 00463 replaceImage( newImage ); 00464 throwException( exceptionInfo ); 00465 } 00466 00467 // Extract channel from image 00468 void Magick::Image::channel ( const ChannelType channel_ ) 00469 { 00470 modifyImage(); 00471 ChannelImage ( image(), channel_ ); 00472 throwImageException(); 00473 } 00474 00475 // Set or obtain modulus channel depth 00476 void Magick::Image::channelDepth ( const ChannelType channel_, 00477 const unsigned int depth_) 00478 { 00479 modifyImage(); 00480 SetImageChannelDepth( image(), channel_, depth_); 00481 throwImageException(); 00482 } 00483 unsigned int Magick::Image::channelDepth ( const ChannelType channel_ ) 00484 { 00485 unsigned int channel_depth; 00486 00487 ExceptionInfo exceptionInfo; 00488 GetExceptionInfo( &exceptionInfo ); 00489 channel_depth=GetImageChannelDepth( constImage(), channel_, 00490 &exceptionInfo ); 00491 throwException( exceptionInfo ); 00492 return channel_depth; 00493 } 00494 00495 00496 // Charcoal-effect image 00497 void Magick::Image::charcoal( const double radius_, const double sigma_ ) 00498 { 00499 ExceptionInfo exceptionInfo; 00500 GetExceptionInfo( &exceptionInfo ); 00501 MagickLib::Image* newImage = 00502 CharcoalImage( image(), radius_, sigma_, &exceptionInfo ); 00503 replaceImage( newImage ); 00504 throwException( exceptionInfo ); 00505 } 00506 00507 // Chop image 00508 void Magick::Image::chop( const Geometry &geometry_ ) 00509 { 00510 RectangleInfo chopInfo = geometry_; 00511 ExceptionInfo exceptionInfo; 00512 GetExceptionInfo( &exceptionInfo ); 00513 MagickLib::Image* newImage = 00514 ChopImage( image(), &chopInfo, &exceptionInfo); 00515 replaceImage( newImage ); 00516 throwException( exceptionInfo ); 00517 } 00518 00519 // Colorize 00520 void Magick::Image::colorize ( const unsigned int opacityRed_, 00521 const unsigned int opacityGreen_, 00522 const unsigned int opacityBlue_, 00523 const Color &penColor_ ) 00524 { 00525 if ( !penColor_.isValid() ) 00526 { 00527 throwExceptionExplicit( OptionError, 00528 "Pen color argument is invalid"); 00529 } 00530 00531 char opacity[MaxTextExtent]; 00532 FormatString(opacity,"%u/%u/%u",opacityRed_,opacityGreen_,opacityBlue_); 00533 00534 ExceptionInfo exceptionInfo; 00535 GetExceptionInfo( &exceptionInfo ); 00536 MagickLib::Image* newImage = 00537 ColorizeImage ( image(), opacity, 00538 penColor_, &exceptionInfo ); 00539 replaceImage( newImage ); 00540 throwException( exceptionInfo ); 00541 } 00542 void Magick::Image::colorize ( const unsigned int opacity_, 00543 const Color &penColor_ ) 00544 { 00545 colorize( opacity_, opacity_, opacity_, penColor_ ); 00546 } 00547 00548 // Compare current image with another image 00549 // Sets meanErrorPerPixel, normalizedMaxError, and normalizedMeanError 00550 // in the current image. False is returned if the images are identical. 00551 bool Magick::Image::compare ( const Image &reference_ ) 00552 { 00553 modifyImage(); 00554 Image ref = reference_; 00555 ref.modifyImage(); 00556 return static_cast<bool>(IsImagesEqual(image(), ref.image())); 00557 } 00558 00559 // Composite two images 00560 void Magick::Image::composite ( const Image &compositeImage_, 00561 const int xOffset_, 00562 const int yOffset_, 00563 const CompositeOperator compose_ ) 00564 { 00565 // Image supplied as compositeImage is composited with current image and 00566 // results in updating current image. 00567 modifyImage(); 00568 00569 CompositeImage( image(), 00570 compose_, 00571 compositeImage_.constImage(), 00572 xOffset_, 00573 yOffset_ ); 00574 throwImageException(); 00575 } 00576 void Magick::Image::composite ( const Image &compositeImage_, 00577 const Geometry &offset_, 00578 const CompositeOperator compose_ ) 00579 { 00580 modifyImage(); 00581 00582 long x = offset_.xOff(); 00583 long y = offset_.yOff(); 00584 unsigned long width = columns(); 00585 unsigned long height = rows(); 00586 00587 GetMagickGeometry (static_cast<std::string>(offset_).c_str(), 00588 &x, &y, 00589 &width, &height ); 00590 00591 CompositeImage( image(), 00592 compose_, 00593 compositeImage_.constImage(), 00594 x, y ); 00595 throwImageException(); 00596 } 00597 void Magick::Image::composite ( const Image &compositeImage_, 00598 const GravityType gravity_, 00599 const CompositeOperator compose_ ) 00600 { 00601 modifyImage(); 00602 00603 long x = 0; 00604 long y = 0; 00605 00606 switch (gravity_) 00607 { 00608 case NorthWestGravity: 00609 { 00610 x = 0; 00611 y = 0; 00612 break; 00613 } 00614 case NorthGravity: 00615 { 00616 x = (columns() - compositeImage_.columns()) >> 1; 00617 y = 0; 00618 break; 00619 } 00620 case NorthEastGravity: 00621 { 00622 x = static_cast<long>(columns() - compositeImage_.columns()); 00623 y = 0; 00624 break; 00625 } 00626 case WestGravity: 00627 { 00628 x = 0; 00629 y = (rows() - compositeImage_.rows()) >> 1; 00630 break; 00631 } 00632 case ForgetGravity: 00633 case StaticGravity: 00634 case CenterGravity: 00635 default: 00636 { 00637 x = (columns() - compositeImage_.columns()) >> 1; 00638 y = (rows() - compositeImage_.rows()) >> 1; 00639 break; 00640 } 00641 case EastGravity: 00642 { 00643 x = static_cast<long>(columns() - compositeImage_.columns()); 00644 y = (rows() - compositeImage_.rows()) >> 1; 00645 break; 00646 } 00647 case SouthWestGravity: 00648 { 00649 x = 0; 00650 y = static_cast<long>(rows() - compositeImage_.rows()); 00651 break; 00652 } 00653 case SouthGravity: 00654 { 00655 x = (columns() - compositeImage_.columns()) >> 1; 00656 y = static_cast<long>(rows() - compositeImage_.rows()); 00657 break; 00658 } 00659 case SouthEastGravity: 00660 { 00661 x = static_cast<long>(columns() - compositeImage_.columns()); 00662 y = static_cast<long>(rows() - compositeImage_.rows()); 00663 break; 00664 } 00665 } 00666 00667 CompositeImage( image(), 00668 compose_, 00669 compositeImage_.constImage(), 00670 x, y ); 00671 throwImageException(); 00672 } 00673 00674 // Contrast image 00675 void Magick::Image::contrast ( const unsigned int sharpen_ ) 00676 { 00677 modifyImage(); 00678 ContrastImage ( image(), (MagickBooleanType) sharpen_ ); 00679 throwImageException(); 00680 } 00681 00682 // Convolve image. Applies a general image convolution kernel to the image. 00683 // order_ represents the number of columns and rows in the filter kernel. 00684 // kernel_ is an array of doubles representing the convolution kernel. 00685 void Magick::Image::convolve ( const unsigned int order_, 00686 const double *kernel_ ) 00687 { 00688 ExceptionInfo exceptionInfo; 00689 GetExceptionInfo( &exceptionInfo ); 00690 MagickLib::Image* newImage = 00691 ConvolveImage ( image(), order_, 00692 kernel_, &exceptionInfo ); 00693 replaceImage( newImage ); 00694 throwException( exceptionInfo ); 00695 } 00696 00697 // Crop image 00698 void Magick::Image::crop ( const Geometry &geometry_ ) 00699 { 00700 RectangleInfo cropInfo = geometry_; 00701 ExceptionInfo exceptionInfo; 00702 GetExceptionInfo( &exceptionInfo ); 00703 MagickLib::Image* newImage = 00704 CropImage( image(), 00705 &cropInfo, 00706 &exceptionInfo); 00707 replaceImage( newImage ); 00708 throwException( exceptionInfo ); 00709 } 00710 00711 // Cycle Color Map 00712 void Magick::Image::cycleColormap ( const int amount_ ) 00713 { 00714 modifyImage(); 00715 CycleColormapImage( image(), amount_ ); 00716 throwImageException(); 00717 } 00718 00719 // Despeckle 00720 void Magick::Image::despeckle ( void ) 00721 { 00722 ExceptionInfo exceptionInfo; 00723 GetExceptionInfo( &exceptionInfo ); 00724 MagickLib::Image* newImage = 00725 DespeckleImage( image(), &exceptionInfo ); 00726 replaceImage( newImage ); 00727 throwException( exceptionInfo ); 00728 } 00729 00730 // Display image 00731 void Magick::Image::display( void ) 00732 { 00733 DisplayImages( imageInfo(), image() ); 00734 } 00735 00736 // Draw on image using single drawable 00737 void Magick::Image::draw ( const Magick::Drawable &drawable_ ) 00738 { 00739 modifyImage(); 00740 00741 DrawingWand *wand = DrawAllocateWand( options()->drawInfo(), image()); 00742 00743 if(wand) 00744 { 00745 drawable_.operator()(wand); 00746 00747 if( constImage()->exception.severity == UndefinedException) 00748 DrawRender(wand); 00749 00750 wand=DestroyDrawingWand(wand); 00751 } 00752 00753 throwImageException(); 00754 } 00755 00756 // Draw on image using a drawable list 00757 void Magick::Image::draw ( const std::list<Magick::Drawable> &drawable_ ) 00758 { 00759 modifyImage(); 00760 00761 DrawingWand *wand = DrawAllocateWand( options()->drawInfo(), image()); 00762 00763 if(wand) 00764 { 00765 for( std::list<Magick::Drawable>::const_iterator p = drawable_.begin(); 00766 p != drawable_.end(); p++ ) 00767 { 00768 p->operator()(wand); 00769 if( constImage()->exception.severity != UndefinedException) 00770 break; 00771 } 00772 00773 if( constImage()->exception.severity == UndefinedException) 00774 DrawRender(wand); 00775 00776 wand=DestroyDrawingWand(wand); 00777 } 00778 00779 throwImageException(); 00780 } 00781 00782 // Hilight edges in image 00783 void Magick::Image::edge ( const double radius_ ) 00784 { 00785 ExceptionInfo exceptionInfo; 00786 GetExceptionInfo( &exceptionInfo ); 00787 MagickLib::Image* newImage = 00788 EdgeImage( image(), radius_, &exceptionInfo ); 00789 replaceImage( newImage ); 00790 throwException( exceptionInfo ); 00791 } 00792 00793 // Emboss image (hilight edges) 00794 void Magick::Image::emboss ( const double radius_, const double sigma_ ) 00795 { 00796 ExceptionInfo exceptionInfo; 00797 GetExceptionInfo( &exceptionInfo ); 00798 MagickLib::Image* newImage = 00799 EmbossImage( image(), radius_, sigma_, &exceptionInfo ); 00800 replaceImage( newImage ); 00801 throwException( exceptionInfo ); 00802 } 00803 00804 // Enhance image (minimize noise) 00805 void Magick::Image::enhance ( void ) 00806 { 00807 ExceptionInfo exceptionInfo; 00808 GetExceptionInfo( &exceptionInfo ); 00809 MagickLib::Image* newImage = 00810 EnhanceImage( image(), &exceptionInfo ); 00811 replaceImage( newImage ); 00812 throwException( exceptionInfo ); 00813 } 00814 00815 // Equalize image (histogram equalization) 00816 void Magick::Image::equalize ( void ) 00817 { 00818 modifyImage(); 00819 EqualizeImage( image() ); 00820 throwImageException(); 00821 } 00822 00823 // Erase image to current "background color" 00824 void Magick::Image::erase ( void ) 00825 { 00826 modifyImage(); 00827 SetImage( image(), OpaqueOpacity ); 00828 throwImageException(); 00829 } 00830 00831 // Flip image (reflect each scanline in the vertical direction) 00832 void Magick::Image::flip ( void ) 00833 { 00834 ExceptionInfo exceptionInfo; 00835 GetExceptionInfo( &exceptionInfo ); 00836 MagickLib::Image* newImage = 00837 FlipImage( image(), &exceptionInfo ); 00838 replaceImage( newImage ); 00839 throwException( exceptionInfo ); 00840 } 00841 00842 // Flood-fill color across pixels that match the color of the 00843 // target pixel and are neighbors of the target pixel. 00844 // Uses current fuzz setting when determining color match. 00845 void Magick::Image::floodFillColor( const unsigned int x_, 00846 const unsigned int y_, 00847 const Magick::Color &fillColor_ ) 00848 { 00849 floodFillTexture( x_, y_, Image( Geometry( 1, 1), fillColor_ ) ); 00850 } 00851 void Magick::Image::floodFillColor( const Geometry &point_, 00852 const Magick::Color &fillColor_ ) 00853 { 00854 floodFillTexture( point_, Image( Geometry( 1, 1), fillColor_) ); 00855 } 00856 00857 // Flood-fill color across pixels starting at target-pixel and 00858 // stopping at pixels matching specified border color. 00859 // Uses current fuzz setting when determining color match. 00860 void Magick::Image::floodFillColor( const unsigned int x_, 00861 const unsigned int y_, 00862 const Magick::Color &fillColor_, 00863 const Magick::Color &borderColor_ ) 00864 { 00865 floodFillTexture( x_, y_, Image( Geometry( 1, 1), fillColor_), 00866 borderColor_ ); 00867 } 00868 void Magick::Image::floodFillColor( const Geometry &point_, 00869 const Magick::Color &fillColor_, 00870 const Magick::Color &borderColor_ ) 00871 { 00872 floodFillTexture( point_, Image( Geometry( 1, 1), fillColor_), 00873 borderColor_ ); 00874 } 00875 00876 // Floodfill pixels matching color (within fuzz factor) of target 00877 // pixel(x,y) with replacement opacity value using method. 00878 void Magick::Image::floodFillOpacity( const unsigned int x_, 00879 const unsigned int y_, 00880 const unsigned int opacity_, 00881 const PaintMethod method_ ) 00882 { 00883 modifyImage(); 00884 MatteFloodfillImage ( image(), 00885 static_cast<PixelPacket>(pixelColor(x_,y_)), 00886 opacity_, 00887 static_cast<long>(x_), static_cast<long>(y_), 00888 method_ ); 00889 throwImageException(); 00890 } 00891 00892 // Flood-fill texture across pixels that match the color of the 00893 // target pixel and are neighbors of the target pixel. 00894 // Uses current fuzz setting when determining color match. 00895 void Magick::Image::floodFillTexture( const unsigned int x_, 00896 const unsigned int y_, 00897 const Magick::Image &texture_ ) 00898 { 00899 modifyImage(); 00900 00901 // Set drawing pattern 00902 options()->fillPattern(texture_.constImage()); 00903 00904 // Get pixel view 00905 Pixels pixels(*this); 00906 // Fill image 00907 PixelPacket *target = pixels.get(x_, y_, 1, 1 ); 00908 if (target) 00909 ColorFloodfillImage ( image(), // Image *image 00910 options()->drawInfo(), // const DrawInfo *draw_info 00911 *target, // const PixelPacket target 00912 static_cast<long>(x_), // const long x_offset 00913 static_cast<long>(y_), // const long y_offset 00914 FloodfillMethod // const PaintMethod method 00915 ); 00916 00917 throwImageException(); 00918 } 00919 void Magick::Image::floodFillTexture( const Magick::Geometry &point_, 00920 const Magick::Image &texture_ ) 00921 { 00922 floodFillTexture( point_.xOff(), point_.yOff(), texture_ ); 00923 } 00924 00925 // Flood-fill texture across pixels starting at target-pixel and 00926 // stopping at pixels matching specified border color. 00927 // Uses current fuzz setting when determining color match. 00928 void Magick::Image::floodFillTexture( const unsigned int x_, 00929 const unsigned int y_, 00930 const Magick::Image &texture_, 00931 const Magick::Color &borderColor_ ) 00932 { 00933 modifyImage(); 00934 00935 // Set drawing fill pattern 00936 options()->fillPattern(texture_.constImage()); 00937 00938 ColorFloodfillImage ( image(), 00939 options()->drawInfo(), 00940 static_cast<PixelPacket>(borderColor_), 00941 static_cast<long>(x_), 00942 static_cast<long>(y_), 00943 FillToBorderMethod 00944 ); 00945 00946 throwImageException(); 00947 } 00948 void Magick::Image::floodFillTexture( const Magick::Geometry &point_, 00949 const Magick::Image &texture_, 00950 const Magick::Color &borderColor_ ) 00951 { 00952 floodFillTexture( point_.xOff(), point_.yOff(), texture_, borderColor_ ); 00953 } 00954 00955 // Flop image (reflect each scanline in the horizontal direction) 00956 void Magick::Image::flop ( void ) 00957 { 00958 ExceptionInfo exceptionInfo; 00959 GetExceptionInfo( &exceptionInfo ); 00960 MagickLib::Image* newImage = 00961 FlopImage( image(), &exceptionInfo ); 00962 replaceImage( newImage ); 00963 throwException( exceptionInfo ); 00964 } 00965 00966 // Frame image 00967 void Magick::Image::frame ( const Geometry &geometry_ ) 00968 { 00969 FrameInfo info; 00970 00971 info.x = static_cast<long>(geometry_.width()); 00972 info.y = static_cast<long>(geometry_.height()); 00973 info.width = columns() + ( static_cast<unsigned long>(info.x) << 1 ); 00974 info.height = rows() + ( static_cast<unsigned long>(info.y) << 1 ); 00975 info.outer_bevel = geometry_.xOff(); 00976 info.inner_bevel = geometry_.yOff(); 00977 00978 ExceptionInfo exceptionInfo; 00979 GetExceptionInfo( &exceptionInfo ); 00980 MagickLib::Image* newImage = 00981 FrameImage( image(), &info, &exceptionInfo ); 00982 replaceImage( newImage ); 00983 throwException( exceptionInfo ); 00984 } 00985 void Magick::Image::frame ( const unsigned int width_, 00986 const unsigned int height_, 00987 const int innerBevel_, const int outerBevel_ ) 00988 { 00989 FrameInfo info; 00990 info.x = static_cast<long>(width_); 00991 info.y = static_cast<long>(height_); 00992 info.width = columns() + ( static_cast<unsigned long>(info.x) << 1 ); 00993 info.height = rows() + ( static_cast<unsigned long>(info.y) << 1 ); 00994 info.outer_bevel = static_cast<long>(outerBevel_); 00995 info.inner_bevel = static_cast<long>(innerBevel_); 00996 00997 ExceptionInfo exceptionInfo; 00998 GetExceptionInfo( &exceptionInfo ); 00999 MagickLib::Image* newImage = 01000 FrameImage( image(), &info, &exceptionInfo ); 01001 replaceImage( newImage ); 01002 throwException( exceptionInfo ); 01003 } 01004 01005 // Gamma correct image 01006 void Magick::Image::gamma ( const double gamma_ ) 01007 { 01008 char gamma[MaxTextExtent + 1]; 01009 FormatString( gamma, "%3.6f", gamma_); 01010 01011 modifyImage(); 01012 GammaImage ( image(), gamma ); 01013 } 01014 void Magick::Image::gamma ( const double gammaRed_, 01015 const double gammaGreen_, 01016 const double gammaBlue_ ) 01017 { 01018 char gamma[MaxTextExtent + 1]; 01019 FormatString( gamma, "%3.6f/%3.6f/%3.6f/", 01020 gammaRed_, gammaGreen_, gammaBlue_); 01021 01022 modifyImage(); 01023 GammaImage ( image(), gamma ); 01024 throwImageException(); 01025 } 01026 01027 // Gaussian blur image 01028 // The number of neighbor pixels to be included in the convolution 01029 // mask is specified by 'width_'. The standard deviation of the 01030 // gaussian bell curve is specified by 'sigma_'. 01031 void Magick::Image::gaussianBlur ( const double width_, const double sigma_ ) 01032 { 01033 ExceptionInfo exceptionInfo; 01034 GetExceptionInfo( &exceptionInfo ); 01035 MagickLib::Image* newImage = 01036 GaussianBlurImage( image(), width_, sigma_, &exceptionInfo ); 01037 replaceImage( newImage ); 01038 throwException( exceptionInfo ); 01039 } 01040 01041 // Implode image 01042 void Magick::Image::implode ( const double factor_ ) 01043 { 01044 ExceptionInfo exceptionInfo; 01045 GetExceptionInfo( &exceptionInfo ); 01046 MagickLib::Image* newImage = 01047 ImplodeImage( image(), factor_, &exceptionInfo ); 01048 replaceImage( newImage ); 01049 throwException( exceptionInfo ); 01050 } 01051 01052 // Magnify image by integral size 01053 void Magick::Image::magnify ( void ) 01054 { 01055 ExceptionInfo exceptionInfo; 01056 GetExceptionInfo( &exceptionInfo ); 01057 MagickLib::Image* newImage = 01058 MagnifyImage( image(), &exceptionInfo ); 01059 replaceImage( newImage ); 01060 throwException( exceptionInfo ); 01061 } 01062 01063 // Remap image colors with closest color from reference image 01064 void Magick::Image::map ( const Image &mapImage_ , const bool dither_ ) 01065 { 01066 modifyImage(); 01067 MapImage ( image(), 01068 mapImage_.constImage(), 01069 dither_ == true ? MagickTrue : MagickFalse ); 01070 throwImageException(); 01071 } 01072 // Floodfill designated area with replacement opacity value 01073 void Magick::Image::matteFloodfill ( const Color &target_ , 01074 const unsigned int opacity_, 01075 const int x_, const int y_, 01076 const Magick::PaintMethod method_ ) 01077 { 01078 modifyImage(); 01079 MatteFloodfillImage ( image(), static_cast<PixelPacket>(target_), 01080 opacity_, x_, y_, method_ ); 01081 throwImageException(); 01082 } 01083 01084 // Filter image by replacing each pixel component with the median 01085 // color in a circular neighborhood 01086 void Magick::Image::medianFilter ( const double radius_ ) 01087 { 01088 ExceptionInfo exceptionInfo; 01089 GetExceptionInfo( &exceptionInfo ); 01090 MagickLib::Image* newImage = 01091 MedianFilterImage ( image(), radius_, &exceptionInfo ); 01092 replaceImage( newImage ); 01093 throwException( exceptionInfo ); 01094 } 01095 01096 // Reduce image by integral size 01097 void Magick::Image::minify ( void ) 01098 { 01099 ExceptionInfo exceptionInfo; 01100 GetExceptionInfo( &exceptionInfo ); 01101 MagickLib::Image* newImage = 01102 MinifyImage( image(), &exceptionInfo ); 01103 replaceImage( newImage ); 01104 throwException( exceptionInfo ); 01105 } 01106 01107 // Modulate percent hue, saturation, and brightness of an image 01108 void Magick::Image::modulate ( const double brightness_, 01109 const double saturation_, 01110 const double hue_ ) 01111 { 01112 char modulate[MaxTextExtent + 1]; 01113 FormatString( modulate, "%3.6f/%3.6f/%3.6f", 01114 brightness_, saturation_, hue_); 01115 01116 modifyImage(); 01117 ModulateImage( image(), modulate ); 01118 throwImageException(); 01119 } 01120 01121 // Negate image. Set grayscale_ to true to effect grayscale values 01122 // only 01123 void Magick::Image::negate ( const bool grayscale_ ) 01124 { 01125 modifyImage(); 01126 NegateImage ( image(), grayscale_ == true ? MagickTrue : MagickFalse ); 01127 throwImageException(); 01128 } 01129 01130 // Normalize image 01131 void Magick::Image::normalize ( void ) 01132 { 01133 modifyImage(); 01134 NormalizeImage ( image() ); 01135 throwImageException(); 01136 } 01137 01138 // Oilpaint image 01139 void Magick::Image::oilPaint ( const double radius_ ) 01140 { 01141 ExceptionInfo exceptionInfo; 01142 GetExceptionInfo( &exceptionInfo ); 01143 MagickLib::Image* newImage = 01144 OilPaintImage( image(), radius_, &exceptionInfo ); 01145 replaceImage( newImage ); 01146 throwException( exceptionInfo ); 01147 } 01148 01149 // Set or attenuate the opacity channel. If the image pixels are 01150 // opaque then they are set to the specified opacity value, otherwise 01151 // they are blended with the supplied opacity value. The value of 01152 // opacity_ ranges from 0 (completely opaque) to MaxRGB. The defines 01153 // OpaqueOpacity and TransparentOpacity are available to specify 01154 // completely opaque or completely transparent, respectively. 01155 void Magick::Image::opacity ( const unsigned int opacity_ ) 01156 { 01157 modifyImage(); 01158 SetImageOpacity( image(), opacity_ ); 01159 } 01160 01161 // Change the color of an opaque pixel to the pen color. 01162 void Magick::Image::opaque ( const Color &opaqueColor_, 01163 const Color &penColor_ ) 01164 { 01165 if ( !opaqueColor_.isValid() ) 01166 { 01167 throwExceptionExplicit( OptionError, 01168 "Opaque color argument is invalid" ); 01169 } 01170 if ( !penColor_.isValid() ) 01171 { 01172 throwExceptionExplicit( OptionError, 01173 "Pen color argument is invalid" ); 01174 } 01175 01176 modifyImage(); 01177 OpaqueImage ( image(), opaqueColor_, penColor_ ); 01178 throwImageException(); 01179 } 01180 01181 // Ping is similar to read except only enough of the image is read to 01182 // determine the image columns, rows, and filesize. Access the 01183 // columns(), rows(), and fileSize() attributes after invoking ping. 01184 // The image data is not valid after calling ping. 01185 void Magick::Image::ping ( const std::string &imageSpec_ ) 01186 { 01187 options()->fileName( imageSpec_ ); 01188 ExceptionInfo exceptionInfo; 01189 GetExceptionInfo( &exceptionInfo ); 01190 MagickLib::Image* image = 01191 PingImage( imageInfo(), &exceptionInfo ); 01192 replaceImage( image ); 01193 throwException( exceptionInfo ); 01194 } 01195 01196 // Ping is similar to read except only enough of the image is read 01197 // to determine the image columns, rows, and filesize. Access the 01198 // columns(), rows(), and fileSize() attributes after invoking 01199 // ping. The image data is not valid after calling ping. 01200 void Magick::Image::ping ( const Blob& blob_ ) 01201 { 01202 ExceptionInfo exceptionInfo; 01203 GetExceptionInfo( &exceptionInfo ); 01204 MagickLib::Image* image = 01205 PingBlob( imageInfo(), blob_.data(), blob_.length(), &exceptionInfo ); 01206 replaceImage( image ); 01207 throwException( exceptionInfo ); 01208 } 01209 01210 // Execute a named process module using an argc/argv syntax similar to 01211 // that accepted by a C 'main' routine. An exception is thrown if the 01212 // requested process module doesn't exist, fails to load, or fails during 01213 // execution. 01214 void Magick::Image::process( std::string name_, const int argc, char **argv ) 01215 { 01216 modifyImage(); 01217 01218 unsigned int status = 01219 ExecuteModuleProcess( name_.c_str(), &image(), argc, argv ); 01220 01221 if (status == false) 01222 throwException( image()->exception ); 01223 } 01224 01225 // Quantize colors in image using current quantization settings 01226 // Set measureError_ to true in order to measure quantization error 01227 void Magick::Image::quantize ( const bool measureError_ ) 01228 { 01229 modifyImage(); 01230 01231 QuantizeImage( options()->quantizeInfo(), 01232 image() ); 01233 01234 if ( measureError_ ) 01235 GetImageQuantizeError( image() ); 01236 01237 // Udate DirectClass representation of pixels 01238 SyncImage( image() ); 01239 throwImageException(); 01240 } 01241 01242 // Apply an arithmetic or bitwise operator to the image pixel quantums. 01243 void Magick::Image::quantumOperator ( const ChannelType channel_, 01244 const MagickEvaluateOperator operator_, 01245 Quantum rvalue_) 01246 { 01247 ExceptionInfo exceptionInfo; 01248 GetExceptionInfo( &exceptionInfo ); 01249 EvaluateImageChannel( image(), channel_, operator_, rvalue_, &exceptionInfo); 01250 throwException( exceptionInfo ); 01251 } 01252 void Magick::Image::quantumOperator ( const int x_,const int y_, 01253 const unsigned int columns_, 01254 const unsigned int rows_, 01255 const ChannelType channel_, 01256 const MagickEvaluateOperator operator_, 01257 const Quantum rvalue_) 01258 { 01259 ExceptionInfo exceptionInfo; 01260 GetExceptionInfo( &exceptionInfo ); 01261 EvaluateImageChannel( image(), channel_, operator_, rvalue_, &exceptionInfo); 01262 throwException( exceptionInfo ); 01263 } 01264 01265 // Raise image (lighten or darken the edges of an image to give a 3-D 01266 // raised or lowered effect) 01267 void Magick::Image::raise ( const Geometry &geometry_ , 01268 const bool raisedFlag_ ) 01269 { 01270 RectangleInfo raiseInfo = geometry_; 01271 modifyImage(); 01272 RaiseImage ( image(), &raiseInfo, raisedFlag_ == true ? MagickTrue : MagickFalse ); 01273 throwImageException(); 01274 } 01275 01276 // Read image into current object 01277 void Magick::Image::read ( const std::string &imageSpec_ ) 01278 { 01279 options()->fileName( imageSpec_ ); 01280 01281 ExceptionInfo exceptionInfo; 01282 GetExceptionInfo( &exceptionInfo ); 01283 MagickLib::Image* image = 01284 ReadImage( imageInfo(), &exceptionInfo ); 01285 01286 // Ensure that multiple image frames were not read. 01287 if ( image && image->next ) 01288 { 01289 // Destroy any extra image frames 01290 MagickLib::Image* next = image->next; 01291 image->next = 0; 01292 next->previous = 0; 01293 DestroyImageList( next ); 01294 01295 } 01296 replaceImage( image ); 01297 throwException( exceptionInfo ); 01298 if ( image ) 01299 throwException( image->exception ); 01300 } 01301 01302 // Read image of specified size into current object 01303 void Magick::Image::read ( const Geometry &size_, 01304 const std::string &imageSpec_ ) 01305 { 01306 size( size_ ); 01307 read( imageSpec_ ); 01308 } 01309 01310 // Read image from in-memory BLOB 01311 void Magick::Image::read ( const Blob &blob_ ) 01312 { 01313 ExceptionInfo exceptionInfo; 01314 GetExceptionInfo( &exceptionInfo ); 01315 MagickLib::Image* image = 01316 BlobToImage( imageInfo(), 01317 static_cast<const void *>(blob_.data()), 01318 blob_.length(), &exceptionInfo ); 01319 replaceImage( image ); 01320 throwException( exceptionInfo ); 01321 if ( image ) 01322 throwException( image->exception ); 01323 } 01324 01325 // Read image of specified size from in-memory BLOB 01326 void Magick::Image::read ( const Blob &blob_, 01327 const