Can PNG image transparency be preserved when using

2019-01-01 08:54发布

The following PHP code snippet uses GD to resize a browser-uploaded PNG to 128x128. It works great, except that the transparent areas in the original image are being replaced with a solid color- black in my case.

Even though imagesavealpha is set, something isn't quite right.

What's the best way to preserve the transparency in the resampled image?

$uploadTempFile = $myField[ 'tmp_name' ]
list( $uploadWidth, $uploadHeight, $uploadType ) 
  = getimagesize( $uploadTempFile );

$srcImage = imagecreatefrompng( $uploadTempFile );    
imagesavealpha( $targetImage, true );

$targetImage = imagecreatetruecolor( 128, 128 );
imagecopyresampled( $targetImage, $srcImage, 
                    0, 0, 
                    0, 0, 
                    128, 128, 
                    $uploadWidth, $uploadHeight );

imagepng(  $targetImage, 'out.png', 9 );

10条回答
倾城一夜雪
2楼-- · 2019-01-01 09:40

I suppose that this might do the trick:

$uploadTempFile = $myField[ 'tmp_name' ]
list( $uploadWidth, $uploadHeight, $uploadType ) 
  = getimagesize( $uploadTempFile );

$srcImage = imagecreatefrompng( $uploadTempFile );

$targetImage = imagecreatetruecolor( 128, 128 );

$transparent = imagecolorallocate($targetImage,0,255,0);
imagecolortransparent($targetImage,$transparent);
imagefilledrectangle($targetImage,0,0,127,127,$transparent);

imagecopyresampled( $targetImage, $srcImage, 
                    0, 0, 
                    0, 0, 
                    128, 128, 
                    $uploadWidth, $uploadHeight );

imagepng(  $targetImage, 'out.png', 9 );

The downside is that the image will be stripped of every 100% green pixels. Anyhow, hope it helps :)

查看更多
步步皆殇っ
3楼-- · 2019-01-01 09:44
imagealphablending( $targetImage, false );
imagesavealpha( $targetImage, true );

did it for me. Thanks ceejayoz.

note, the target image needs the alpha settings, not the source image.

Edit: full replacement code. See also answers below and their comments. This is not guaranteed to be be perfect in any way, but did achieve my needs at the time.

$uploadTempFile = $myField[ 'tmp_name' ]
list( $uploadWidth, $uploadHeight, $uploadType ) 
  = getimagesize( $uploadTempFile );

$srcImage = imagecreatefrompng( $uploadTempFile ); 

$targetImage = imagecreatetruecolor( 128, 128 );   
imagealphablending( $targetImage, false );
imagesavealpha( $targetImage, true );

imagecopyresampled( $targetImage, $srcImage, 
                    0, 0, 
                    0, 0, 
                    128, 128, 
                    $uploadWidth, $uploadHeight );

imagepng(  $targetImage, 'out.png', 9 );
查看更多
冷夜・残月
4楼-- · 2019-01-01 09:44

Why do you make things so complicated? the following is what I use and so far it has done the job for me.

$im = ImageCreateFromPNG($source);
$new_im = imagecreatetruecolor($new_size[0],$new_size[1]);
imagecolortransparent($new_im, imagecolorallocate($new_im, 0, 0, 0));
imagecopyresampled($new_im,$im,0,0,0,0,$new_size[0],$new_size[1],$size[0],$size[1]);
查看更多
一个人的天荒地老
5楼-- · 2019-01-01 09:44

Regrading the preserve transparency, then yes like stated in other posts imagesavealpha() have to be set to true, to use the alpha flag imagealphablending() must be set to false else it doesn't work.

Also I spotted two minor things in your code:

  1. You don't need to call getimagesize() to get the width/height for imagecopyresmapled()
  2. The $uploadWidth and $uploadHeight should be -1 the value, since the cordinates starts at 0 and not 1, so it would copy them into an empty pixel. Replacing it with: imagesx($targetImage) - 1 and imagesy($targetImage) - 1, relativily should do :)
查看更多
登录 后发表回答