distort bug?

IMagick is a native PHP extension to create and modify images using the ImageMagick API. ImageMagick Studio LLC did not write nor does it maintain the IMagick extension, however, IMagick users are welcome to discuss the extension here.
f3k

distort bug?

Post by f3k »

hello folks,

i'm trying to accomplish some perspective distortion, but it doesn't seem to work as i imagine, so i'll post here the example that is supposed to work. it can be reviewed at http://www.imagemagick.org/Usage/distorts/. i'll take the chessboard example. the source image is the following:
Image
the command line transformation:

Code: Select all

  convert checks.png -matte -virtual-pixel transparent \
          -distort Perspective '0,0,0,0  0,90,0,90  90,0,90,25  90,90,90,65' \
          checks_pers.png
and the (theoretical) result:
Image
now, using php and the Imagick extension, i suppose that transforms into the following code:

Code: Select all

<?php
$testImagick = new Imagick("checks.png");
$testImagick->setImageMatteColor(new ImagickPixel("transparent"));
$testImagick->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
$testImagick->distortImage(Imagick::DISTORTION_PERSPECTIVE, array(0,0,0,0,  0,90,0,90,  90,0,90,25,  90,90,90,65), false);
$testImagick->writeImage("checks_distorted.png");
$testImagick->destroy();
?>
unfortunately, this brings me the following result:
Image
which is not what i am looking for. changing the bestfit parameter to true doesn't change the fact that the background stays yellow instead of transparent.

what's weird also: if i run the command line example, what i get is a square filled 100% yellow (checks are gone). i tried several imagemagick versions, including the svn trunk of imagemagick, since i noticed some distortion.c changes recently. for imagick, i always used the cvs version.

any hints would be greatly appreciated.

cheers,

-f3k.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: distort bug?

Post by anthony »

No bug, misuse...

The -mattecolor is used for 'sky' or 'beyond the horizon' color. In -distort terms is it for pixels that have a 'invalid' result according to the distortion mathematics. You don't have any 'sky' on the right hand side of this image.

What you want is to some how set the virtual pixel method. Not I said 'method' not color! Though there is a VP method to use the color set in the -background color setting, for white, black, perfect gray, or transparency, there is a more direct VP setting.

You have not changed the VP method being used, so it defaulted to 'edge' That is the edge of the image is repeated out to infinity. That is the default method as VP has some important effects for convolution, and more specifically 'blur' which pre-date distortions by... well forever in IM terms.

You need to find out how to set the Virtual Pixel Method in IMagick, when you (or someone else does figure it out, post a reply to this thread.

PS: more perspective distortion options are planned using 3 dimensional angles, to make it easier to do image rotations such as this. Fred Wienhaus has figured out the heavy matrix maths formulas needed, and I am trying to implement this into IM distort, so stay tuned.

However that was put on hold due to distortion filter and quality improvments, including more work to speed up infinte tiled horizon views.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
f3k

Re: distort bug?

Post by f3k »

thanks for the fast reply!

I'm not sure if i completely understood your point. with

Code: Select all

$testImagick->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
I do set the virtual pixel method to transparent, don't I? Or are you saying that there should be another method, which sets the virtual pixel method specially for the background?

i played around some more and found out that

Code: Select all

$src = new Imagick("checks.png");
$testImagick = new Imagick();
$testImagick->newImage($src->getImageWidth() + 2, $src->getImageHeight() + 2, new ImagickPixel("transparent"), "png");
$testImagick->compositeImage($src, Imagick::COMPOSITE_OVER, 1, 1);
$testImagick->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
$testImagick->distortImage(Imagick::DISTORTION_PERSPECTIVE, array(0,0,0,0,  0,90,0,90,  90,0,90,25,  90,90,90,65), false);
$testImagick->writeImage("checks_distorted.png");
$testImagick->destroy();
does the job more or less. although a direct apply of distort would be more elegant and less cpu-consuming (i guess). any hints how to accomplish that are greatly appreciated :)

nevertheless, keep up the great work!
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: distort bug?

Post by anthony »

The is another VP method that means 'surround the image with the background color'. I mentioned that as only black, white, gray, and transparent has specific VP methods, if you want another color, say "maroon", then you will need to use the background VP method, OR use transparent and 'flatten' the image onto a background.

The VP method basically defined what IM thinks is surrounding the image proper. You could for example tell it to just surrend the image with an infinite tile of itself!

I am not certian why you composited the original image over a transparent one, if only to set a transparent border. It will not be needed with the give VP method.
I suggest you do either one or the other, both is overkill.

You should be able to just set the VP method an distort the original image directly.

PS: if you set the 'false' flag to 'true' the returned image will be sized to 'bestfit' the distorted image, with appropriate virtual canvas offsets (if wanted).

I am working to improve the current fuzziness of the distorted image.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
f3k

Re: distort bug?

Post by f3k »

hello again,
anthony wrote:The is another VP method that means 'surround the image with the background color'.
another vp method different from setImageVirtualPixelMethod()? any idea which one that could be?
anthony wrote:I mentioned that as only black, white, gray, and transparent has specific VP methods, if you want another color, say "maroon", then you will need to use the background VP method, OR use transparent and 'flatten' the image onto a background.
i'm confused. i DO want to apply transparent, and even if wouldn't, which method should i apply then? and could you explain the "use transparent and flatten" method? use transparent how? flatten how?
anthony wrote: The VP method basically defined what IM thinks is surrounding the image proper. You could for example tell it to just surrend the image with an infinite tile of itself!
supposing that there are two vp methods (the one i am already using, setImageVirtualPixelMethod(), and the "background vp method"), which are you referring to?
anthony wrote: I am not certian why you composited the original image over a transparent one, if only to set a transparent border. It will not be needed with the give VP method.
I suggest you do either one or the other, both is overkill.
well, i thought by creating a "virgin image" with explicit transparent background would resolve the issue stated above. it did, but as you said, it's a little overkill.
anthony wrote: You should be able to just set the VP method an distort the original image directly.
indeed. if someone happens to know how to do that with php's Imagick, that would be great. :)
anthony wrote: PS: if you set the 'false' flag to 'true' the returned image will be sized to 'bestfit' the distorted image, with appropriate virtual canvas offsets (if wanted).

I am working to improve the current fuzziness of the distorted image.
great stuff. will play with it as soon as i get past this issue :)
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: distort bug?

Post by mkoppanen »

I ran into a similar issue and I couldnt find a way to solve this. I tried to copy an example from Anthony's examples (great examples btw) but no luck. I just can't reproduce the results using the API (not from Imagick and not from C code).
Mikko Koppanen
My blog: http://valokuva.org
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: distort bug?

Post by anthony »

f3k wrote:
anthony wrote:The is another VP method that means 'surround the image with the background color'.
another vp method different from setImageVirtualPixelMethod()? any idea which one that could be?
A method in this can means a different setting within that function.
f3k wrote:i'm confused. i DO want to apply transparent, and even if wouldn't, which method should i apply then? and could you explain the "use transparent and flatten" method? use transparent how? flatten how?
The transparent is the VP method (setting) for the distortion. It will leave the areas surrounding the image with a transparent area. This usually forms one image in a number of image layers.

'Flatten' is a standard image operation to then merge that image either onto a transparent or cold background behind all the image. Another layer can also be used to form a background image as well.

All these processes are covered in the command line interface examples.
supposing that there are two vp methods (the one i am already using, setImageVirtualPixelMethod(), and the "background vp method"), which are you referring to?
[/quote]
The one VP method will replace the other. Only one such method (or setting) is in effect at any one time and the one set at the time is what will be used by the distortion operator (or whatever operation requires such a method.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
esm723

Re: distort bug?

Post by esm723 »

Alright, I'm running into this error also. It seems to be a glitch in imagick.

Other people are running into this error also. Please see viewtopic.php?f=18&t=13601&p=46084&hili ... ncy#p46084

Anthony, f3k was writing the correct code to get what he wanted (a distorted checker border with transparency past the horizon) according to the original ImageMagick example.
f3k wrote:hello folks,

i'm trying to accomplish some perspective distortion, but it doesn't seem to work as i imagine, so i'll post here the example that is supposed to work. it can be reviewed at http://www.imagemagick.org/Usage/distorts/. i'll take the chessboard example. the source image is the following:
Image
the command line transformation:

Code: Select all

  convert checks.png -matte -virtual-pixel transparent \
          -distort Perspective '0,0,0,0  0,90,0,90  90,0,90,25  90,90,90,65' \
          checks_pers.png
and the (theoretical) result:
Image
now, using php and the Imagick extension, i suppose that transforms into the following code:

Code: Select all

<?php
$testImagick = new Imagick("checks.png");
$testImagick->setImageMatteColor(new ImagickPixel("transparent"));
$testImagick->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
$testImagick->distortImage(Imagick::DISTORTION_PERSPECTIVE, array(0,0,0,0,  0,90,0,90,  90,0,90,25,  90,90,90,65), false);
$testImagick->writeImage("checks_distorted.png");
$testImagick->destroy();
?>
unfortunately, this brings me the following result:
Image
To do this, he used setImageVirtualPixelMethod to imagick::VIRTUALPIXELMETHOD_TRANSPARENT. However, for some reason, the default (imagick::VIRTUALPIXELMETHOD_EDGE) was still taking effect and extending the edge of the rendered image infinitively to the edge of the image. This is exactly what is happening with the people in the thread I mentioned above.

To look into this further, I checked to see if my $im was taking the new ImageVirtualPixelMethod using the following code:

Code: Select all

<?php
$im = new Imagick();

$im->newPseudoImage(100, 100, "pattern:checkerboard");
$im->setImageFormat('png');
$im->setImageMatte(true);

echo imagick::VIRTUALPIXELMETHOD_TRANSPARENT;      // outputs 8
echo $im->getImageVirtualPixelMethod();  // sets the VP to what I want (8 in theory)
$im->setImageVirtualPixelMethod(imagick::VIRTUALPIXELMETHOD_TRANSPARENT);  // does not output 8.  instead, it outputs 0, or imagick::VIRTUALPIXELMETHOD_UNDEFINED, which I assume points to the default imagick::VIRTUALPIXELMETHOD_EDGE
?>
Sure enough, this proved wrong. The first echo outputs 8, the integer value of the constant imagick::VIRTUALPIXELMETHOD_TRANSPARENT. I then set the VP to imagick::VIRTUALPIXELMETHOD_TRANSPARENT, but the second echo, after the set statement, does not output 8 as it should (or as I assume it should).

So, long story short, the imagick::VIRTUALPIXELMETHOD_TRANSPARENT is not successfully being applied to the $im object. Any ideas?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: distort bug?

Post by fmw42 »

try setting the equivent of -background none and then use the equivalent of -virtual-pixel background
esm723

Re: distort bug?

Post by esm723 »

This is what I tried, but I didn't have any luck. It's a good idea, though. Maybe I made a mistake in my Imagick PHP calls.

Code: Select all

	$im = new Imagick($image);
	$im->setImageMatteColor(new ImagickPixel("transparent"));
	$im->setImageVirtualPixelMethod(imagick::VIRTUALPIXELMETHOD_BACKGROUND);
	$im->setBackgroundColor(new ImagickPixel("transparent"));
	$im->setImageBackgroundColor(new ImagickPixel("transparent"));
So far, the only thing to work is f3k's workaround above where he adds 1px on every side of transparency. Then, even with VIRTUALPIXELMETHOD_EDGE being called, it makes everything transparent right to the edge of the image. This works, but since you are adding 2px to height and width, it's not as precise without further hacking.

Any other ideas?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: distort bug?

Post by fmw42 »

try setting the background color BEFORE the virtual-pixel
esm723

Re: distort bug?

Post by esm723 »

Ah, yes, I guess I should've done that to begin with, but it still doesn't work.... :\

Code: Select all

	$im = new Imagick($image);
   	$im->setImageMatteColor(new ImagickPixel("transparent"));
   	$im->setBackgroundColor(new ImagickPixel("transparent"));
   	$im->setImageBackgroundColor(new ImagickPixel("transparent"));
   	$im->setImageVirtualPixelMethod(imagick::VIRTUALPIXELMETHOD_BACKGROUND);
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: distort bug?

Post by fmw42 »

At this point I am out of ideas. I guess you need to discuss further with iMagick developer. Perhaps he needs to discuss with Anthony, the developer of -distort perspective
el_supremo
Posts: 1015
Joined: 2005-03-21T21:16:57-07:00

Re: distort bug?

Post by el_supremo »

I don't know if this will make any difference (haven't tried it) but you haven't accounted for the -matte in your command which turns the alpha channel on.
I don't know what the equivalent is in IMagick. In C and MagickWand it is

Code: Select all

	MagickSetImageAlphaChannel(mw,SetAlphaChannel);
Pete
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.
esm723

Re: distort bug?

Post by esm723 »

Well, I tried to add the setImageMatte to true, but that didn't do the trick. :(

Code: Select all

	$im = new Imagick($image);
	$im->setImageMatte(true);
	$im->setImageMatteColor(new ImagickPixel("transparent"));
	$im->setBackgroundColor(new ImagickPixel("transparent"));
	$im->setImageBackgroundColor(new ImagickPixel("transparent"));
	$im->setImageVirtualPixelMethod(imagick::VIRTUALPIXELMETHOD_BACKGROUND);
For some reason, it still looks to be dealing with the virtual pixels with VIRTUALPIXELMETHOD_EDGE.
Post Reply