GD colour problem

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
helraizer
Forum Commoner
Posts: 31
Joined: Thu Jun 05, 2008 8:20 pm

GD colour problem

Post by helraizer »

Hey folks,

Code: Select all

 
 
 if ($back == "m") //$back is a value pulled from a db; that works perfectly.
    {
        $wid = $rowing['width'];
        $hei = $rowing['height'];
        createthumb("660x240background2.gif", "./user/" . $user . "_back.gif", $wid, $hei);
 
        $image = imagecreatefromgif("./user/" . $user . "_back.gif");
        $blue = ImageColorAllocate($image, 200, 200, 255); // prepare some blueness
        $black = ImageColorAllocate($image, 0, 0, 0); // ... and whiteness
        $im = ImageCreate(300, 35);
        $black_a = imagecolorallocate($im, 0, 0, 0);
        $white_a = imagecolortransparent($im, $black_a);
        $white = ImageColorAllocate($im, 255, 255, 255);
        ImageFill($im, 0, 0, $white_a);
        Imagettftext($im, 15, 0, 10, 30, $white, $font, $user . "'s Shoutbox");
 
        $cur_line_y = 65; // This stores how far down the image the current line will print
 
        $postperpage = 11;
       }
elseif ($back == "u")
    {
        $wid = $rowing['width'];
        $hei = $rowing['height'];
 
 
 
        //        createthumb("./user/".$user."_img.gif", "./user/" . $user . "_backim.gif", $wid, $hei);
 
        imagecreatefromgif("./user/" . $user . "_img.gif");
 
 
 
        $images = imagecreate($wid, $hei);
 
        $imge = imagecreatefromgif("./user/" . $user . "_backim.gif");
 
        imagecopymerge($images, $imge, 0, 0, 0, 0, $wid, $hei, 20);
 
        imagegif($images, "./user/" . $user . "_back_trans.gif");
 
        $image = imagecreatefromgif("./user/" . $user . "_back_trans.gif");
 
$im = ImageCreate(300, 35);
        $black_a = imagecolorallocate($im, 0, 0, 0);
        $white_a = imagecolortransparent($im, $black_a);
        $white = ImageColorAllocate($im, 255, 255, 255);
        ImageFill($im, 0, 0, $white_a);
        Imagettftext($im, 15, 0, 10, 30, $white, $font, $user . "'s Shoutbox");
        
        $cur_line_y = 74; // This stores how far down the image the current line will print
        $postperpage = 10;
    }
 
$sql = ""; // no need for actuall SQL statement - it works.
 
$result = mysql_query($sql) or die("error in  sqllls: " . mysql_error());
 
 
$cur_line_x = 24; // This stores how far across the image the current line will print
$pagecharwidth = 75; // this is the maximum length of the line before it wraps;
$lineheight = 18; // This is how much to move down to print the next line
$pagelinelimit = 1; // How many of each comment appears per page.
 
 
//ImageString($image, 3, 15, $cur_line_y, trim(stripslashes($wordwrapped[0])), $black);
 
$numberOfLines = $pagelinelimit;
 
for ($i = 0; $i < $numberOfLines; $i++)
{
    while ($row = mysql_fetch_array($result))
    {
 
        $name = "[" . htmlspecialchars_decode($row['username']) . "] "; //it works - returns username
        $font = $row['font']; //it works - renders the colour
        $color = $row['color']; //it works - changes the font
        $line = htmlspecialchars_decode($row['comment']); //it works, posts the shout
 
 if ($name == "[] ")
        {
            $name = "";
 
            $line = $name . $line;
        }
        else
        {
            $line = $name . $line;
 
        }
 
//code for emoticons.
 
//add shouts to image!
        if ($back == "m" )
        {
            if ($color == "white" || $color == "yellow" || $color == "green" || $color ==
                "orange" || $color == "aqua")
            {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, getColor($color), getfont
                    ($font), trim($line));
 
 
            }
            elseif ($color != "white" || $color != "yellow" || $color != "green" || $color !=
                "orange" || $color != "aqua")
            {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, $white, getfont($font),
                    trim($line));
 
 
            }
            elseif ($font == "fixedsys" || $font == "Courbd" || $font == "arial" || $font ==
                "timesnr" || $font == "calibri" || $font == "comicsans" || $font == "palab")
            {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, getColor($color), getfont
                    ($font), trim($line));
 
 
            }
            else
            {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, $white, "courbd.ttf", trim
                    ($line));
 
 
            }
 
        }
        elseif ($back == "w" )
        {
 
            $blac = imagecolorallocate($image, 0, 0, 0);
 
            if ($color == "black" || $color == "purple" || $color == "blue" || $color ==
                "emerald" || $color == "red")
            {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, getColor($color), getfont
                    ($font), trim($line));
 
 
            }
            elseif ($color != "black" || $color != "purple" || $color != "blue" || $color !=
                "emerald" || $color != "red")
            {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, $blac, getfont($font),
                    trim($line));
 
 
            }
            elseif ($font == "fixedsys" || $font == "Courbd" || $font == "arial" || $font ==
                "timesnr" || $font == "calibri" || $font == "comicsans" || $font == "palab")
            {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, getColor($color), getfont
                    ($font), trim($line));
 
 
            }
            else
            {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, $white, "courbd.ttf", trim
                    ($line));
 
 
            }
 
           }
 
 
 

Depending on the values of $back, the background of the image changes and the font colours also change. This code works so far.

Problem code

Code: Select all

 
 elseif($back == "u")
           {
               if ($color == "white" || $color == "yellow" || $color == "green" || $color ==
                "orange" || $color == "aqua")
            {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, getColor($color), getfont
                    ($font), trim($line));
 
 
            }elseif ($color != "black" || $color != "purple" || $color != "blue" || $color !=
                "emerald" || $color != "red")
            {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, $white, getfont($font),
                    trim($line));
 
 
            }
            elseif ($font == "fixedsys" || $font == "Courbd" || $font == "arial" || $font ==
                "timesnr" || $font == "calibri" || $font == "comicsans" || $font == "palab")
            {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, getColor($color), getfont
                    ($font), trim($line));
 
 
            }
           else
           {
               Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, $white, "courbd.ttf", trim
                 ($line) . "    ");
 
 
           }
        }
    
        $cur_line_y += $lineheight;
 
 
    }
}
 
The problem is that when $back == "u", for the first two comments the colours are normal then after that the older comments turn black; the newest comment is in colour but it also changes the colour of the $im that says "User's Shoutbox", which is created as a seperate image.

I can't, for the life of me, see the problem.. can you?

An example: $back == "u" because it's an uploaded background. The oldest comment was white, then I added the Yellow comment, the white one turned black.

Image

Hope that makes sense; if you need more code, just ask. =)
Sam
helraizer
Forum Commoner
Posts: 31
Joined: Thu Jun 05, 2008 8:20 pm

Re: GD colour problem

Post by helraizer »

*bump*

Any one got any ideas?

The process of the background image is that when they upload it as either jpg, gif or png; it is converted to and saved a gif file.

So I uploaded this image

Image

which then is pulled into the code where $back == "u" the first time. It is the saved to the user's specified dimensions. So creates this (700x290, in this case).

Image

It is the merged onto a gd made image at the same dimensions, this time at 20% transparency. Which gives this:

Image

That final, darkened image is what the shouts are written onto. Is there any way this process could be affecting the colours? I can't imagine it can because this process happens seperately each time, before the shouts are written on.

Sam
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Re: GD colour problem

Post by onion2k »

I notice you're using gifs with a 'photo' background. You're probably running out of colours. Gifs can only use 256 different hues* .. after that imagecolorallocate() will fail, and the color used will be the first color in the palette (black in this case by the looks of it).

* Well, actually they can have as many as you like, but breaking through the 256 color limit is far too complicated to go into here.
helraizer
Forum Commoner
Posts: 31
Joined: Thu Jun 05, 2008 8:20 pm

Re: GD colour problem

Post by helraizer »

onion2k wrote:I notice you're using gifs with a 'photo' background. You're probably running out of colours. Gifs can only use 256 different hues* .. after that imagecolorallocate() will fail, and the color used will be the first color in the palette (black in this case by the looks of it).

* Well, actually they can have as many as you like, but breaking through the 256 color limit is far too complicated to go into here.

Aaaargh, it's always so simple. xD

Well thanks for that, you are correct.

I've fixed it now! Based on what you said I used createimagetruecolour($wid, $hei); instead and it works poifectly.

Thanks!
Sam
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Re: GD colour problem

Post by onion2k »

Nice idea for a script by the way. I wrote something similar a few years ago, except rather than creating a gif it actually logged into a forum board using Curl and updated the signature on my account. It was cool until people started posting obscene/racist/sexist stuff, and then the admin for the forum made me remove it for obvious reasons. You might want to add a swear filtering option, or even a moderated message queue, for people when they create a shoutbox for their site...
helraizer
Forum Commoner
Posts: 31
Joined: Thu Jun 05, 2008 8:20 pm

Re: GD colour problem

Post by helraizer »

onion2k wrote:Nice idea for a script by the way. I wrote something similar a few years ago, except rather than creating a gif it actually logged into a forum board using Curl and updated the signature on my account. It was cool until people started posting obscene/racist/sexist stuff, and then the admin for the forum made me remove it for obvious reasons. You might want to add a swear filtering option, or even a moderated message queue, for people when they create a shoutbox for their site...
Yeah, I have a swearing filter at the moment. It's user defined for their shoutbox but if they don't specify anything, a default set it used. I'll also give them the option to moderate their shoutbox. If it's off, then posts will go straight in (through the filter, which is case insensitive so they can't get away with trying to fool the filter by sWAriNg); if it's on, then the user (owner of the shoutbox) will have to okay or deny the posts. Could be good.

At the moment the filter will pick up a word and give the message.

'The word you entered, "bad_word", has been detected as being offensive or threatening in nature; your post has not been submitted. Sorry for any inconvenience.'

and if they are a registered user then a 'warning' point is added to their account, after 10 warning points they can't post in a shoutbox for an amount of time, I think 1 week at the moment.

The current backgrounds being used are

default:
Image
Image

custom:
Image
Image

What do you think to those ideas?

Sam
Last edited by helraizer on Sat Jun 07, 2008 4:30 am, edited 1 time in total.
helraizer
Forum Commoner
Posts: 31
Joined: Thu Jun 05, 2008 8:20 pm

Re: GD colour problem

Post by helraizer »

Hey onion2k or anyone else,

the imagecreatetruecolour hasn't fixed it after all..

You said there was a way for gifs to use more colour, how can I do this?

Or at least come to a comprimise with it and stop the fonts turning black?

Sam
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Re: GD colour problem

Post by onion2k »

The easiest route by far would be to use a jpeg instead of a gif ... just replace imagegif() with imagejpeg, and set the Content-Type header to image/jpeg. Or a PNG, that'd work too.

A slightly more complicated way to do it would be to check to see if imagecolorallocate() returned true, and if it didn't (eg the allocation failed) to use imagecolorclosest() to find the nearest matching color in the image and use that rather than the specific color. That might return something weird if there isn't anything very close though.

To get more than 256 colors into a gif requires some knowledge of how gifs actually work. In a nutshell, a gif is an array of indexes to a colour table. The table (palette) says color 1 is red, color 2 is blue and so on. After that the image data is just a reference to the colors in the table rather than the colors themselves ... so a line that's alternating red and blue pixels would be stored as 1212121212121212. Now, one of the colors is allowed to be transparent, which really means 'don't change the color of the pixel that was there before displaying the gif'. That's how a basic gif works. The next thing you need to know is how an animated gif works. They're actually really simple. They're just a series of normal gif files bundled into a single file with some extra information about how long each gif show be displayed for, and whether the whole thing should loop. The clever bit is that each gif in the animation can have it's own palette. So frame 1, the first gif in the animation, can have 256 colors, the second can have 256 different colors, and so on. If the second gif uses a transparent color then all the colors from the first gif will show through... use one frame for every 255 colors (+1 for transparent) and you can have as many colors in a gif as you like. Here's a good example:

Image

The problem is that GD2 can't make animated gifs, so you'd have to write some code that calculates which pixels should be in each frame, and then make all the frames, and then construct the animated gif data yourself. It'd be *really* complicated.

I'd just use a jpeg.
helraizer
Forum Commoner
Posts: 31
Joined: Thu Jun 05, 2008 8:20 pm

Re: GD colour problem

Post by helraizer »

onion2k wrote:The easiest route by far would be to use a jpeg instead of a gif ... just replace imagegif() with imagejpeg, and set the Content-Type header to image/jpeg. Or a PNG, that'd work too.

A slightly more complicated way to do it would be to check to see if imagecolorallocate() returned true, and if it didn't (eg the allocation failed) to use imagecolorclosest() to find the nearest matching color in the image and use that rather than the specific color. That might return something weird if there isn't anything very close though.

To get more than 256 colors into a gif requires some knowledge of how gifs actually work. In a nutshell, a gif is an array of indexes to a colour table. The table (palette) says color 1 is red, color 2 is blue and so on. After that the image data is just a reference to the colors in the table rather than the colors themselves ... so a line that's alternating red and blue pixels would be stored as 1212121212121212. Now, one of the colors is allowed to be transparent, which really means 'don't change the color of the pixel that was there before displaying the gif'. That's how a basic gif works. The next thing you need to know is how an animated gif works. They're actually really simple. They're just a series of normal gif files bundled into a single file with some extra information about how long each gif show be displayed for, and whether the whole thing should loop. The clever bit is that each gif in the animation can have it's own palette. So frame 1, the first gif in the animation, can have 256 colors, the second can have 256 different colors, and so on. If the second gif uses a transparent color then all the colors from the first gif will show through... use one frame for every 255 colors (+1 for transparent) and you can have as many colors in a gif as you like. Here's a good example:

Image

The problem is that GD2 can't make animated gifs, so you'd have to write some code that calculates which pixels should be in each frame, and then make all the frames, and then construct the animated gif data yourself. It'd be *really* complicated.

I'd just use a jpeg.
Hey,

I'll look into that when I get back from work.

The only problem with imagejpg is the quality of colours.. the gif gives

Image - bold strong colours.

whereas imagejpg gives:

Image - pale, almost pastel colours + fuzzier image.

I could use png, but they tend to be larger file size. I'll try something.

Thanks,
Sam
helraizer
Forum Commoner
Posts: 31
Joined: Thu Jun 05, 2008 8:20 pm

Re: GD colour problem

Post by helraizer »

I got it to work now with the same technique only now it creates each image as png. :D

It works perfectly now, and no black fonts!

Image

Image

Image

Image

Thanks for your help, onion2k.

Sam
Post Reply