21

I am using a script that lets users upload images. The script resizes and converts the images to JPEG.

The problem I have is when a PNG with transparency is uploaded, the resulting JPEG image is black where there was transparency.

How can I edit the below script to replace the black with white? It already does this for GIF's but not for PNG's.

 // RESIZE IMAGE AND PUT IN USER DIRECTORY
  switch($this->file_ext)
{
    case "gif":
      $file = imagecreatetruecolor($width, $height);
      $new = imagecreatefromgif($this->file_tempname);
      $kek=imagecolorallocate($file, 255, 255, 255);
      imagefill($file,0,0,$kek);
      imagecopyresampled($file, $new, 0, 0, 0, 0, $width, $height, $this->file_width, $this->file_height);
      imagejpeg($file, $photo_dest, 100);
      ImageDestroy($new);
      ImageDestroy($file);
      break;

    case "bmp":
      $file = imagecreatetruecolor($width, $height);
      $new = $this->imagecreatefrombmp($this->file_tempname);
      for($i=0; $i<256; $i++) { imagecolorallocate($file, $i, $i, $i); }
      imagecopyresampled($file, $new, 0, 0, 0, 0, $width, $height, $this->file_width, $this->file_height); 
      imagejpeg($file, $photo_dest, 100);
      ImageDestroy($new);
      ImageDestroy($file);
      break;

    case "jpeg":
    case "jpg":
      $file = imagecreatetruecolor($width, $height);
      $new = imagecreatefromjpeg($this->file_tempname);
      for($i=0; $i<256; $i++) { imagecolorallocate($file, $i, $i, $i); }
      imagecopyresampled($file, $new, 0, 0, 0, 0, $width, $height, $this->file_width, $this->file_height);
      imagejpeg($file, $photo_dest, 100);
      ImageDestroy($new);
      ImageDestroy($file);
      break;

    case "png":
      $file = imagecreatetruecolor($width, $height);
      $new = imagecreatefrompng($this->file_tempname);
      for($i=0; $i<256; $i++) { imagecolorallocate($file, $i, $i, $i); }
      imagecopyresampled($file, $new, 0, 0, 0, 0, $width, $height, $this->file_width, $this->file_height); 
      imagejpeg($file, $photo_dest, 100);
      ImageDestroy($new);
      ImageDestroy($file);
      break;
  } 

  chmod($photo_dest, 0777);

  return true;
}

I tried editing the case "png": portion to match that of the case "gif": code but the resulting JPEG is completely white.

UPDATE:

I fixed it myself.

Thanks, Everyone, for contributing!

I replaced:

case "png":
      $file = imagecreatetruecolor($width, $height);
      $new = imagecreatefrompng($this->file_tempname);
      for($i=0; $i<256; $i++) { imagecolorallocate($file, $i, $i, $i); }
      imagecopyresampled($file, $new, 0, 0, 0, 0, $width, $height, $this->file_width, $this->file_height); 
      imagejpeg($file, $photo_dest, 100);
      ImageDestroy($new);
      ImageDestroy($file);
      break;

with:

case "png":
      $file = imagecreatetruecolor($width, $height);
      $new = imagecreatefrompng($this->file_tempname);
      $kek=imagecolorallocate($file, 255, 255, 255);
      imagefill($file,0,0,$kek);
      imagecopyresampled($file, $new, 0, 0, 0, 0, $width, $height, $this->file_width, $this->file_height);
      imagejpeg($file, $photo_dest, 100);
      ImageDestroy($new);
      ImageDestroy($file);
      break;
michaeltwofish
  • 4,096
  • 3
  • 28
  • 32
Jeff
  • 495
  • 1
  • 5
  • 18
  • What does this imagecolorallocate do? It's receiving 4 parameters for png, shouldn't it receive 5, for the alpha channel? – Ortiga Apr 16 '11 at 19:27
  • I did not write the code, I'm a noob. I don't know the answer to your question. Sorry I could not help you to help me. – Jeff Apr 16 '11 at 19:43
  • This is all in the manual, actually. _imagecolorallocate - Returns a color identifier representing the color composed of the given RGB components._ And for the alpha transparency, you need to use `imagecolorallocatealpha`, which indeed adds a 5th parameter: http://php.net/manual/en/function.imagecolorallocatealpha.php – kasimir Dec 06 '12 at 09:57
  • 4
    @Jeff - as you solved the problem yourself, why not write an answer and accept it as the solution? That way your question is no longer sitting around as "unanswered". – Raad Feb 21 '13 at 14:18
  • Use this tutorial http://stackoverflow.com/questions/43409133/solved-png-image-issue-php-background-black-backround-on-resized-images – Raju Harry Apr 14 '17 at 10:02
  • one would think to use imagepng instead of imagejpeg but that person would be wrong .... PS I'm that person. – Mike Q Jun 06 '17 at 17:02

6 Answers6

3
switch($image_extension){
  case 'gif':
  case 'GIF':
    $image_orig_resource = imagecreatefromgif($image_orig_path);
    break;
  case 'png':
  case 'PNG':
    $image_orig_resource = imagecreatefrompng($image_orig_path);
    break;
  case 'jpg':
  case 'jpeg':
  case 'JPG':
  case 'JPEG':
    $image_orig_resource = imagecreatefromjpeg($image_orig_path);
    break;
  default:
    throw new Exception('Extension not supported');
}

$image_resource = imagecreatetruecolor($width, $height);
imagefill($image_resource, 0, 0, imagecolorallocate($image_resource, 255, 255, 255));  // white background;

imagecopyresampled($image_resource, $image_orig_resource, 0, 0, 0, 0, $width, $height, $image_orig_width, $image_orig_height);

imagejpeg($image_resource, $image_path, 100); // quality: [0-100]
jiappo
  • 61
  • 4
1

I found this other similar question here on this site. I hope it is helpful.

adding background color to transparent images using gd and php

Community
  • 1
  • 1
user3125362
  • 63
  • 1
  • 9
0

After Image true colour add the lines:

    $file = imagecreatetruecolor($width, $height);
    $background = imagecolorallocate($file, 0, 0, 0);
    imagecolortransparent($file, $background);
    imagealphablending($file, false);
    imagesavealpha($file, true);

This will help in mailtaining alpha for all formats. Ping if u dont get answer.

0

Ok, this function is from php. As I've never worked with images on php, so I didn't know it.

So, images a composed of three colors: RGB (red, green, blue). In case of PNG, it's also composed of another filter, called alpha, which is the transparency

SO, just for PNG, you should switch imagecolorallocate to imagecolorallocatealpha($file,$i,$i,$i,$i);

This should make your images transparent. Does this solve your problem or do you really need them in white background?

Edit: I also noted that you are using imagejpg function in all cases. Switch them to the corresponding function, i.e., imagepng, imagebmp, imagegif

Ortiga
  • 8,455
  • 5
  • 42
  • 71
  • I need to keep imagejpeg for all functions because all of the new images must be jpg. I made the other changes you suggested but the resulting jpg's still have black where there was transparency. I do not need to keep the transparency, I just need to change the black to white. Thank you! – Jeff Apr 16 '11 at 20:33
0

Try like this (not tested):

case "png":
  $file = imagecreatetruecolor($width, $height);
  $new = imagecreatefrompng($this->file_tempname);
  imagefilledrectangle ($file, 0, 0, $width, $height, imagecolorallocate($file, 0,0,0))

(predraw a white background on $file image)

Also, the for($i=0; $i<256; $i++) { imagecolorallocate($file, $i, $i, $i); } part looks strange.

glebtv
  • 3,739
  • 1
  • 22
  • 10
0

for me these settings effected a black background, to get white change it to:

$background = imagecolorallocate($file, 255, 255, 255);

My example:

$NewImageWidth      = 275; //New Width of Image
$NewImageHeight     = 275; // New Height of Image
$Quality        = 85; //Image Quality

$NewCanves = imagecreatetruecolor($NewWidth, $NewHeight);
$background = imagecolorallocate($NewCanves, 255, 255, 255);
imagefilledrectangle($NewCanves, 0, 0, $NewWidth, $NewHeight, $background);
$NewImage = imagecreatefrompng($SrcImage);
imagejpeg($NewCanves,$DestImage,$Quality);
Gabor Koltai
  • 431
  • 6
  • 11