1 module dmagick.c.distort; 2 3 import dmagick.c.exception; 4 import dmagick.c.geometry; 5 import dmagick.c.image; 6 import dmagick.c.magickType; 7 import dmagick.c.magickVersion; 8 9 extern(C) 10 { 11 version(D_Ddoc) 12 { 13 /** 14 * The distortion method to use when distorting an image. 15 */ 16 enum DistortImageMethod 17 { 18 /** */ 19 UndefinedDistortion, 20 21 /** 22 * Distort the image linearly by moving a list of at least 3 or 23 * more sets of control points (as defined below). Ideally 3 sets 24 * or 12 floating point values are given allowing the image to 25 * be linearly scaled, rotated, sheared, and translated, according 26 * to those three points. See also the related AffineProjection 27 * and ScaleRotateTranslateDistortion distortions. 28 * 29 * More than 3 sets given control point pairs (12 numbers) is least 30 * squares fitted to best match a lineary affine distortion. If only 31 * 2 control point pairs (8 numbers) are given a two point image 32 * translation rotation and scaling is performed, without any possible 33 * shearing, flipping or changes in aspect ratio to the resulting image. 34 * If only one control point pair is provides the image is only 35 * translated, (which may be a floating point non-integer translation). 36 * 37 * This distortion does not include any form of perspective distortion. 38 */ 39 AffineDistortion, 40 41 /** 42 * Linearly distort an image using the given Affine Matrix of 6 pre-calculated 43 * coefficients forming a set of Affine Equations to map the source 44 * image to the destination image. 45 * 46 * Sx,Rx,Ry,Sy,Tx,Ty 47 */ 48 AffineProjectionDistortion, 49 50 /** 51 * Distort image by first scaling and rotating about a given 52 * 'center', before translating that 'center' to the new location, 53 * in that order. It is an alternative method of specifying a 54 * 'Affine' type of distortion, but without shearing effects. It 55 * also provides a good way of rotating and displacing a smaller 56 * image for tiling onto a larger background (IE 2-dimensional 57 * animations). 58 * 59 * The number of arguments determine the specific meaning of each 60 * argument for the scales, rotation, and translation operations. 61 * $(TABLE 62 * $(HEADERS #, arguments meaning ) 63 * $(ROW 1:, $(COMMA Angle_of_Rotation )) 64 * $(ROW 2:, $(COMMA Scale Angle )) 65 * $(ROW 3:, $(COMMA X,Y Angle )) 66 * $(ROW 4:, $(COMMA X,Y Scale Angle )) 67 * $(ROW 5:, $(COMMA X,Y ScaleX,ScaleY Angle )) 68 * $(ROW 6:, $(COMMA X,Y Scale Angle NewX,NewY )) 69 * $(ROW 7:, $(COMMA X,Y ScaleX,ScaleY Angle NewX,NewY )) 70 * ) 71 * 72 * This is actually an alternative way of specifying a 2 dimensional 73 * linear 'Affine' or 'AffineProjection' distortion. 74 */ 75 ScaleRotateTranslateDistortion, 76 77 /** 78 * Perspective distort the images, using a list of 4 or more sets of 79 * control points (as defined below). More that 4 sets (16 numbers) of 80 * control points provide least squares fitting for more accurate 81 * distortions (for the purposes of image registration and panarama 82 * effects). Less than 4 sets will fall back to a 'Affine' linear distortion. 83 * 84 * Perspective Distorted images ensures that straight lines remain straight, 85 * but the scale of the distorted image will vary. The horizon is 86 * anti-aliased, and the 'sky' color may be set using the -mattecolor setting. 87 */ 88 PerspectiveDistortion, 89 90 /** 91 * Do a Perspective distortion biased on a set of 8 pre-calculated coefficients. 92 * If the last two perspective scaling coefficients are zero, the remaining 93 * 6 represents a transposed 'Affine Matrix'. 94 */ 95 PerspectiveProjectionDistortion, 96 97 /** 98 * Bilinear Distortion, given a minimum of 4 sets of coordinate pairs, 99 * or 16 values (see below). Not that lines may not appear straight 100 * after distortion, though the distance between coordinates will 101 * remain consistent. 102 * 103 * The BilinearForward is used to map rectangles to any quadrilateral, 104 * while the BilinearReverse form maps any quadrilateral to a rectangle, 105 * while preserving the straigth line edges in each case. 106 * 107 * Note that BilinearForward can generate invalid pixels which will be 108 * colored using the -mattecolor color setting. Also if the quadraterial 109 * becomes 'flipped' the image may dissappear. 110 * 111 * There are future plans to produce a true Bilinear distortion that will 112 * attempt to map any quadrilateral to any other quadrilateral, 113 * while preserving edges (and edge distance ratios). 114 */ 115 BilinearForwardDistortion, 116 117 /** 118 * ditto 119 */ 120 BilinearDistortion = BilinearForwardDistortion, 121 122 /** 123 * ditto 124 */ 125 BilinearReverseDistortion, 126 127 /** 128 * 129 */ 130 PolynomialDistortion, 131 132 /** 133 * Arc the image (variation of polar mapping) over the angle given around a circle. 134 * $(TABLE 135 * $(HEADERS Argument, Meaning) 136 * $(ROW arc_angle, The angle over which to arc the image side-to-side) 137 * $(ROW rotate_angle, Angle to rotate resulting image from vertical center) 138 * $(ROW top_radius, Set top edge of source image at this radius) 139 * $(ROW bottom_radius, Set bottom edge to this radius (radial scaling)) 140 * ) 141 * 142 * The resulting image is always resized to best fit the resulting image, while 143 * attempting to preserve scale and aspect ratio of the original image as much 144 * as possible with the arguments given by the user. All four arguments will be 145 * needed to change the overall aspect ratio of an 'Arc'ed image. 146 * 147 * This a variation of a polar distortion designed to try to preserve the aspect 148 * ratio of the image rather than direct Cartesian to Polar conversion. 149 */ 150 ArcDistortion, 151 152 /** 153 * Like ArcDistortion but do a complete Cartesian to Polar mapping of the image. 154 * that is the height of the input image is mapped to the radius limits, while 155 * the width is wrapped around between the angle limits. 156 * 157 * Arguments : Rmax,Rmin CenterX,CenterY, start,end_angle 158 * 159 * All arguments are optional. With Rmin defaulting to zero, the center to the 160 * center of the image, and the angles going from -180 (top) to +180 (top). If 161 * Rmax is given the special value of '0', the the distance from the center to 162 * the nearest edge is used for the radius of the output image, which will ensure 163 * the whole image is visible (though scaled smaller). However a special value of 164 * '-1' will use the distance from the center to the furthest corner, This may 165 * 'clip' the corners from the input rectangular image, but will generate the 166 * exact reverse of a 'DePolar' with the same arguments. 167 */ 168 PolarDistortion, 169 170 /** 171 * Uses the same arguments and meanings as a Polar distortion but generates the 172 * reverse Polar to Cartesian distortion. 173 * 174 * The special Rmax setting of '0' may however clip the corners of the input image. 175 * However using the special Rmax setting of '-1' (maximum center to corner distance) 176 * will ensure the whole distorted image is preserved in the generated result, so that 177 * the same argument to 'Polar' will reverse the distortion re-producing the original. 178 * Note that as this distortion requires the area resampling of a circular arc, which 179 * can not be handled by the builtin EWA resampling function. As such the normal EWA 180 * filters are turned off. It is recommended some form of 'super-sampling' image 181 * processing technique be used to produce a high quality result. 182 */ 183 DePolarDistortion, 184 185 /** */ 186 Cylinder2PlaneDistortion, 187 188 /** */ 189 Plane2CylinderDistortion, 190 191 /** 192 * Given the four coefficients (A,B,C,D) as defined by Helmut Dersch, perform a barrell or 193 * pin-cushion distortion appropriate to correct radial lens distortions. That is in 194 * photographs, make straight lines straight again. 195 * 196 * Arguments : A B C [D [X,Y]] $(BR) 197 * or Ax Bx Cx Dx Ay By Cy Dy [X,Y] $(BR) 198 * So that it forms the function $(BR) 199 * Rsrc = r * ( A*r³ + B*r² + C*r + D ) 200 * 201 * Where X,Y is the optional center of the distortion (defaulting to the center of the image). 202 * The second form is typically used to distort images, rather than correct lens distortions. 203 */ 204 BarrelDistortion, 205 206 /** 207 * This is very simular to BarrelDistortion with the same set of arguments, and argument handling. 208 * However it uses the inverse of the radial polynomial, so that it forms the function 209 * 210 * Rsrc = r / ( A*r³ + B*r² + C*r + D ) 211 * 212 * Note that this is not the reverse of the Barrel distortion, 213 * just a different barrel-like radial distortion method. 214 */ 215 BarrelInverseDistortion, 216 217 /** 218 * Distort the given list control points (any number) using an Inverse Squared Distance 219 * Interpolation Method (Shepards Method). The control points in effect do 'localized' 220 * displacement of the image around the given control point (preserving the look and the 221 * rotation of the area near the control points. For best results extra control points 222 * should be added to 'lock' the positions of the corners, edges and other unchanging 223 * parts of the image, to prevent their movement. 224 * 225 * The distortion has been likened to 'taffy pulling' using nails, or pins' stuck in a 226 * block of 'jelly' which is then moved to the new position, distorting te surface of the jelly. 227 */ 228 ShepardsDistortion, 229 230 /** */ 231 ResizeDistortion, 232 233 /* Not a real distortion, ImageMagick uses this to get the amount of Distortions supported */ 234 SentinelDistortion 235 } 236 } 237 else 238 { 239 mixin( 240 { 241 string methods = "enum DistortImageMethod 242 { 243 UndefinedDistortion, 244 AffineDistortion, 245 AffineProjectionDistortion, 246 ScaleRotateTranslateDistortion, 247 PerspectiveDistortion, 248 PerspectiveProjectionDistortion, 249 BilinearForwardDistortion, 250 BilinearDistortion = BilinearForwardDistortion, 251 BilinearReverseDistortion, 252 PolynomialDistortion, 253 ArcDistortion, 254 PolarDistortion, 255 DePolarDistortion,"; 256 257 static if ( MagickLibVersion >= 0x671 ) 258 { 259 methods ~= "Cylinder2PlaneDistortion, 260 Plane2CylinderDistortion,"; 261 } 262 263 methods ~= " 264 BarrelDistortion, 265 BarrelInverseDistortion, 266 ShepardsDistortion,"; 267 268 static if ( MagickLibVersion >= 0x670 ) 269 { 270 methods ~= "ResizeDistortion,"; 271 } 272 273 methods ~= " 274 SentinelDistortion 275 }"; 276 277 return methods; 278 }()); 279 } 280 281 /** 282 * Determines how to fill intervening colors. 283 */ 284 enum SparseColorMethod 285 { 286 /** */ 287 UndefinedColorInterpolate = cast(int)DistortImageMethod.UndefinedDistortion, 288 289 /** 290 * three point triangle of color given 3 points. Giving only 2 points 291 * will form a linear gradient between those points. The gradient 292 * generated extends beyond the triangle created by those 3 points. 293 */ 294 BarycentricColorInterpolate = cast(int)DistortImageMethod.AffineDistortion, 295 296 /** 297 * Like barycentric but for 4 points. Less than 4 points fall back 298 * to barycentric. 299 */ 300 BilinearColorInterpolate = cast(int)DistortImageMethod.BilinearReverseDistortion, 301 302 /** */ 303 PolynomialColorInterpolate = cast(int)DistortImageMethod.PolynomialDistortion, 304 305 /** 306 * Colors points biased on the ratio of inverse distance squared. 307 * Generating spots of color in a sea of the average of colors. 308 */ 309 ShepardsColorInterpolate = cast(int)DistortImageMethod.ShepardsDistortion, 310 311 /** 312 * Simply map each pixel to the to nearest color point given. 313 * The result are polygonal cells of solid color. 314 */ 315 VoronoiColorInterpolate = cast(int)DistortImageMethod.SentinelDistortion, 316 317 /** 318 * Colors points biased on the ratio of inverse distance. 319 * This generates sharper points of color rather than rounded spots 320 * of ShepardsColorInterpolate Generating spots of color in a sea 321 * of the average of colors. 322 */ 323 InverseColorInterpolate 324 } 325 326 Image* AffineTransformImage(const(Image)*, const(AffineMatrix)*, ExceptionInfo*); 327 Image* DistortImage(const(Image)*, const DistortImageMethod, const size_t, const(double)*, MagickBooleanType, ExceptionInfo* exception); 328 329 static if ( MagickLibVersion >= 0x670 ) 330 { 331 Image* DistortResizeImage(const(Image)*, const size_t, const size_t, ExceptionInfo*); 332 } 333 334 Image* RotateImage(const(Image)*, const double, ExceptionInfo*); 335 Image* SparseColorImage(const(Image)*, const ChannelType, const SparseColorMethod, const size_t, const(double)*, ExceptionInfo*); 336 }