Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

GD reducing pallete causes major problems.

by r.joseph (Hermit)
on Aug 10, 2002 at 08:23 UTC ( #189153=perlquestion: print w/replies, xml ) Need Help??
r.joseph has asked for the wisdom of the Perl Monks concerning the following question:

Hey everyone - wow, it's been a long time since I posted here (school, work, etc. taking all my time) - I missed this place!

Anyway, in my quest to finally get back to Perl after a year of using Java and C in a forced academic enviornment, I decided to start playing around with the module from Lincoln Stien.

I have an image gallery on my website, and I wanted to (because I use Image::Magick to do dynamic resizing anyway) add dynamic text to the images such as a caption that will be held in a database somewhere else. Therefore, GD immediatley came to mind.

So, say I have a file my_image.png, and I want to use GD to simply add the string "TEST!" to the top left-hand corner of the image and re-print it:
use GD; # read the image my $gdimg = GD::Image->newFromPng("my_image.png"); # we need a color for our text my $green = $gdimg->colorAllocate(0,255,0); # write the string "TEST!" to the image $gdimg->string(gdMediumBoldFont, 5, 5, "TEST!", $green); # get the new image my $data = $gdimg->png; # write it out binmode STDOUT; print $data;
Running the above script, color pallete becomes GREATLY reduced, even though the image format stayed the same (PNG all the way through). The same happened if the calls to $gdimg->colorAllocate() and $gdimg->string() are completely removed, so that basically all that is happening is a read/write of the file through the GD interface. Printing out $gdimg->colorsTotal() returns only 256. As an example, check out these two images:

Original: New Window
GD'ed: New Window

As you can see from even these small thumbnail files, the color pallete has been reduced unacceptably (and it's even worse for larger files). Does anyone have any ideas why this might be happening? Thanks a bunch everyone - it's great to be back!

r. j o s e p h
"Violence is a last resort of the incompetent" - Salvor Hardin, Foundation by Issac Asimov

Replies are listed 'Best First'.
Re: GD reducing pallete causes major problems.
by LTjake (Prior) on Aug 10, 2002 at 13:36 UTC
    I can't answer from any experience, but, here goes.

    The image already has a set palette. Judging from the image I would say it already has all 256 colors allocated. You then print text on the image in green. If green isnít already in those 256 colors, then it will have to overwrite one of the existing colors in the palette. Thus when writing the new image, the palette will be messed up. Perhaps you should use the colorClosest function instead? ($index = $image->colorClosest(red,green,blue)) That way you wonít change the current palette.

    See GD docs for more information.

    I could be completely wrong, but no one else has answered yet. :)
Re: GD reducing pallete causes major problems.
by Albannach (Prior) on Aug 10, 2002 at 18:25 UTC
    As handy as GD is, it is strictly an 8-bit tool, and as such even if you do no manipulations at all to your 24-bit PNG, it will still end up with just 256 colours. This is mentioned in the docs, but in my version it is only with reference to jpeg files, however the original docs on Thomas Boutell's site confirm that it is 8-bit for PNG also (apparently true colour support is planned for version 2.0 however).

    My advice is to use GD for schematic graphing and charting (limited pallettes), or for generating tiny thumbnails, but use something else if you need quality.

    Updated: clarified that the starting PNG image was indeed 24-bit, re: hossman's response

    Update 2: The PNG standard states that pallettes be 256 8-bit colours only, but apparently that is not always the case either.

    Update 3: I don't see how the above is misleading, though I suppose it may be considered incomplete (but that's why I linked to the full document ;-). Certainly PNGs are not required to have pallettes, but if they do they can only hold up to 256 colours, and those colours are only 8-bits for each of red, green and blue. That's all I meant to say - honest! ;-)

    More fodder to show your final line of speculation is correct: If you continue to read the GD docs, check out "What's new in version 1.6.1" and you will see that all non-pallette PNGs are pallettized "badly, by dithering them", and that surely must be the true root of this problem. Just below that you will see that version 1.6 of GD was the first to support PNGs, and then it was only PNGs with pallettes, so 1.6.1 was just a quick hack to accept a wider variety of PNGs.

    I'd like to be able to assign to an luser

      I'm failing to understand your argument.

      The image he started with was only 8-bit -- so why does GD introduce loss even without performing any operations on the image?

      (I could understand if he started with a 24-bit image ... but i don't get why working on 8-bit images, with a tool that only supports 8-bit images, would cause problems.)

      Update: ok... at first i thought the confusion was because the orriginal image changed on the remote site (which it did -- the original one was 128x96 -- the current one is 400x300). But i realize now even the 128x96 was 24-bit ("file" lied to me and said it was 8-bit). It looks like after GD is done with an image, it can still be 24bit (at least that's what the gimp says) but instead of being "RGB Color" it's "Indexed Color (40 colors)"
      (file says they're all 8-bit, but says the post GD image is "8-bit colormap" not "8-bit/color RGB")

      Minor issue regarding Update#2...

      Update 2: The PNG standard states that pallettes be 256 8-bit colours only, but apparently that is not always the case either.

      That statement is slightly missleading. If you keep reading, you'll see that if your PNG includes a color pallette, then that pallette can contain at most 256 colors -- but you don't have to use a color pallette at all. PNG supports 5 distinct color types, including "truecolor and truecolor with alpha" in which case...

      ...the PLTE chunk is optional. If present, it provides a suggested set of from 1 to 256 colors to which the truecolor image can be quantized if the viewer cannot display truecolor directly.


      Perhaps some tools (like GD, and the linux file command i was using) are incorrectly detecting the presence of a 256 color pallete as an indication of the PNG being "8-bit", when in fact it is a 24-bit (or greater) "true color" PNG.

      (Of course -- since GD is clearly documented to only support 8-bit images, it might not even be trying to deal with the true color PNGs properly)

      Yep, digging deeper into the docs, it seems as if you are right. Therefore, I suppose that GD is now out of the running as an option for me.

      Therefore, does anyone know of any other Perl image manipulation libraries (ImageMagick can't add text, AFAIK) that could get this job done for me? Thanks!

      r. j o s e p h
      "Violence is a last resort of the incompetent" - Salvor Hardin, Foundation by Issac Asimov
        I stand corrected - it seems Image::Magick has limited text writing functionality, but that is really I'm looking for - I guess that's why they call it ImageMagick!

        r. j o s e p h
        "Violence is a last resort of the incompetent" - Salvor Hardin, Foundation by Issac Asimov
Re: GD reducing pallete causes major problems.
by hossman (Prior) on Aug 15, 2002 at 17:41 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://189153]
Approved by wil
[stevieb]: aaaand Mickey fixed the MetaCPAN::Client bug I just finished talking about already ;)
[stevieb]: Fixed in 2.017000

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2017-06-25 23:48 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (572 votes). Check out past polls.