Re: PGM Colourisation

Bob Friesenhahn <[email protected]> Mon, 14 Dec 2020 18:30:31 -0600 (CST)
Newsgroups gmane.comp.video.graphicsmagick.help
Message-ID <[email protected]>
On Mon, 14 Dec 2020, Stuart McDonagh via Graphicsmagick-help wrote:
>
> I am having trouble understanding why performing a particular operation in specific circumstances generates what I perceive to be erroneous output.

I think that there is a bug.

> So I am producing a visualisation of a spectrum analyser.
> My program produces frames in PGM (Portable Graymap) binary format, because it is simple to implement.
> These frames contain a maximum of 4 shades of grey:-
> #000000 (black) - the background;
> #555555 - low-value peaks;
> #AAAAAA - mid-value peaks;
> #FFFFFF max-value peaks.

Are you able to supply a sample PGM file?

> Afterwards, I open each frame in GraphicsMagick, like so:-
> gm convert -depth 8 test00000.pgm -fill green -opaque '#555555' -fill yellow -opaque '#AAAAAA' -fill red -opaque '#FFFFFF' -type palette test00000.png

Although the pixels will be 16-bits per sample while in memory, it is 
highly likely that the output file will be 8-bits/sample by default 
because the PGM file is 8-bits/sample.  When using the -depth 8, I 
suggest putting it just before the -type command.

It is normal for the PGM coder to return a PseudoClass ('palette') 
image by default using a grayscale palette. It does this for purpose 
of efficiency.

> The idea is to convert the greyscale image to colour, with the peaks represented by green, yellow and red respectively, then losslessly compress.
>
> The 'depth' argument is due to the packaged gm being built as Q16; output files will by default contain 16-bit samples.

The above is not normally true. Normally the original depth is 
preserved

> However, it doesn't seem to work properly, instead the background (black) gets changed to green.
> The peaks do not change colour at all.
> In addition, I get the error message "Unrecognized color #FFFFFF".

I don't get that error.

> Trying to debug this, I think that in the "gray" colourspace, the 
> lowest colour in the palette is "black" and the highest is "white", 
> with some shades of grey having specific names and the rest being 
> identified by their hex values. If a palette value is named, I can't 
> use its hex value?

You can use the hex value.  I believe that I know the cause of the 
bug. The PNG writer thinks that the image is still grayscale even 
though you did change some pixels to color.  This is actually a bug in 
the '-fill' operation which is not remembering that color was added 
to the gray image.

Add -debug coder prior to the file name and you will see this:

18:25:55 0:0.413178  0.545u 6978 png.c/WriteOnePNGImage/8452/Coder:
       PNG sample depth: 8
18:25:55 0:0.413244  0.545u 6978 png.c/WriteOnePNGImage/8454/Coder:
       PNG color type: Gray (0)

The color type is wrong.

> I have read the documentation for the "-opaque" command several times and it indicates that it should match the exact colour, or nearest if there is a fuzz applied (defaults to 0).
> Therefore, I don't understand why trying to fill '#555555' with green results in black being changed.
>
> Do I need to convert the colourspace before I can use actual colours?  How do I do that?

No.  The grayscale image is compatible with RGB image representation.

If you have a X-windows display (X11), then you can specify "x:" where 
the output file name would go, and an image will be displayed.  In 
this case, you will see color.

Bob
-- 
Bob Friesenhahn
[email protected], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
Public Key,     http://www.simplesystems.org/users/bfriesen/public-key.txt