2015-10-13 51 views
5

example image重建PNG图像是黑色

注:SO已转换的上述参考图像为JPEG。这里是transparent PNG


下面是示例代码上重新创建一个新的画布 PNG图像并保留透明度。正如你所看到的,它也允许像素级别的操作。具有像custom_func($r, $g, $b)这样的自定义功能,在这个问题的底部可以更好地说明。

基本上这个代码再现/重绘上述图像上一个新的画布成功,因为它是。 请注意,上图中的天空是完全透明的。

$image = imagecreatefrompng('grass.png'); 

    $x_dimension = imagesx($image); 
    $y_dimension = imagesy($image); 
    $new_image = imagecreatetruecolor($x_dimension, $y_dimension); 

    // create a transparent canvas 
    $trans_color = imagecolorallocatealpha($new_image, 0x00, 0x00, 0x00, 127); 
    imagefill($new_image, 0, 0, $trans_color); 

    for ($x = 0; $x < $x_dimension; $x++) { 
      for ($y = 0; $y < $y_dimension; $y++) { 
      $rgb = imagecolorat($image, $x, $y); 
      $r = ($rgb >> 16) & 0xFF; 
      $g = ($rgb >> 8) & 0xFF; 
      $b = $rgb & 0xFF; 
      $alpha = ($rgb & 0x7F000000) >> 24; 
      //$pixel = custom_function($r, $g, $b); 
      imagesetpixel($new_image, $x, $y, imagecolorallocatealpha($image, $r, $g, $b, $alpha)); 
     } 
     } 
    imagesavealpha($new_image, true); 
    imagepng($new_image, 'grass-result.png'); 

然而,当我运行下面这种特定PNG图像上的相同的代码。

problematic png image

它给了我这样一个几乎是黑色的图像。

very dark blue - almost black recreated image


我想明白这里为什么发生?最重要的是,我想知道可能影响过程的因素,所以我可以研究它。为什么结果不同于一个PNG?

理想情况下,我希望我的代码能够保留并将源png图像的透明状态(透明,半透明或不透明)保留并传输到重新创建的图像。正如你所看到的,除了上面的情况,我已经能够实现它。


为了以防万一,这里是我的环境。 Windows 7 - 64位** Wampserver2.5 ** Apache-2.4.9 ** Mysql-5.6.17 ** php5.5.12-64b。而且,这里是图像与getimagesize()一个的var_dump:

array (size=6) 
    0 => int 228 
    1 => int 230 
    2 => int 3 
    3 => string 'width="228" height="230"' (length=24) 
    'bits' => int 8 
    'mime' => string 'image/png' (length=9) 

UPDATE 这里是证明,例如图像确实是透明的,也是可以操作,同时保持透明度。注意图像的底部现在更加褐色。这是通过这条线的稍加修改来实现imagesetpixel($new_image, $x, $y, imagecolorallocatealpha($image, 100, $g, $b, $alpha));

manipulated transparent image

+0

“请注意,上图中的天空是完全透明的。”不,它不是。尝试在非白色背景上查看它。 – timclutton

+0

这是一张JPG。您的代码需要PNG。你上传了正确的文件吗? – timclutton

+2

不知道是否将png转换为.jpegs。不管怎么说,我现在会用证明来更新这个帖子。 – gurung

回答

1

你的第二图像是8位的,这意味着它只能支持最多256种颜色。这使它成为一个“基于调色板”的图像,因此它不支持阿尔法透明度。

通过简单地添加以下行创建$image就可以解决这个问题后:

imagepalettetotruecolor($image); 

这不会对那些已经真彩色图像的任何影响,所以grass.png继续正确处理。从PHP manual page

如果转换完成或源图像已经是真彩色图像,则返回TRUE,否则返回FALSE。

+0

肯定的作品,任何想法为什么32kb图像变成119kb娱乐。 ? – gurung

+1

因为它保存为32位图像,而不是其原始的8位格式。您需要使用['imagetruecolortopalette'](http://php.net/manual/en/function.imagetruecolortopalette.php)反转操作以再次减小文件大小。 – timclutton