简体   繁体   English

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

[英]PHP - transparency issue on smaller images

So I'm using a method for re-sizing images that I came across on here the other day and it works great for the initial image it processes but I use the process a second time to create a smaller image to use for a thumb nail. 因此,我正在使用一种方法来重新调整前几天在这里遇到的图像的大小,该方法对于它处理的初始图像效果很好,但是我第二次使用该方法来创建较小的图像以用于指甲。 When this second thumb nail is created it comes out with a black background where it should be transparent. 当第二个指甲被创建时,它带有黑色背景,应该是透明的。 I know this is a common problem as I have seen plenty of threads on here with similar complaints. 我知道这是一个普遍的问题,因为我在这里看到许多类似投诉的话题。 When I was looking last night in the php error logs it was saying that imagecolorat was trying to hit pixels which were out of bounds..... 当我昨晚在php错误日志中查找内容时,它说imagecolorat试图击中超出范围的像素.....

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

At least I know whats happening but what I need to know now is how to fix it. 至少我知道发生了什么,但是我现在需要知道的是如何解决它。 Its really strange that for the larger copy of the same image I dont get this error at all and it works just fine producing a nice copy of the larger uploaded copy. 真奇怪,对于同一张图片的较大副本,我根本没有收到此错误,并且可以很好地生成较大上传副本的副本。 Heres the code that Im using to resize everything: 这是Im用于调整大小的代码:

 $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);

Like I said everything works fine for the first run but for some reason on the second run it farts and throws a out of bounds error. 就像我说的那样,第一次运行一切正常,但由于某种原因,第二次运行放屁并抛出界外错误。 it starts at 0,28 and goes on until the end of the loop process at 50,50 它从0,28开始,一直持续到50,50的循环过程结束

我弄清楚了:)我拿起上面创建了alpha正确副本的代码,并将其全部转换为自己的函数,现在一切正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM