Page 1 of 2

Getting pixels from a grayscale PSD with alpha

Posted: 2017-05-26T14:17:31-07:00
by valen
ImageMagick++ (7.0.5-7-Q8-x64-dll)
Visual Studio 2015
Windows 10
Adobe Photoshop CS6 & CC 2017

I am working on a program that converts a PSD file into a custom format and have come across some weird behavior.

I am creating an Image object by passing in a filepath, for example:

Magick::Image myImage("c:\temp\myFile.psd");

The PSD file is in "grayscale" format (Photoshop-->Image-->Mode-->Grayscale) and has 1 alpha channel.

--- First Question ---
The Magick::Image::ImageType() function tells me this is of type "PaletteAlphaType". I expected it to say this is of type "GrayscaleAlphaType". Why is this?

--- Second Question ---
When I create an Image object from a PSD that is grayscale only (no alpha), Magick::Image::channels() tells me that the image has 2 channels. Shouldn't it be 1 channel? And when I create an Image object from a PSD that is grayscale with alpha, Magick::Image::channels() tells me that the image has 3 channels. Shouldn't it be 2 channels?

-- Third Question ---
I am using the Magick::Image::getPixels() function to access the pixels in the image. In other PSD files that are not grayscale with alpha, I get predictable results. But I get odd results when getting pixels from a PSD that is grayscale with alpha. It seems to "skip" the actual gray channel and give me either all zeros or values from the alpha channel. Has anyone else had this problem?

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-02T14:00:16-07:00
by valen
This is driving me crazy. Is there no one who has had experience with this?

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-02T14:32:55-07:00
by snibgo
Q1: I suppose your image has less than 256 shades of gray, so IM has palettised it.

Q2: I don't know. The 1 or 2 channels is a very recent change to IM. Perhaps there is a bug. I suggest you post a minimal sample program that shows the problem, and input files.

Q3: As Q2.

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-03T06:50:06-07:00
by dlemstra
The 'extra' channel is the index channel. I though we had a method in Magick++ that would allow you to determine the type of a channel at a specific index. Cannot find it at the moment. We should probably add it if that is not available.

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-03T19:28:14-07:00
by valen
Thank you for the replies. So, based on what you've said, I still don't see how I am supposed to read the pixels values from a Photoshop file that is grayscale and contains an alpha channel. Whether or not there are "extra" channels, and whether or not my data is being "palletized", I am still not getting values for the gray channel. I either get zeros or the alpha value. No gray values.

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-15T07:23:27-07:00
by valen
Update: Still no luck. I found online someone talking about the "color map" for palettized images. So I printed out all the values in the images color map ( Magick::Image::colorMap() ) but they all appeared to be generic default values. Nothing special or useful.

I still can't find the grayscale pixels and this is becoming more urgent. Can someone help? I can email a sample file if someone wants to IM me.

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-15T08:02:54-07:00
by valen
Create two Photoshop PSD files.
1) 16x16, grayscale
- Fill the image with a solid color (RGB all 50 from color picker)
- No alpha channel
2) 16x16, grayscale
- Fill the image with a solid color (RGB all 50 from color picker)
- Create an alpha channel and fill it with a different solid color (RGB all 200 from color picker).

Code: Select all

int res = 16;
int numPixels = res * res;
		
std::string image1 = "c:\\temp\\image1.psd";
Magick::Image image(image1);

int numChannels = image.channels();

Magick::Quantum *pixels = image.getPixels(0, 0, res, res);

for (int i = 0; i < (numPixels * numChannels); i++)
{
	std::cout << "Pixel: " << std::to_string(i) << " Value: " << std::to_string((uint8_t)*pixels++) << std::endl;
}
The Output:

The first image (grayscale, no alpha) prints out 512 pixel values. This is because ImageMagick reads 2 channels from it. Why 2? I don't know. All the values it prints out are 35. I assume this is a gamma adjusted value based on the original 50 we used.

The second image (grayscale, yes alpha) prints out 768 pixel values. This is because ImageMagick reads 3 channels from it. Why 3? I don't know. The values print out in a repeating pattern "186, 255, 186". Over and over again until all 768 are printed, that pattern repeats. I assume the 186 is a gamma adjusted value based on the original 200 we used. I don't know where the 255 came from. And notice the actual grayscale values of 50 (or adjusted 35) are nowhere to be found!!!??

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-15T08:34:12-07:00
by snibgo
dlemstra says above:
dlemstra wrote:The 'extra' channel is the index channel.
valen wrote:- Fill the image with a solid color (RGB all 50 from color picker)
"50" in a scale of what to what? 0 to 100? 0 to 255?

image.h has a comment for getPixels():
This method is valid for DirectClass images.
Is your image DirectClass? Does your code check this? Given that all the pixels are the same colour, PseudoClass (palleted) seems likely.

Your code assumes your image has at least 16x16 pixels. What do columns() and rows() say about the size?

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-15T11:39:54-07:00
by valen
Sorry - the color values I mentioned were part of the 0-255 range.

I checked now and saw that the image is "PseudoClass". Does that mean I have to process it differently that reading the values via getPixels()?

My code example above was just overly simplified to assume a 16x16 image.

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-15T12:01:57-07:00
by snibgo
There are only two classes: DirectClass and PseudoClass. The documentation says:
This method is valid for DirectClass images.
I assume (but I don't know) the method is therefore not valid for PseudoClass. I guess the numbers you are seeing are indexes, not pixel values.

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-15T12:44:08-07:00
by valen
I guess the numbers you are seeing are indexes, not pixel values.
Indexes into what? The color map? When I print out the color map, I get a 1:1 relationship between the map index and the associated color values. For example, when I print out the color at index 15, I get RGB values all of 15 and the alpha value is always 255. Its like its just in its default state and has not been modified to suite the image. Its not giving me anything useful.

Is there any documentation or samples on how to get color values from a PseudoClass image?

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-15T13:40:17-07:00
by fmw42
I do not know about Magick++, but in command line you can do

Code: Select all

convert image -format "%[pixel:u.p{x,y}]" info:
That will return the color at pixel x,y

Code: Select all

convert -size 128x128 gradient: -alpha copy test.psd
convert test.psd -format "%[pixel:u.p{20,20}]\n" info:
graya(84%,1)
graya(84%,1)

The above is wrong, since the alpha value should be the same as the gray level and it should not be a value of 1 (fully opaque). It is also showing results for two layers.

If I save as png, I get a proper result of

Code: Select all

convert -size 128x128 gradient: -alpha copy test.png
convert test.png -format "%[pixel:u.p{20,20}]\n" info:
graya(84%,0.842527)

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-15T13:43:41-07:00
by valen
Thanks for the info. Unfortunately I must stay in C++ for this tool. I can't resort to the command line.

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-15T13:44:54-07:00
by fmw42
valen wrote:
2017-06-15T13:43:41-07:00
Thanks for the info. Unfortunately I must stay in C++ for this tool. I can't resort to the command line.
I understand. But IM is not processing the psd file correctly from my test even in the command line.

Re: Getting pixels from a grayscale PSD with alpha

Posted: 2017-06-15T13:49:46-07:00
by valen
Sorry, I see now in your post that you were demonstrating another problem with ImageMagick reading PSD files. Interesting.

Just for fun, I tried converting my image to DirectClass via "myImage.classType(Magick::ClassType::DirectClass)" but I still got the same bad pixel values.