Converting a 24bit PNG into a JPEG with GD

GD and GD2 are useful libraries for creating graphics on-the-fly. Discuss your PHP GD and GD2 scripts here.

Moderators: onion2k, General Moderators

Post Reply
grahama
Forum Newbie
Posts: 6
Joined: Mon Jul 07, 2003 11:57 pm

Converting a 24bit PNG into a JPEG with GD

Post by grahama »

feyd | Please use

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]


Is there some trick to getting PHP GD to properly convert a 24bit PNG[with alpha] into a JPEG without garbling the image output?

The below WILL output the jpg image, but it appears that the alpha channel from the original png is not being replace by the new background color.

To no avail, I tried:
* Setting imageAlphaBlending and imageSaveAlpha to 'false' and 'true' and '1' and '0'.
* Setting the jpeg quality to 90 and 100.
* Trying imagecopy and imagecopymerge with a background-color image built from imagecreate
* ditching the background image and just using imagefill directly on the png

At this point, I am blindly throwing darts at a wall.

many thanks in advance

example url:
get_image.php?url=24bit.png&type=jpg&color=420000

Code: Select all

<?php

isset($_GET["type"])?$type=htmlentities($_GET["type"] ):$type="jpg";
isset($_GET["url"])?$url=realpath($_GET["url"]): $url="blank.png";
isset($_GET["color"])?$color= ($_GET["color"]):$color="#ffffff";

$path_parts= pathinfo($url);
$file= explode(".",$path_parts['basename']);
$image_name=$file[0];
$image_output = '$image_name'.'.'.$type;
list($sx, $sy)=getimagesize($url);

//colored background image
$bg_image=imagecreate($sx,$sy);
list($R,$G,$B)= (HEX2RGB($color));
$mycolor= ImageColorAllocate($bg_image, $R,$G,$B);
ImageFill($bg_image, 0, 0, $mycolor);

//the 24bit png with an alpha channel
$image = imagecreatefrompng($url);
imageAlphaBlending($image,true);
imageSaveAlpha($image, true);

//Neither one of these works outputs properly
//imagecopy($bg_image, $image, 0, 0, 0, 0, $sx, $sy);
imagecopymerge($bg_image,$image, 0, 0, 0, 0, $sx,$sy, 100);

header('Content-type:image/jpeg');
imagejpeg($bg_image,'',95);
imagedestroy($bg_image);
imagedestroy($image);

function HEX2RGB($color){
$color_array = array();
$hex_color = strtoupper($color);
for($i = 0; $i < 6; $i++){
$hex = substr($hex_color,$i,1);
switch($hex){
case "A": $num = 10; break;
case "B": $num = 11; break;
case "C": $num = 12; break;
case "D": $num = 13; break;
case "E": $num = 14; break;
case "F": $num = 15; break;
default: $num = $hex; break;
}
array_push($color_array,$num);
}
$R = (($color_array[0] * 16) + $color_array[1]);
$G = (($color_array[2] * 16) + $color_array[3]);
$B = (($color_array[4] * 16) + $color_array[5]);
return array($R,$G,$B);
unset($color_array,$hex,$R,$G,$B);
}

?>

feyd | Please use

Code: Select all

,

Code: Select all

and [syntax="..."] tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:  [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url] to learn how to do it too.[/color]
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Shouldn't you use imagecreatetruecolor()?
grahama
Forum Newbie
Posts: 6
Joined: Mon Jul 07, 2003 11:57 pm

Post by grahama »

thanks for the tip :)
I tried imagecreatetruecolor, but had the same results

Code: Select all

$bg_image=imagecreatetruecolor($sx,$sy); //changed from imagecreate
list($R,$G,$B)= (HEX2RGB($color));
$mycolor= ImageColorAllocate($bg_image, $R,$G,$B);
ImageFill($bg_image, 0, 0, $mycolor);
here is the original 24bit PNG:
Image

here is the resulting jpg:
Image

I have tried serveral other 'source' png-24 images, with the same garbled results

anyone know?
grahama
Forum Newbie
Posts: 6
Joined: Mon Jul 07, 2003 11:57 pm

Post by grahama »

I got it:)
The trick is to use imagecopyresample.

This will be great for my css files.
If all goes well, the below will be used to dynamically convert PNG images to Jpegs for IE6 and below.
For some bizarre reason, you can not use the background-position property with PNGs for <= IE 6.
So, in my IE-specific css, I'll dynamically convert the PNG to a JPG and replace the transparency with a background color


Code: Select all

<?php

isset($_GET["type"]) ? $type=htmlspecialchars($_GET["type"] ): $type="jpg";
isset($_GET["url"]) ? $url=realpath($_GET["url"] ): $url="blank.png";
isset($_GET["color"]) ?$color= htmlspecialchars($_GET["color"]):$color="#ffffff";

//get path info on the $url
$path_parts= pathinfo($url);
$file= explode(".",$path_parts['basename']);
$image_name=$file[0];
list($sx, $sy)=getimagesize($url);

// Create a bg image from the color and image size variables
$bg_image=imagecreatetruecolor($sx,$sy);
list($R,$G,$B)= (HEX2RGB($color));
$mycolor= ImageColorAllocate($bg_image, $R,$G,$B);
ImageFill($bg_image, 0, 0, $mycolor);

//Create the PNG image from the $url variable
$image = imagecreatefrompng($url);
imageAlphaBlending($image,true	); imageSaveAlpha($image, true);

//Resample the merging of the background image and the original PNG file
imagecopyresampled($bg_image, $image, 0, 0, 0, 0, $sx, $sy, $sx, $sy);

// Send out as GIF or JPG
Switch ($type){
case "jpg":   header('Content-type: image/jpeg');  imagejpeg($bg_image,'',95); break;
case "gif":   header('Content-type: image/gif');  imagegif($image); break;
}

//Remove bg image and PNG from memory
imagedestroy($bg_image);
imagedestroy($image);


function HEX2RGB($color){
$color_array = array();
$hex_color = strtoupper($color);
for($i = 0; $i < 6; $i++){
  $hex = substr($hex_color,$i,1);
  switch($hex){
   case "A": $num = 10; break;
   case "B": $num = 11; break;
   case "C": $num = 12; break;
   case "D": $num = 13; break;
   case "E": $num = 14; break;
   case "F": $num = 15; break;
   default: $num = $hex; break;
  }
  array_push($color_array,$num);
}
$R = (($color_array[0] * 16) + $color_array[1]);
$G = (($color_array[2] * 16) + $color_array[3]);
$B = (($color_array[4] * 16) + $color_array[5]);
return array($R,$G,$B);
unset($color_array,$hex,$R,$G,$B);
}
?>
Post Reply