Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
I'm trying to convert PSD files to PNG using ImageMagick, and I get a white border where the alpha is less than 255.
Here is an image that shows the difference. For you to notice, I put a black background after converting it to PNG.
I tried using the -background parameter like so :
-background none
-background black
-background rgba(0, 0, 0, 0)
Thus where the image is partially transparent the near white is coming through as a halo.
You can try recreating your input file with black under the transparent.
I have tried to change white to black in IM, but as the white is not consistent, I need a very large fuzz factor which then destroys part of the image as well.
The only thing that I can do is reduce the extent of the transparency area so that it does not cover where the image is kind of white.
I wonder why IM reads white values. Seems to me the colors are linearly interpolated from their actual RBG values to a White according their Alpha values.
Something like :
That would explain the values you outputted.
- When the alpha is 255 we get the normal source color
- When the alpha gets a little below 255 we get something whiter.
- When the alpha is amost 0 we get something almost white : 517: (250,250,250, 5)
- When the alpha is 0 we get a perfect white : 17487 : (255,255,255, 0)
No, basically you cannot have a transparency without an underlying color. When IM creates pure transparent pixels it has a black color underneath R=0,B=0,G=0,A=0. But in your image, the underlying color is white or near white, R=255,G=255,B=255,A=0. When you have partial transparency, then IM will take some fraction of the underlying color and show that according to the amount of transparency. In this case, you see partial white, which creates a halo effect.
So I think your problem is in your PSD file. But I could be wrong.
What it appears to me is that PS is treating the background as black, but in exporting it or when IM imports it, it somehow gets white rather than black.
But someone with more expertise than I regarding PSD files needs to look at it.
Your ColorTest.psd file has both background transparency and an alpha transparency (in your colors layer). Perhaps, IM cannot handle this properly as it can only deal with one kind of transparency at a time. (Both files also appear to contain one vertical cyan line that does not show up in IM).
I think Magick may have to look at these files.
Last edited by fmw42 on 2010-09-06T16:40:52-07:00, edited 1 time in total.
fmw42 wrote:basically you cannot have a transparency without an underlying color.
There is no reason to choose the white color as the underlying color. Why not use the RBG color of the pixel instead.
fmw42 wrote:What it appears to me is that PS is treating the background as black, but in exporting it or when IM imports it, it somehow gets white rather than black.
I don't think PS treat the background as black. Otherwise the colors in the circle test should have appeared draker when saved to PNG.
Let's take an example of a red pixel inside a photoshop layer : (255, 0, 0, 255)
Now I change the opacity of the layer to 50. We get: (255, 0, 0, 128)
When we save to PNG inside photoshop we get : (255, 0, 0, 128)
When we convert to PNG with IM we get : (255, 128, 128, 128)
if IM needs to use an underlying color, it would make more sense to use the original RBG (255, 0, 0).
But I don't really see why IM should have to use an underlying color.
Last edited by noon on 2010-09-06T23:16:33-07:00, edited 1 time in total.
Take a look a the histogram I made first. Look at the last line which is pure transparency. It has white underneath it. Pure transparency has to have some underlying color defined for it or colors from the image. In your first image at least, the underlying color is white when you turn the alpha channel off in IM. I don't know where the white is coming from.
But every one of my display tools on the Mac displays your image differently. Some are lighter and some are darker. PSD files are Photoshop and can have proprietary fields that only they know how to interpret.
I just don't know what is going on and it will take some expert to resolve this.
I agree when the pixel is pure transparency, the RBG value has to be chosen. The White color is a good pick for this case.
It does not matter a lot since pure transparent pixel are not visible. It would matter when trying to interpolate with neighboors pixels, for a bilinear interpolation for example, but that's another subject.
But when the pixel is not fully transparent, I can't think of any good reason to use an underlying color. The RBG color should be used.
I used the libpsd (http://sourceforge.net/projects/lib/) and did a simple application to test if it was Photoshop or ImageMagick who was messing with the color values.
As ImageMagick, libpsd can read the merged image and every layer.
I created a layer in photoshop and painted it in red with 50% opacity brush.
The layer itslef has 100% opacity, but all his pixels are supposed to be (255, 0, 0, 128).
What I should read: (255, 0, 0, 128)
What I get when reading the merged image: (255, 127, 127, 255)
What I get when reading the first layer: (255, 0, 0, 128)
Now, I don't understand why the alpha is wrong when reading the merged image (255 instead of 128), but you can notice the RBG values move to white.
On the othe hand reading the first layer gives the right values!
To confirm this test I tried using ImageMagick to convert the PSD to PNG, but instead of using the merged image (layer 0), I convert the layer 1 :
convert ColorTest.psd[1] ColorTest.png
This does give the same result as saving the PNG directly from photoshop!
So it seems Photoshop is to blame. More precisly the merged image of Photoshop is to blame.
It kinda sucks, because to get the right color values, all the layers need to be merged into one inside photoshop to convert only the layer 1...
I understood why the alpha value was 255 when reading in the merged image.
It seems the alpha values of the merged image need to be read in a separated alpha channel.
When reading this channel instead, I get the right alpha value (128).
This mean there is maybe a way to get the original colors from the RGB and the Alpha channel.
I'm looking for it and I'll post if I find out.
I'm not sure but here is a formula I think would work to get the real pixels colors from the merged image in the PSD file :
x = (x - (255 - A)) * (255 / A)
Where A is the alpha channel and x is the R, G, or B component of the pixel.
I came up with this after exporting a red image with 50% opacity and a red image with 25% opacity.
You may have noticed the G and B values grow according alpha like so : 255 - A.
So we can retract it from G :
G = G - (255 - A).
G = 191 - (255 - 64)
G = 191 - 191
G = 0
But it wouldn't work for R :
R = R - (255 - A)
R = 255 - (255 - 64)
R = 255 - 191
R = 64
Now we would get RBG = (64, 0, 0)
To get back on our feet we just need to multiply the R, G and B by (255 / A)
noon wrote:I agree when the pixel is pure transparency, the RBG value has to be chosen. The White color is a good pick for this case.
It does not matter a lot since pure transparent pixel are not visible. It would matter when trying to interpolate with neighboors pixels, for a bilinear interpolation for example, but that's another subject.
But when the pixel is not fully transparent, I can't think of any good reason to use an underlying color. The RBG color should be used.
Thanks for your help !
The problem is that the colors under the partially transparent pixels are near white, so you get a halo.
Yes, I knew the color under the partially transparent pixels were white, and caused the white border.
That's why in my first post I said I tried using the -background parameter with "black" or "rgba(0, 0, 0, 0)".
My question was :
- Why a white background color was used when there is no need to (for non full transparent pixels)
- Was it because of the data contained in the PSD file or because of the way ImageMagick reads the PSD file.
After my tests, seems to me ImageMagick could do a better job during the PSD to PNG conversion, or at least provide an optional parameter to manage the alpha as Photoshop does.
My question was :
- Why a white background color was used when there is no need to (for non full transparent pixels)
- Was it because of the data contained in the PSD file or because of the way ImageMagick reads the PSD file.
In both cases it seems to be in the image or the way the image is interpreted by IM. I don't know. One of the IM experts will need to look into this.
How did you create this images? What were the steps? Is there some control in PS that says what the background will be under transparency? How did you add the transparency?
Too many unknowns for me to be able to give you an answer. Other than PSD files are very hard to translate if you are not photoshop.