【问题标题】:I am getting black background image while uploading png image with trransperent我在上传透明的 png 图像时得到黑色背景图像
【发布时间】:2013-08-07 18:54:52
【问题描述】:

我在上传透明的 png 图像时得到黑色背景图像。你能帮帮我吗 我的代码贴在这里

$temp_image_path = $_FILES['img_recipe']['tmp_name'];
$temp_image_name = $_FILES['img_recipe']['name'];

$img_arr = getimagesize( $temp_image_path );
$ext = '';

switch($img_arr['mime'])
{
case 'image/gif': $ext = 'gif';  break;

case 'image/png': $ext = 'png';  break;

case 'image/jpeg': $ext = 'jpg'; break;

case 'image/pjpeg': $ext = 'jpg'; break;

case 'image/x-png': $ext = 'png'; break;

default: return false;
}

$temp_image_name = genToken( $len = 32, $md5 = true );
$temp_image_name .= "." . $ext;

$uploaded_image_path = UPLOADED_IMAGE_DESTINATION . $temp_image_name;

move_uploaded_file( $temp_image_path, $uploaded_image_path );

$recipe_image_path = RECIPE_IMAGE_DESTINATION . $temp_image_name;
$recipe_thumb_image_path = RECIPE_THUMB_IMAGE_DESTINATION . $temp_image_name;

$result_recipe = generate_image_resize( $uploaded_image_path, $recipe_image_path, RECIPE_MAX_WIDTH, RECIPE_MAX_HEIGHT );
$result_recipe_thumb = generate_image_resize( $uploaded_image_path, $recipe_thumb_image_path, RECIPE_THUMB_MAX_WIDTH, RECIPE_THUMB_MAX_HEIGHT );

unlink($uploaded_image_path);

函数 generate_image_resize( $source_image_path, $thumbnail_image_path, $width, $height ) { 列表($source_image_width,$source_image_height,$source_image_type)=getimagesize($source_image_path);

            switch ( $source_image_type )
            {
                case IMAGETYPE_GIF:
                $source_gd_image = imagecreatefromgif( $source_image_path );
                break;

                case IMAGETYPE_JPEG:
                $source_gd_image = imagecreatefromjpeg( $source_image_path );
                break;

                case IMAGETYPE_PNG:
                $source_gd_image = imagecreatefrompng( $source_image_path );
                break;
            }

            if ( $source_gd_image === false ){  return false;   }

            $thumbnail_image_width = $width;
            $thumbnail_image_height = $height;

            $source_aspect_ratio = $source_image_width / $source_image_height;
            $thumbnail_aspect_ratio = $thumbnail_image_width / $thumbnail_image_height;             
            if ( $source_image_width <= $thumbnail_image_width && $source_image_height <= $thumbnail_image_height )
            {   $thumbnail_image_width = $source_image_width;   $thumbnail_image_height = $source_image_height; }
            elseif ( $thumbnail_aspect_ratio > $source_aspect_ratio )
            {   $thumbnail_image_width = ( int ) ( $thumbnail_image_height * $source_aspect_ratio );    }
            else
            {   $thumbnail_image_height = ( int ) ( $thumbnail_image_width / $source_aspect_ratio );    }               
            $thumbnail_gd_image = imagecreatetruecolor( $thumbnail_image_width, $thumbnail_image_height );              
            imagecopyresampled( $thumbnail_gd_image, $source_gd_image, 0, 0, 0, 0, $thumbnail_image_width, $thumbnail_image_height, $source_image_width, $source_image_height );                
            imagejpeg( $thumbnail_gd_image, $thumbnail_image_path, 90 );                
            imagedestroy( $source_gd_image );               
            imagedestroy( $thumbnail_gd_image );

            return true;
        }

【问题讨论】:

    标签: php image-processing gd


    【解决方案1】:

    让我们调用源图像$si,缩略图$ti(这么长...)

    在加载的图像中启用透明度:

    imagealphablending($si, true);
    

    获取加载图片的原始透明色:

    $tc = imagecolortransparent($si);
    
    $tc = ($tc != -1)? $tc = imagecolorsforindex($si, $tc):'hopeless';
    

    这会创建一个黑色的:

    $ti = imagecreatetruecolor( $ti_width, $ti_height );
    

    然后在创建之后:

    if($tc !='hopeless'){ // do we have transparent color?
         // calculate new transparent color
         $tn = imagecolorallocate( $ti, $tc['red'], $tc['green'],$tc['blue']);
         // we need it as index from now on
         $tn = imagecolortransparent( $ti, $tn );
         // fill target with transparent color
         imagefill( $ti, 0,0, $tn);
         // assign the transparent color in target
         imagecolortransparent( $ti, $tn );
    }
    

    现在重新采样可能会更改原始图像上的颜色索引。所以文物会存在。

    imagecopyresampled($ti,$si, 0,0,0,0,$ti_width,$ti_height,$si_width,$si_height );  
    

    【讨论】:

    • if ( $source_gd_image === false ){ return false; }
    • 好吧,现在看看,Suhas,这就是我所知道的一切......如果它仍然不起作用。我不知道还能做什么。
    【解决方案2】:

    在这两行之间添加图像透明度代码:

    $thumbnail_gd_image = imagecreatetruecolor($thumbnail_image_width, $thumbnail_image_height);

    imagecopyresampled($thumbnail_gd_image, $source_gd_image, 0, 0, 0, 0,$thumbnail_image_width, $thumbnail_image_height, $source_image_width, $source_image_height);

    所以新代码将是:

    $thumbnail_gd_image = imagecreatetruecolor($thumbnail_image_width, $thumbnail_image_height);

    // 保持透明度

    如果($ext = 'gif' || $ext = 'png') {

    imagecolortransparent($thumbnail_gd_image, imagecolorallocatealpha($thumbnail_gd_image, 0, 0, 0, 127));
    imagealphablending($thumbnail_gd_image, false);
    imagesavealpha($thumbnail_gd_image, true);
    

    }

    imagecopyresampled($thumbnail_gd_image, $source_gd_image, 0, 0, 0, 0, $thumbnail_image_width, $thumbnail_image_height, $source_image_width, $source_image_height);

    【讨论】:

      【解决方案3】:

      我没有答案(我认为@Ihson 已经给出了答案),但有一个建议。

      而不是:

      switch ($img_arr['mime'])
      {
          case 'image/gif': $ext = 'gif';
              break;
      
          case 'image/png': $ext = 'png';
              break;
      
          case 'image/jpeg': $ext = 'jpg';
              break;
      
          case 'image/pjpeg': $ext = 'jpg';
              break;
      
          case 'image/x-png': $ext = 'png';
              break;
      
          default: return false;
      }
      
      // (...)
      
      switch ($source_image_type)
      {
          case IMAGETYPE_GIF:
              $source_gd_image = imagecreatefromgif($source_image_path);
              break;
      
          case IMAGETYPE_JPEG:
              $source_gd_image = imagecreatefromjpeg($source_image_path);
              break;
      
          case IMAGETYPE_PNG:
              $source_gd_image = imagecreatefrompng($source_image_path);
              break;
      }
      

      我建议你使用:

      $string = file_get_contents($source_image_path);
      $img = @imagecreatefromstring($string);
      if ($img === false) {
           // something went wrong...
      } else {
           // do what you want with $img
      }
      

      这是在讨论使用@ 运算符,但在这种情况下,至少有两个原因:

      • 编写/测试/维护的代码更少
      • mime 类型可能有误(如果我将 .jpg 重命名为 .png)。

      【讨论】: