Jump to content

Image png transparency issues


Ninjakreborn

Recommended Posts

I am having issues with PNG files showing strange black stuff in the background.

I am using the following PHP image class:

<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
* File: SimpleImage.php
* Author: Simon Jarvis
* Copyright: 2006 Simon Jarvis
* Date: 08/11/06
* Link: http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php
* 
* This program is free software; you can redistribute it and/or 
* modify it under the terms of the GNU General Public License 
* as published by the Free Software Foundation; either version 2 
* of the License, or (at your option) any later version.
* 
* This program is distributed in the hope that it will be useful, 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
* GNU General Public License for more details: 
* http://www.gnu.org/licenses/gpl.html
*
*/
/* Usage Examples  http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php

Save the above file as SimpleImage.php and take a look at the following examples of how to use the script.

The first example below will load a file named picture.jpg resize it to 250 pixels wide and 400 pixels high and resave it as picture2.jpg

<?php
   include('SimpleImage.php');
   $image = new SimpleImage();
   $image->load('picture.jpg');
   $image->resize(250,400);
   $image->save('picture2.jpg');
?>
If you want to resize to a specifed width but keep the dimensions ratio the same then the script can work out the required height for you, just use the resizeToWidth function.

<?php
   include('SimpleImage.php');
   $image = new SimpleImage();
   $image->load('picture.jpg');
   $image->resizeToWidth(250);
   $image->save('picture2.jpg');
?>
You may wish to scale an image to a specified percentage like the following which will resize the image to 50% of its original width and height

<?php
   include('SimpleImage.php');
   $image = new SimpleImage();
   $image->load('picture.jpg');
   $image->scale(50);
   $image->save('picture2.jpg');
?>
You can of course do more than one thing at once. The following example will create two new images with heights of 200 pixels and 500 pixels

<?php
   include('SimpleImage.php');
   $image = new SimpleImage();
   $image->load('picture.jpg');
   $image->resizeToHeight(500);
   $image->save('picture2.jpg');
   $image->resizeToHeight(200);
   $image->save('picture3.jpg');
?>
The output function lets you output the image straight to the browser without having to save the file. Its useful for on the fly thumbnail generation

<?php
   header('Content-Type: image/jpeg');
   include('SimpleImage.php');
   $image = new SimpleImage();
   $image->load('picture.jpg');
   $image->resizeToWidth(150);
   $image->output();
?>
The following example will resize and save an image which has been uploaded via a form

<?php
   if( isset($_POST['submit']) ) {
      include('SimpleImage.php');
      $image = new SimpleImage();
      $image->load($_FILES['uploaded_image']['tmp_name']);
      $image->resizeToWidth(150);
      $image->output();
   } else {
?>
   <form action="upload.php" method="post" enctype="multipart/form-data">
      <input type="file" name="uploaded_image" />
      <input type="submit" name="submit" value="Upload" />
   </form>
<?php
   }
?>
*/

class Simpleimage {
   
   var $image;
   var $image_type;

   function load($filename) {
      $image_info = getimagesize($filename);
  $this->image_type = $image_info[2];
      if( $this->image_type == IMAGETYPE_JPEG ) {
         $this->image = imagecreatefromjpeg($filename);
      } elseif( $this->image_type == IMAGETYPE_GIF ) {
         $this->image = imagecreatefromgif($filename);
      } elseif( $this->image_type == IMAGETYPE_PNG ) {
         $this->image = imagecreatefrompng($filename);
      }
   }
   function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {
      if( $image_type == IMAGETYPE_JPEG ) {
         imagejpeg($this->image,$filename,$compression);
      } elseif( $image_type == IMAGETYPE_GIF ) {
         imagegif($this->image,$filename);         
      } elseif( $image_type == IMAGETYPE_PNG ) {
         imagepng($this->image,$filename);
      }   
      if( $permissions != null) {
         chmod($filename,$permissions);
      }
   }
   function output($image_type=IMAGETYPE_JPEG) {
      if( $image_type == IMAGETYPE_JPEG ) {
         imagejpeg($this->image);
      } elseif( $image_type == IMAGETYPE_GIF ) {
         imagegif($this->image);
      } elseif( $image_type == IMAGETYPE_PNG ) {
	 imagepng($this->image);
      }   
   }
   function getWidth() {
      return imagesx($this->image);
   }
   function getHeight() {
      return imagesy($this->image);
   }
   function resizeToHeight($height) {
      $ratio = $height / $this->getHeight();
      $width = $this->getWidth() * $ratio;
      $this->resize($width,$height);
   }
   function resizeToWidth($width) {
      $ratio = $width / $this->getWidth();
      $height = $this->getheight() * $ratio;
      $this->resize($width,$height);
   }
   function scale($scale) {
      $width = $this->getWidth() * $scale/100;
      $height = $this->getheight() * $scale/100; 
      $this->resize($width,$height);
   }
   function resize($width,$height) {
      $new_image = imagecreatetruecolor($width, $height);
      imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
      $this->image = $new_image;   
   }      
}
?>

 

In order to call the file I am just calling it via an image tag..and using the following code (this is in a code ignitor framework)

<?php
function show_image($image_name, $height = 0, $width = 0, $dir = 'user_photos') {
	// Get extension
	$characters = 4;
	$length = strlen($image_name);
	$start = $length-$characters;
	$extension = substr($image_name, $start, $characters);

	// Show header based off extension
	switch($extension) {
		case '.jpg':
			header('Content-Type: image/jpeg');
			break;
		case '.gif':
			header('Content-Type: image/gif');			
			break;
		case '.png':
			header('Content-Type: image/png');
			break;
		default:
			header('Content-Type: image/jpeg');
			break;
	}

	// Load image/resize/display
	$this->simpleimage->load(base_url() . 'public/assets/' . $dir . '/' . $image_name);

	// Resize based on passed parameters
	if ($height != 0 && $width == 0) {
		$this->simpleimage->resizeToHeight($height);			
	}else if ($width != 0 && $height == 0) {
		$this->simpleimage->resizeToWidth($width);
	}else if ($height != 0 && $width != 0) {
		$this->simpleimage->resize($width,$height);
	}

	// Perform resizing based off parameters
	$this->simpleimage->output();
}
?>

 

I have this same thing setup as you can see for jpeg's and gifs as well. The only file it's messing up is the PNG files...I have tried on multiple files for PNG type. Some of them show nothing but a black image while others show part of the original image surrounded by black background. I have been able to find out from google that it is something related to a Transparency issue...this is happening in all browsers...I even visit the image page directly and see it directly output and it's the same issue.  It happens in every single browser.

 

Any advice would be greatly appreciated, at this point I am out of ideas. I have tried a variety of image handling functions that I tried adding into the class to see if it started

working and nothing is making that black background stuff go away.  Thanks.

Link to comment
Share on other sites

Try using imagecolorallocatealpha(). With the alpha channel set to 127.

Sometimes when resizing transparent images you get black instead of transparency, strange that the gifs aren't doing it as well with transparency. But sometimes it's picky in my experience.

 

I've resolved this sometimes with code that I adapted from here:

http://www.akemapa.com/2008/07/10/php-gd-resize-transparent-image-png-gif/

 

Link to comment
Share on other sites

I tried this in a variety of ways as you mentioned. I did this to the resize function:

<?php
   function resize($width,$height) {
	$new_image = imagecreatetruecolor($width, $height);
	$transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
	imagefilledrectangle($new_image, 0, 0, $width, $height, $transparent);
	imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
	$this->image = $new_image;   
   }
?>

I have also tried disabling resize so the image comes out as it normally would without any resizing..neither of those work. Also on upload I am doing nothing

(no resizing or nothing) so the PNG's that are uploaded are uploaded unaltered (what I am doing here is on the fly on a page by page basis).  So basically

now I have tried all things with resizing...I even grabbed a test PNG off wikipedia and it actually shows up but still has a lot of black in the background.  I am running

out of ideas here. Not sure how to approach this issue.  Any more advice?

Link to comment
Share on other sites

I assume you've tried this, but just to be thorough...

Have you tried the follow lines just before the line of code you use the imagecolorallocatealpha() in?

 

imagealphablending($new_image, false);

imagesavealpha($new_image,true);

 

Other then that I would try searching some more through google looking specifically for png and php transparency issues. Like I said I sometimes resolved it with that.. hmmm if i think of anything else I'll let u know.

Link to comment
Share on other sites

I just tried that and it didn't work. I also tried a few bits of other debugging work and nothing is working. I do not understand.  This is a standard image.  I can

take any PNG file directly as is, with no resizing or any other changes and just output it.  It's still distorted. As of right now I am doing no resizing at all. I have

checked..even tried commenting out the resize code..then verified the parameters I am passing is (0, 0) is not causing a resize.  I do not understand exactly what is happening here.

Is it something to do with the headers I am used..I have verified it's using the one for PNG only.  I am confused.  Google doesn't seem to be causing any issues...

it's not showing up anything related to the issue I am having and all of those issues I have tested for.  Some stuff about IE only transparency issues which isn't the case here because it's happening in all browsers (although I tried it there as well).

 

I tried the other changes you suggested and nothing else is seeming to work.  The same code on a Jpg works perfectly but anytime I try to do a PNG file it just returns either a pure black image or an image with a lot of black around the edges.  It can't be specifically the way those PNG's are made because I have gotten PNG files from quite a few sources to test this out thouroughly.  If you think of anything else or have any more advice let me know.

 

The strange thing is the Jpg files are working perfectly..and they ARE being resized.  The PNG's aren't even being resized but their still causing this issue. I don't get it.

Link to comment
Share on other sites

If it helps the PHP version is 5.2.13.

The GD information is:

 

gd

 

GD Support enabled

GD Version bundled (2.0.34 compatible)

FreeType Support enabled

FreeType Linkage with freetype

FreeType Version 2.3.8

GIF Read Support enabled

GIF Create Support enabled

JPG Support enabled

PNG Support enabled

WBMP Support enabled

XBM Support enabled

 

Could some of that data have anything to do with why this isn't working?

Link to comment
Share on other sites

OK finally got it.  First off the class was for some reason recognizing these images as Jpg's instead of PNG files..so I manually passed the filetype 'IMAGETYPE_PNG' as the type.

So now that it was taken care of I used the following code:

<?php
   function output($image_type=IMAGETYPE_JPEG) {
      if( $image_type == IMAGETYPE_JPEG ) {
         imagejpeg($this->image);
      } elseif( $image_type == IMAGETYPE_GIF ) {
         imagegif($this->image);
      } elseif( $image_type == IMAGETYPE_PNG ) {
	imageAlphaBlending($this->image, true);
	imageSaveAlpha($this->image, true);
	imagepng($this->image);
      }   
   }
?>

All it took was the alphablending set to true and save it before doing the actually imagepng function. This finally works, and seems to work correctly in all browsers.

 

Thanks for all the help.

Link to comment
Share on other sites

I am still having issues with Resizing though..same thing.  When it's a natural image it works, but when I need to resize it screws up. Now that I am past the basic issue I am working to debug the issue related to the resizing.  In general the output issue was because certain PNG files have different information that others...some are 8, and some are 24..I think different ones (depending on how the backgrounds are done in them) cause some issues with the basic function and require a little more processing (as we figured out while working through it).  I will let you know what works for the resizing once I get it sorted out.

Link to comment
Share on other sites

And the situation has been resolved.  Use the above stuff I described when outputting an image..for PNG files this'll allow it to work properly..then if you need to do a resizing just do this and it all should fall into place...

<?php
   function resize($width,$height) {
   // Setup new image
	$new_image = imagecreatetruecolor($width, $height);

	// These parameters are required for handling PNG files.
	imagealphablending($new_image, false);
	imagesavealpha($new_image,true);
	$transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
	imagefilledrectangle($new_image, 0, 0, $width, $height, $transparent);

	// Resize image
	imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
	$this->image = $new_image;
   }
?>

 

Seems I have resolved all issues. As a bonus the above code works for Jpg files as well.so I didn't have to do special conditions to check what filetype it was before doing this..so it seems this works for all images as well as fixes PNG issues.

 

I haven't done any testing on GIF files so unsure how all that will work..but since this works for the JPG as well as fixes all issues with PNG files then it should support GIF files.  This class I am using I got off the internet but I have heavily modified it so now that these issues are fixed I think I am going to carry it around with me now and start adding in debugging support and everything else.  Thanks for the help, the only reason I was able to resolve it quicker was because of you pointing me in the right direction and giving me that link.  Thanks again.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.