PHP - 较小图像上的透明度问题

时间:2011-12-18 22:31:20

标签: php image-processing transparency

所以我正在使用一种方法来重新调整我前几天在这里遇到的图像,它对于它处理的初始图像效果很好但我再次使用该过程创建一个较小的图像用于拇指钉。当第二个拇指指甲被创建时,它会出现黑色背景,它应该是透明的。我知道这是一个常见问题,因为我在这里看到了很多关于类似投诉的帖子。当我昨晚在php错误日志中查看时,有人说imagecolorat试图点击超出界限的像素.....

 PHP Notice:  imagecolorat(): 0,28 is out of bounds in C:\inetpub\

至少我知道发生了什么,但我现在需要知道的是如何解决它。它真的很奇怪,对于同一图像的较大副本,我根本不会得到这个错误,它可以很好地生成较大的上传副本的漂亮副本。下面是我用来调整所有内容的代码:

 $image_source = imagecreatefromstring($markericon); //original image

    $imgHead =  "image/jpeg"; //tag for image to be pulled later. images go in are png's

//code to make sure image is never larger than certain size
    $image_width =  imagesx($image_source);
    $image_height =     imagesy($image_source);


    if($image_width>$max_upload_large_side || $image_height >$max_upload_large_side){
        $proportionslarge = $image_width/$image_height;

        if($image_width>$image_height){
            $new_large_width = $max_upload_large_side;
            $new_large_height = round($max_upload_large_side/$proportionslarge);
        }       
        else{
            $new_large_height = $max_upload_large_side;
            $new_large_width = round($max_upload_large_side*$proportionslarge);
        }       

        $new_large_image = imagecreatetruecolor($new_large_width , $new_large_height);

//code used to retain image transparency


        //over write alpha chanel of image destination
        imagealphablending($new_large_image, false); // Overwrite alpha
        imagesavealpha($new_large_image, true);

        // Create a separate alpha channel to blend images with
        $alpha_image = imagecreatetruecolor($image_width, $image_height);
        imagealphablending($alpha_image, false); // Overwrite alpha
        imagesavealpha($alpha_image, true);

        //copy data at every pixel in image
        for ($x = 0; $x < $image_width; $x++) {
        for ($y = 0; $y < $image_height; $y++) {
        $alpha = (imagecolorat($image_source, $x, $y) >> 24) & 0xFF;
        $color = imagecolorallocatealpha($alpha_image, 0, 0, 0, $alpha);
        imagesetpixel($alpha_image, $x, $y, $color);
                                    }
                                    }

        // Resize image to destination, using gamma correction
        imagegammacorrect($image_source, 2.2, 1.0);
        imagecopyresampled($new_large_image, $image_source, 0, 0, 0, 0,  $new_large_width, $new_large_height, $image_width, $image_height);
        imagegammacorrect($new_large_image, 1.0, 2.2);

        // Resize alpha channel
        $alpha_resized_image = imagecreatetruecolor($new_large_width, $new_large_height);
        imagealphablending($alpha_resized_image, false);
        imagesavealpha($alpha_resized_image, true);

        imagecopyresampled($alpha_resized_image, $alpha_image, 0, 0, 0, 0, $new_large_width, $new_large_height, $image_width, $image_height);

        // Copy alpha channel back to resized image
        for ($x = 0; $x < $new_large_width; $x++) {
         for ($y = 0; $y < $new_large_height; $y++) {
         $alpha = (imagecolorat($alpha_resized_image, $x, $y) >> 24) & 0xFF;
         $rgb = imagecolorat($new_large_image, $x, $y);
         $r = ($rgb >> 16 ) & 0xFF;
         $g = ($rgb >> 8 ) & 0xFF;
         $b = $rgb & 0xFF;
         $color = imagecolorallocatealpha($new_large_image, $r, $g, $b, $alpha);
         imagesetpixel($new_large_image, $x, $y, $color);
             }
            }



        // end of first run//

        ob_start(); // Start capturing stdout.  
        imagePNG($new_large_image); 
        $lBinaryThumbnail = ob_get_contents(); // the raw jpeg image data.  
        ob_end_clean(); // Dump the stdout so it does not screw other output.
        $lBinaryThumbnail = addslashes($lBinaryThumbnail);
        imagedestroy($new_large_image);         
    } else $lBinaryThumbnail = $imgData;


//start of second image run
    if($image_width>$max_upload_small_side || $image_height >$max_upload_small_side){
        $proportionssmall = $image_width/$image_height;

        if($image_width>$image_height){
            $new_small_width = $max_upload_small_side;
            $new_small_height = round($max_upload_small_side/$proportionssmall);
        }       
        else{
            $new_small_height = $max_upload_small_side;
            $new_small_width = round($max_upload_small_side*$proportionssmall);
        }       

        $new_small_image = imagecreatetruecolor($new_small_width , $new_small_height);

         //////////////////////////////////////////////////////////////////////////////////

        //over write alpha chanel of image destination
        imagealphablending($new_small_image, false); // Overwrite alpha
        imagesavealpha($new_small_image, true);

        // Create a separate alpha channel to blend images with
        $alpha_image = imagecreatetruecolor($image_width, $image_height);
        imagealphablending($alpha_image, false); // Overwrite alpha
        imagesavealpha($alpha_image, true);

        //copy data at every pixel in image
        for ($x = 0; $x < $image_width; $x++) {
        for ($y = 0; $y < $image_height; $y++) {
        $alpha = (imagecolorat($image_source, $x, $y) >> 24) & 0xFF;
        $color = imagecolorallocatealpha($alpha_image, 0, 0, 0, $alpha);
        imagesetpixel($alpha_image, $x, $y, $color);
                                    }
                                    }

        // Resize image to destination, using gamma correction
        imagegammacorrect($image_source, 2.2, 1.0);
        imagecopyresampled($new_small_image, $image_source, 0, 0, 0, 0,  $new_small_width , $new_small_height, $image_width, $image_height);
        imagegammacorrect($new_small_image, 1.0, 2.2);

        // Resize alpha channel
        $alpha_resized_image = imagecreatetruecolor( $image_width, $image_height);
        imagealphablending($alpha_resized_image, false);
        imagesavealpha($alpha_resized_image, true);

        imagecopyresampled($alpha_resized_image, $alpha_image, 0, 0, 0, 0, $new_small_width ,$new_small_height, $image_width, $image_height);

        // Copy alpha channel back to resized image
        for ($x = 0; $x < $new_small_width; $x++) {
         for ($y = 0; $y < $new_small_height; $y++) {
         $alpha = (imagecolorat($alpha_resized_image, $x, $y) >> 24) & 0xFF;
         $rgb = imagecolorat($new_small_image, $x, $y); //this is the line that throws the error first and gives a out of bounds related error.
         $r = ($rgb >> 16 ) & 0xFF;
         $g = ($rgb >> 8 ) & 0xFF;
         $b = $rgb & 0xFF;
         $color = imagecolorallocatealpha($new_small_image, $r, $g, $b, $alpha);
         imagesetpixel($new_small_image, $x, $y, $color);
             }
            }



        // end of new code // 
        //imagecopyresampled($new_small_image, $image_source, 0, 0, 0, 0, $new_small_width, $new_small_height, $image_width, $image_height);

        ob_start(); // Start capturing stdout.  
        imagePNG($new_small_image); 
        $sBinaryThumbnail = ob_get_contents(); // the raw jpeg image data.  
        ob_end_clean(); // Dump the stdout so it does not screw other output.
        $sBinaryThumbnail = addslashes($sBinaryThumbnail);
        imagedestroy($new_small_image);         
    } else $sBinaryThumbnail = $lBinaryThumbnail;



    imagedestroy($image_source);

就像我说第一次运行时一切正常但是由于某种原因在第二次运行时它放弃并抛出一个超出界限的错误。它从0,28开始并一直持续到循环过程结束时为50,50

1 个答案:

答案 0 :(得分:0)

我想出来了:)我把上面的代码创建了alpha正确的副本并将其全部转换为自己的函数,现在它的工作正常。