I've set about using image.module to give me dynamic resizing and have discovered that it doesn't handle transparent pngs at all well. It makes the transparent part black. I've narrowed this down to the functions image.inc provides.
Searching google reveals that GD does not support this funcitonality very well. However on this site; http://forums.devnetwork.net/viewtopic.php?t=43357&
I found a workaround for this limited functionality.
function image_gd_resize($source, $destination, $width, $height) {
if (!file_exists($source)) {
return false;
}
$info = image_get_info($source);
if (!$info) {
return false;
}
$im = image_gd_open($source, $info['extension']);
if (!$im) {
return false;
}
//New line to use new function
//$res = imageCreateTrueColor($width, $height);
$res = imagecreatetruecolortransparent($width, $height);
imageCopyResampled($res, $im, 0, 0, 0, 0, $width, $height, $info['width'], $info['height']);
$result = image_gd_close($res, $destination, $info['extension']);
imageDestroy($res);
imageDestroy($im);
return $result;
}
function imagecreatetruecolortransparent($x,$y) {
$i = imagecreatetruecolor($x,$y);
$b = imagecreatefromstring(base64_decode(blankpng()));
imagealphablending($i,false);
imagesavealpha($i,true);
imagecopyresized($i,$b,0,0,0,0,$x,$y,imagesx($b),imagesy($b));
return $i;
}
function blankpng() {
$c = "iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m";
$c .= "dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADqSURBVHjaYvz//z/DYAYAAcTEMMgBQAANegcCBNCg";
$c .= "dyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAAN";
$c .= "egcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQ";
$c .= "oHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAA";
$c .= "DXoHAgTQoHcgQAANegcCBNCgdyBAgAEAMpcDTTQWJVEAAAAASUVORK5CYII=";
return $c;
}The code above is the necessary functions and the changed .inc function. I cannot make patches :-/ sorry.
I've tested this and it works fine. I get nice transparent resized pngs. Since this is a workaround for GD based shortcomings i'm not sure of it's status within drupal bugs, but here it is.
Thanks
Adam
| Comment | File | Size | Author |
|---|---|---|---|
| #20 | image.inc-transparency_0.patch | 813 bytes | darren oh |
| #17 | try.png | 23.34 KB | Stefan Nagtegaal |
| #16 | image-transluscent-png.diff | 991 bytes | Stefan Nagtegaal |
| #14 | image.inc-transparency.patch | 593 bytes | darren oh |
| #5 | image.inc_3.patch | 1.46 KB | darren oh |
Comments
Comment #1
Stefan Nagtegaal commentedI will investigate this option tonight..
And provde a patch when this is needed..
Comment #2
darren ohThe new code is great! I really appreciate it since I can't get ImageMagick to work. Here is the patch.
Comment #3
dries commentedI'd prefer not have code like this. Maybe this got fixed in newer versions of PHP?
Comment #4
drummPlease remove the debug code.
Comment #5
darren ohI removed the comments. I hope this is what you meant.
Comment #6
Stefan Nagtegaal commentedI'm not sure your way is the cleanest and most elegant one.
I think there is a better way to solve this.. Let me get back to this issue after some investigation and testing..
Comment #7
dries commented-1 on this patch. It's a PHP issue, IMO.
Comment #8
killes@www.drop.org commentedack
Comment #9
darren ohI am now using PHP5 and can confirm that the patch is still necessary. I don't think this is a PHP issue because GD2 obviously does support transparency with this patch. I agree that the code should be simplified.
Comment #10
darren ohComment #11
darren ohIt may be a while before I can work on this.
Comment #12
darren ohI see now why this is a PHP issue. The patch creates a function that really should be provided by PHP.
Comment #13
darren ohI found a method for preserving transparency that uses existing PHP functions described in the PHP manual:
Comment #14
darren ohI found that the problem is that the default background is black. I added four lines to make the background transparent and preserve transparency.
Comment #15
Stefan Nagtegaal commentedI will test and review this patch later. Probably tomorrow..
Steef
Comment #16
Stefan Nagtegaal commentedokay, i tested this it is indeed working..
Because the extra lines of code do only work for transluscent png's, I added a check for
if ($info['extension'] == 'png')and did the extra image alpha allocation in there.Another benefit for this check is that the used functions
imagealphablending()are quite heavy for a server to handle. So doing that for every uploaded image is nonsense..IMO this is RTBC, but I let someone else decide on this..
To test:
Use some (partially) transparent png-file to upload it to drupal and make use of the
img-tag inside your body to display the image..Without this patch, the transluscent/transparent parts of the image will become black and with the patch applied, every transluscent/transparent pixel will be handled as expected for the end user.
I really encourage you guys to review and apply this patch.
If any more work has to be done to get this in, let me know and I'll try to take care of it..
Steef
Comment #17
Stefan Nagtegaal commentedFor people to test, I added a transluscent png to this issue so it's easier to test.
Comment #18
Stefan Nagtegaal commentedI'm using this for 3 days, uploading and resizing/rotating/manipulating images all through drupal and so I dare to set this RTBC.
Please apply..
Comment #19
dries commentedTabs? Coding style needs work.
Comment #20
darren ohCleaned up patch.
Comment #21
Stefan Nagtegaal commentedThis works and coding style looks okay now..
(BTW sorry for the coding style things, I thought my editor was setup the right way for using spaces instead of tabs,but I was obviously wrong :-( )
Comment #22
dries commentedCommitted to CVS HEAD. Thanks.
Comment #23
killes@www.drop.org commentedbackported
Comment #24
(not verified) commented