Ninjakreborn Posted June 21, 2010 Share Posted June 21, 2010 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. Quote Link to comment https://forums.phpfreaks.com/topic/205424-image-png-transparency-issues/ Share on other sites More sharing options...
gwolgamott Posted June 21, 2010 Share Posted June 21, 2010 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/ Quote Link to comment https://forums.phpfreaks.com/topic/205424-image-png-transparency-issues/#findComment-1075030 Share on other sites More sharing options...
Ninjakreborn Posted June 21, 2010 Author Share Posted June 21, 2010 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? Quote Link to comment https://forums.phpfreaks.com/topic/205424-image-png-transparency-issues/#findComment-1075043 Share on other sites More sharing options...
gwolgamott Posted June 21, 2010 Share Posted June 21, 2010 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. Quote Link to comment https://forums.phpfreaks.com/topic/205424-image-png-transparency-issues/#findComment-1075057 Share on other sites More sharing options...
Ninjakreborn Posted June 21, 2010 Author Share Posted June 21, 2010 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. Quote Link to comment https://forums.phpfreaks.com/topic/205424-image-png-transparency-issues/#findComment-1075099 Share on other sites More sharing options...
Ninjakreborn Posted June 21, 2010 Author Share Posted June 21, 2010 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? Quote Link to comment https://forums.phpfreaks.com/topic/205424-image-png-transparency-issues/#findComment-1075103 Share on other sites More sharing options...
Ninjakreborn Posted June 21, 2010 Author Share Posted June 21, 2010 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. Quote Link to comment https://forums.phpfreaks.com/topic/205424-image-png-transparency-issues/#findComment-1075119 Share on other sites More sharing options...
gwolgamott Posted June 21, 2010 Share Posted June 21, 2010 Cool. Glad it works and will note what you had for my future references too. Quote Link to comment https://forums.phpfreaks.com/topic/205424-image-png-transparency-issues/#findComment-1075120 Share on other sites More sharing options...
Ninjakreborn Posted June 21, 2010 Author Share Posted June 21, 2010 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. Quote Link to comment https://forums.phpfreaks.com/topic/205424-image-png-transparency-issues/#findComment-1075137 Share on other sites More sharing options...
Ninjakreborn Posted June 21, 2010 Author Share Posted June 21, 2010 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. Quote Link to comment https://forums.phpfreaks.com/topic/205424-image-png-transparency-issues/#findComment-1075144 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.