Getting pixels from a grayscale PSD with alpha

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
valen
Posts: 19
Joined: 2017-05-10T14:32:37-07:00
Authentication code: 1151

Getting pixels from a grayscale PSD with alpha

Post by valen » 2017-05-26T14:17:31-07:00

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?

valen
Posts: 19
Joined: 2017-05-10T14:32:37-07:00
Authentication code: 1151

Re: Getting pixels from a grayscale PSD with alpha

Post by valen » 2017-06-02T14:00:16-07:00

This is driving me crazy. Is there no one who has had experience with this?

snibgo
Posts: 12269
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Getting pixels from a grayscale PSD with alpha

Post by snibgo » 2017-06-02T14:32:55-07:00

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.
snibgo's IM pages: im.snibgo.com

User avatar
dlemstra
Posts: 1576
Joined: 2013-05-04T15:28:54-07:00
Authentication code: 6789
Contact:

Re: Getting pixels from a grayscale PSD with alpha

Post by dlemstra » 2017-06-03T06:50:06-07:00

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.
.NET + ImageMagick = Magick.NET https://github.com/dlemstra/Magick.NET, @MagickNET, Donate

valen
Posts: 19
Joined: 2017-05-10T14:32:37-07:00
Authentication code: 1151

Re: Getting pixels from a grayscale PSD with alpha

Post by valen » 2017-06-03T19:28:14-07:00

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.

valen
Posts: 19
Joined: 2017-05-10T14:32:37-07:00
Authentication code: 1151

Re: Getting pixels from a grayscale PSD with alpha

Post by valen » 2017-06-15T07:23:27-07:00

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.

valen
Posts: 19
Joined: 2017-05-10T14:32:37-07:00
Authentication code: 1151

Re: Getting pixels from a grayscale PSD with alpha

Post by valen » 2017-06-15T08:02:54-07:00

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!!!??

snibgo
Posts: 12269
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Getting pixels from a grayscale PSD with alpha

Post by snibgo » 2017-06-15T08:34:12-07:00

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?
snibgo's IM pages: im.snibgo.com

valen
Posts: 19
Joined: 2017-05-10T14:32:37-07:00
Authentication code: 1151

Re: Getting pixels from a grayscale PSD with alpha

Post by valen » 2017-06-15T11:39:54-07:00

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.

snibgo
Posts: 12269
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Getting pixels from a grayscale PSD with alpha

Post by snibgo » 2017-06-15T12:01:57-07:00

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.
snibgo's IM pages: im.snibgo.com

valen
Posts: 19
Joined: 2017-05-10T14:32:37-07:00
Authentication code: 1151

Re: Getting pixels from a grayscale PSD with alpha

Post by valen » 2017-06-15T12:44:08-07:00

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?

User avatar
fmw42
Posts: 25654
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Getting pixels from a grayscale PSD with alpha

Post by fmw42 » 2017-06-15T13:40:17-07:00

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)

valen
Posts: 19
Joined: 2017-05-10T14:32:37-07:00
Authentication code: 1151

Re: Getting pixels from a grayscale PSD with alpha

Post by valen » 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.

User avatar
fmw42
Posts: 25654
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Getting pixels from a grayscale PSD with alpha

Post by fmw42 » 2017-06-15T13:44:54-07:00

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.

valen
Posts: 19
Joined: 2017-05-10T14:32:37-07:00
Authentication code: 1151

Re: Getting pixels from a grayscale PSD with alpha

Post by valen » 2017-06-15T13:49:46-07:00

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.

Post Reply