Possible bug in MagickDistortImage

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
Post Reply
el_supremo
Posts: 1015
Joined: 2005-03-21T21:16:57-07:00

Possible bug in MagickDistortImage

Post by el_supremo »

I've been playing with affine transformations (which will eventually end up in my MagickWand examples) and the program below rotates the logo: image clockwise by 90 degrees and requests that the distorted result be retained (otherwise the result is a white image). The logo: image is 640x480 but the final image is 481x641. Is this just a result of round-off or some other unavoidable feature of the affine transformation, or is it a bug in the way the bestfit is made?
The program first puts a black pixel in each corner of logo: so that you can see that in the final image the top row and right edge have each been extended by one pixel to produce the extension from the expected 480x630 to 481x641.

Pete

Code: Select all

#include <windows.h>
#include <wand/magick_wand.h>
#define _USE_MATH_DEFINES
#include <math.h>
#define DegreesToRadians(a) (a*M_PI/180.)

// Set the affine array to rotate image by 'degrees' clockwise
double *set_rotate_affine(double r[],double degrees)
{
	r[0] = cos(DegreesToRadians(fmod(degrees,360.0)));
	r[1] = sin(DegreesToRadians(fmod(degrees,360.0)));
	r[2] = -sin(DegreesToRadians(fmod(degrees,360.0)));
	r[3] = cos(DegreesToRadians(fmod(degrees,360.0)));
	r[4] = 0;
	r[5] = 0;
	return(r);
}
void test_wand(void) {
{
	double r[6];
	DrawingWand *dw = NULL;
	PixelWand *pw = NULL;
	MagickWand *mw = NULL;

	MagickWandGenesis();
	mw=NewMagickWand();
	MagickReadImage(mw,"logo:");

	// Put a black pixel in each of the corners
	pw = NewPixelWand();
	dw = NewDrawingWand();
	PixelSetColor(pw,"black");
	DrawSetFillColor(dw,pw);
	DrawPoint(dw,0,0);
	DrawPoint(dw,0,479);
	DrawPoint(dw,639,479);
	DrawPoint(dw,639,0);
	MagickDrawImage(mw,dw);

	// Do the affine rotation
	MagickDistortImage(mw,AffineProjectionDistortion,
							6,set_rotate_affine(r,90),MagickTrue);
							
	// Output as GIF - avoid JPG artifacts
	MagickWriteImage(mw,"logo_affine_4.gif");
	if(mw)mw = DestroyMagickWand(mw);
	if(dw)dw = DestroyDrawingWand(dw);
	if(pw)pw = DestroyPixelWand(pw);
	MagickWandTerminus();
}
Sorry, my ISP shutdown all personal webspace so my MagickWand Examples in C is offline.
See my message in this topic for a link to a zip of all the files.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Possible bug in MagickDistortImage

Post by anthony »

With MagickTrue flag the distort is equivelent to +distort.

this can result in the image being enlarged slightly to ensure that semi-tranparent edge pixels are captured by the distort process.

Essentually the distort function tries to forward map the corners (or other parts) of the image into distorted space to try to figure out how big the destination image should and with what offset on the virtual canvas. These calculated locations are floating point, and yet the virtual canvas is only specified in intergers (image size and offset (may be a negative offset!). The virtual canvas size itself is best fited to this, though really it is non-sensical without further input from the user (say due to multiple layers and a -layers merge)

The float to interger rounding is not perfect, and can result in a 1 or 2 pixel size difference, and a posible -1 offset difference.

Basicaly it depends on just how well the forward map is handled.

Note the distortion itself is a reverse mapping, and sometimes a forward mapping is not available! For example in Shepards Distortions or Barrel Distortions.

Note setting MagickTrue (using MagickFalse) so as to use the original image size and offset as the viewport, OR supplying a distort:viewport setting will override this calculation.

Basically I have tries to make distort as 'virtual canvas friendly' as I can. You are welcome to check the code, or make suggestions. In fact I welcome any programmer input. Work commitments are keeping me too busy for much coding time.

Just look at 'magick/distort.c'
A view from other programmers would be very helpful at this point.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply