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

发布于 2024-12-21 17:43:08 字数 7576 浏览 4 评论 0原文

因此,我正在使用前几天在这里遇到的一种重新调整图像大小的方法,它对于它处理的初始图像非常有效,但我第二次使用该过程来创建一个较小的图像以用于缩略图。当创建第二个缩略图时,它会出现黑色背景,而它应该是透明的。我知道这是一个常见问题,因为我在这里看到过很多有类似抱怨的帖子。当我昨晚查看 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 结束

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 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:

 $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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酒浓于脸红 2024-12-28 17:43:08

我想通了:)我把上面的代码创建了alpha正确的副本,并将其全部变成了它自己的函数,现在它工作得很好。

I figured it out :) I took the code I had up above that created the alpha correct copy and turned it all into its own function and now it works just fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文