Page 1 of 1

fx command not effect on png transparency image

Posted: 2008-09-07T23:13:41-07:00
by htvu
I use the command: convert image.png map.png -fx "p{i,v*h}" effect.png to make a Distort effect. It work perfect if image.png not contain any tranparent pixel. When image.png contain tranparent pixels the effect.png is produced same image.png

Help me please !!

Re: fx command not effect on png transparency image

Posted: 2008-09-08T01:09:04-07:00
by fmw42
I am not sure what you are questioning? Are you saying that effect.png is the same as image.png? Are you saying that effect.png has lost the transparency from image.png? Please clarify?

What version of IM are you using?


to preserve transparency in effect.png, try

convert image.png -channel rgba -matte map.png -fx "p{i,v*h}" effect.png

You can also use -clut, if you have a reasonably current IM version.

convert image.png map.png -clut effect.png


see http://www.imagemagick.org/script/comma ... s.php#clut

Re: fx command not effect on png transparency image

Posted: 2008-09-08T02:21:46-07:00
by htvu
hi fmw42,
Thanks for your reply. Sorry for my English. I will upload image files to make you understand my question.

My IM version is 6.3.8

Please download all image and do follow commands:
convert image.png map.png -fx "p{i,v*h}" effect.png (not effect)
convert image2.png map.png -fx "p{i,v*h}" effect2.png (work perfectly)

image.png (transparent background)
Image

image2.png
Image

map.png
Image

-======================================

effect.png
Image

effect2.png
Image
this effect with transparent background is all I want. Please help me !!

Re: fx command not effect on png transparency image

Posted: 2008-09-08T17:28:26-07:00
by anthony
Add -channel RGBA before the -fx and it will then work as expected.

-fx and many other operators are channel effected, and by default -channel is restricted to just RGB and not RGBA

I mention this in many places throughout IM examples.

PS: It is nice to see someone making use of Image distortion maps.

I am really hoping to work on the built-in fast operator for these maps.

ASIDE: the 'effect.png' image was actually distorted, but as the image is really pure black with transparency, and transparency was not distorted, you did not see any result.

If the text was some other color you would see the color was distorted, but with 'black' appearing where the image should have been made fully transparent (weird but true).

Re: fx command not effect on png transparency image

Posted: 2008-09-08T17:44:03-07:00
by fmw42
I am not sure if -fx can do that directly. You will have to wait for Anthony to supply an answer. But here is a workaround:

convert image.png -fill white -opaque none -alpha off map.png -fx "p{i,v*h}" -fuzz 50% -transparent white effect3.png


This changes transparent to white, disables the alpha channel, does your warp, then changes white (using -fuzz to account for gray values due to interpolation) back to transparent.


Note your two images have strange differences:

identify -verbose image.png
Colorspace: Gray
Depth: 16/8-bit
Channel depth:
gray: 1-bit
alpha: 8-bit
Channel statistics:
gray:
min: 0 (0)
max: 0 (0)
mean: 0 (0)
standard deviation: -0 (-0)
alpha:
min: 255 (1)
max: 0 (0)
mean: 55.0361 (0.215828)
standard deviation: 103.896 (0.407436)


It seems very strange to have an alpha min of 255 and max of 0!!! Also your image data is 1-bit here but below it is 8-bit

identify -verbose image2.png
Colorspace: Gray
Depth: 16/8-bit
Channel depth:
gray: 8-bit
alpha: 1-bit
Channel statistics:
gray:
min: 0 (0)
max: 255 (1)
mean: 199.964 (0.784172)
standard deviation: 103.896 (0.407436)
alpha:
min: 255 (1)
max: 255 (1)
mean: 255 (1)
standard deviation: -0 (-0)

NOTE that both image have an alpha channel. So it is not the alpha that is the problem, but either the bit depth of the main image or the bit depth of the alpha and its values.


Perhaps Anthony can shed more light on this situation about the types of images and also about -fx and transparency.

Re: fx command not effect on png transparency image

Posted: 2008-09-08T20:17:02-07:00
by anthony
fmw42 in pm wrote:But as I just mailed you, it does NOT work. I tried it. Unless I am doing something wrong, this does not work:

convert image.png map.png -channel rgba -fx "p{i,v*h}" effect.png

to do as he is expecting. All I get is black image.
Well of course it does not work if you look at what it is doing when working on the transparency channel.

You are looking up a position for the transparency value from a opaque image. But as you did not specify a specific channel it will get the lookup location from the transparency channel. But this will always be '1.0' (opaque), which will get whatever is at 'h' in the source image (usally transparency!)

For a LUT from a grayscale image, you need to pick the grayscale channel to avoid the transparency channel.

EG: you need to use... "p{i,v.g*h}" to ensure you get a grayscale 'color' value from the distortion LUT.

This is also one reason why -channel does not include 'A' by default. the transparency channel is not a 'color' channel has has odd effects when you treat it as a 'color' channel. Especially when dealing with masks, and other grayscale images. You need to think things trough more carefully about everything when transparency becomes involved.

Re: fx command not effect on png transparency image

Posted: 2008-09-08T20:34:24-07:00
by htvu
Many thanks to Mr Anthony and Mr fmw42 !!!
convert image.png map.png -channel rgba -fx "p{i,v.g*h}" effect.png work very well !

Now, I have an issue about the result image - effect.png
If you look at the side of character A (/) it is not a line. I think -fx convert from float number to integer and make this unexpect result. I try to make the map with 300dpi and 16bits/channel but still get same result. :( I used Photoshop to make maps. Is there a way to resolve this problem ???

Re: fx command not effect on png transparency image

Posted: 2008-09-08T21:05:39-07:00
by anthony
You are doing a trapezoidal transform, also called a forward mapped bi-linear transform, or in this special case, bilinear height distortion. Lines do not remain straight, unless they were parallel to the original orthogonal axis.

Actually I have not even been able to generate a simple distortion to achieve this simple effect! Though it is not too difficult to generate if the 'quadrilateral' is aligned with the orthogonal axis, in either source or destination.

If you want ALL lines to remain straight you need to distort BOTH X and Y directions, and in effect generate a Perspective Distortion! Rather than a 'bilinear height distortion'

See http://www.imagemagick.org/Usage/distorts/#perspective
and have an IM that is at least.. version 6.3.5-1

PS: the type of distortion you are generating is still a work in progress, and I need to get it working to generate a future 'grid' distortion.

Re: fx command not effect on png transparency image

Posted: 2008-09-08T21:23:45-07:00
by fmw42
anthony wrote:Well of course it does not work if you look at what it is doing when working on the transparency channel.

You are looking up a position for the transparency value from a opaque image. But as you did not specify a specific channel it will get the lookup location from the transparency channel. But this will always be '1.0' (opaque), which will get whatever is at 'h' in the source image (usally transparency!)

For a LUT from a grayscale image, you need to pick the grayscale channel to avoid the transparency channel.

EG: you need to use... "p{i,v.g*h}" to ensure you get a grayscale 'color' value from the distortion LUT.

This is also one reason why -channel does not include 'A' by default. the transparency channel is not a 'color' channel has has odd effects when you treat it as a 'color' channel. Especially when dealing with masks, and other grayscale images. You need to think things trough more carefully about everything when transparency becomes involved.

This is still not quite clear to me as map.png has no transparency. I admit I had just assumed it was a single channel grayscale image, but I now see that it is rgb, with the same values in each of r,g,b. But I had no idea that one needed to pick a single channel (you used g) to work with as all channels are the same and there is no alpha. So I assume that if you don't specify a single channel, it applies each channel from map.png to the corresponding channel of image.png. But as there is no corresponding alpha in map.png to correspond to image.png, then it appears that you are implying that -fx sort of creates a pure opaque alpha to use in this case.

Unfortunately, the examples (at http://wraith.itc.griffith.edu.au/~anth ... nsform/#fx) regarding -fx do not make this clear. This might make a good example for that page to explain how to handle transparent images in such a case.

Re: fx command not effect on png transparency image

Posted: 2008-09-08T22:01:40-07:00
by anthony
-fx looks up each 'value' for each channel one at a time.

when you set -channel RGBA it means for each pixel it will run through the FX expression four times. Once for red, green, blue and alpha. When it sees 'u' or 'v' or 'p' (etc) without any channel restriction it will use the current channel being evaluated by default.

that is for a 'red' channel "p{i,v*h}" effectively becomes "u.p{i,v.r*h}.r"
that is look up the red channel value from the LUT (in 'v') then use that to look up
the 'r' value at the 'p' position for 'u'.

When IM does this for the 'alpha' value Im effectivally evaluates "u.p{i,v.a*h}.a"
BUT 'v.a' is always opaque or '1', as the gray-scale LUT is opaque. So you get "u.p{i,h}.a" which most likely is always 'transparent', and NOT what you want.

You need to force the lookup of the LUT to only use a color channel, ANY color channel. I like to use 'g' to not only mean 'green' but to imply 'gray-scale' (even though it really isn't. Instead of 'g' I could have used 'intensity' though the result for a proper gray-scale image will still be the same (just slower as IM does more calculations).

So I use "p.{i,v.g*h}" whcih when FX evaluates it for a 'alpha' value will be come. "u.p{i,v.g*h}.a" and the right value of 'a' will be looked up according to the gray-scale LUT image in 'v'.

Re: fx command not effect on png transparency image

Posted: 2008-09-08T22:55:52-07:00
by fmw42
anthony wrote:-fx looks up each 'value' for each channel one at a time.

when you set -channel RGBA it means for each pixel it will run through the FX expression four times. Once for red, green, blue and alpha. When it sees 'u' or 'v' or 'p' (etc) without any channel restriction it will use the current channel being evaluated by default.

that is for a 'red' channel "p{i,v*h}" effectively becomes "u.p{i,v.r*h}.r"
that is look up the red channel value from the LUT (in 'v') then use that to look up
the 'r' value at the 'p' position for 'u'.

When IM does this for the 'alpha' value Im effectivally evaluates "u.p{i,v.a*h}.a"
BUT 'v.a' is always opaque or '1', as the gray-scale LUT is opaque. So you get "u.p{i,h}.a" which most likely is always 'transparent', and NOT what you want.

You need to force the lookup of the LUT to only use a color channel, ANY color channel. I like to use 'g' to not only mean 'green' but to imply 'gray-scale' (even though it really isn't. Instead of 'g' I could have used 'intensity' though the result for a proper gray-scale image will still be the same (just slower as IM does more calculations).

So I use "p.{i,v.g*h}" whcih when FX evaluates it for a 'alpha' value will be come. "u.p{i,v.g*h}.a" and the right value of 'a' will be looked up according to the gray-scale LUT image in 'v'.
Thanks. That confirms what I suspected after your last message. I was thinking that the second image was single channel and was used for each channel of the first image. And as there was no alpha channel in the second, I did not realize that it would create an opaque alpha to use for that case. But it makes sense to do so. Your explanation is very helpful.