Page 1 of 2
distort bug?
Posted: 2007-10-21T15:32:25-07:00
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:
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:
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:
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.
Re: distort bug?
Posted: 2007-10-21T19:33:41-07:00
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.
Re: distort bug?
Posted: 2007-10-22T01:06:43-07:00
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!
Re: distort bug?
Posted: 2007-10-22T06:59:32-07:00
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.
Re: distort bug?
Posted: 2007-10-22T07:48:03-07:00
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
Re: distort bug?
Posted: 2007-10-23T00:47:06-07:00
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).
Re: distort bug?
Posted: 2007-10-23T02:46:10-07:00
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.
Re: distort bug?
Posted: 2010-06-08T12:40:07-07:00
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:
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:
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:
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?
Re: distort bug?
Posted: 2010-06-08T13:56:35-07:00
by fmw42
try setting the equivent of -background none and then use the equivalent of -virtual-pixel background
Re: distort bug?
Posted: 2010-06-08T15:20:52-07:00
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?
Re: distort bug?
Posted: 2010-06-08T16:18:35-07:00
by fmw42
try setting the background color BEFORE the virtual-pixel
Re: distort bug?
Posted: 2010-06-08T18:15:03-07:00
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);
Re: distort bug?
Posted: 2010-06-08T18:20:51-07:00
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
Re: distort bug?
Posted: 2010-06-08T18:53:06-07:00
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
Re: distort bug?
Posted: 2010-06-08T20:23:58-07:00
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.