php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47946 ImageConvolution overwrites background (fix included)
Submitted: 2009-04-10 16:26 UTC Modified: 2009-06-23 00:57 UTC
Votes:6
Avg. Score:4.8 ± 0.4
Reproduced:6 of 6 (100.0%)
Same Version:3 (50.0%)
Same OS:3 (50.0%)
From: jcolby at acsol dot net Assigned: pajoye
Status: Assigned Package: GD related
PHP Version: 5.2.9 OS: openSuse, CentOS, FreeBSD
Private report: No CVE-ID:
Have you experienced this issue?
Rate the importance of this bug to you:

 [2009-04-10 16:26 UTC] jcolby at acsol dot net
Description:
------------
When using imageconvolution on an image containing alpha, the background color on the resource image will be replaced with opaque black regardless of any alpha or background settings. This is because of the gdimagecopy internal to the function without the proper savealpha flags being set & no transparent image fill after gdimagecreatetruecolor is used inside the function. 

This is similar to bug #34992 but I've had a chance to break it open and actually fix it.

This affects all versions of php 5, up to the latest 5.2.9 stable build, and I wouldn't doubt it currently affects 6 as well. 

Now, I managed to fix it in my own build, but I don't know how to get it advanced from there. This is not my realm of experience, I just had to repair it.

Patch: php-5.2.9\ext\gd\libgd\gd.c

Add in var initialization:
/* patch */
gdImagePtr  srctrans;
/* patch */

Add after "srcback = gdImageCreateTrueColor..."
/* patch */
srcback->saveAlphaFlag = 1;
srctrans = gdImageColorAllocateAlpha(srcback, 0, 0, 0, 127);
gdImageFill(srcback, 0, 0, srctrans);
/* end patch */

Thats all it requires.


Reproduce code:
---------------
  <?php
  function makeFilter($resource, $matrix, $offset=1.0) {
        global $$resource;
        (float)$divisor = array_sum(array_flatten($matrix));
        if ($divisor == 0) {
          $divisor = .01;
        }
        return imageconvolution($resource, $matrix, $divisor, $offset) ? true : false;
  }  
  
  $edgeMatrix = array(array(1, 0, 1), array(0, 5, 0), array(1, 0, 1));

  $file = "images/anypngwithalpha.png"; // path to png image
  $im = imagecreatefrompng($file); // open image
  imagesavealpha($im, true); 
  makeFilter($im, $edgeMatrix);

  header('Content-type: image/png');
    
  imagepng($im);
  imagedestroy($im);
  ?>

Expected result:
----------------
Convolutionmatrix should apply to all opaque or semi opaque pixels, and background should remain unchanged.

Actual result:
--------------
Convolutionmatrix applies to all opaque and semi opaque pixels, background reverts to solid opaque black regardless of any external settings.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-04-10 16:31 UTC] jcolby at acsol dot net
Missing function from test case:


function array_flatten($array) {
  (array)$tempArray = array();
    
  foreach ( $array as $value ) {
    if ( is_array($value) ) {
      $tempArray = array_merge($tempArray, array_flatten($value));
    } else {
      $tempArray[] = $value;
    }
  }
    
  return $tempArray;
}
 [2009-04-12 14:45 UTC] iliaa@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 [2009-04-12 16:59 UTC] pajoye@php.net
Assigned to me, not completely happy with the fix. 
 [2009-04-12 17:58 UTC] jcolby at acsol dot net
Looking at it, I did initialize the srctrans variable incorrectly. If you have a better method have at it! I'm not a C developer of any form. Since imagecreatetruecolor does a black fill and defaults to alpha off, in order to have a transparent background on the srcback/temp convolution image the reverse becomes necessary or all alpha areas of the image will inherit the black background of srcback.
 [2009-06-23 00:57 UTC] kalle@php.net
Currently the variable assignments have been fixed so it compiles, since it broke the build on a few platforms but thats fixed now. Pierre said he would look into a correct fix for this one
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 18 03:02:48 2014 UTC