重新创建的png图像是黑色的

时间:2015-10-13 07:47:41

标签: php image-processing gd

example image

注意: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)

更新 这里证明了示例图像确实是透明的,并且可以在保持透明度的同时对其进行操作。请注意,图像的底部现在更加褐色。这是通过略微修改此行imagesetpixel($new_image, $x, $y, imagecolorallocatealpha($image, 100, $g, $b, $alpha));

来实现的

manipulated transparent image

1 个答案:

答案 0 :(得分:1)

您的第二张图片是8位,这意味着它最多只支持256种颜色。这使得它成为“基于调色板”的图像,因此它不支持Alpha透明度。

只需在创建$image后添加以下行即可解决问题:

imagepalettetotruecolor($image);

这对已经是真彩色的图像没有任何影响,因此grass.png继续正确处理。来自PHP manual page

  

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