PHP - проблема прозрачности на небольших изображениях - PullRequest
0 голосов
/ 19 декабря 2011

Так что я использую метод для изменения размера изображений, с которым я столкнулся здесь на днях, и он отлично работает для исходного изображения, которое он обрабатывает, но я использую этот процесс во второй раз, чтобы создать изображение меньшего размера для использования для ноготь большого пальца. Когда этот второй ноготь большого пальца создан, он выходит с черным фоном, где он должен быть прозрачным. Я знаю, что это распространенная проблема, поскольку я видел множество тем с подобными жалобами. Когда я смотрел вчера вечером в журналах ошибок 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 голосов
/ 19 декабря 2011

Я понял это :) Я взял приведенный выше код, который создал правильную альфа-копию, и превратил все это в свою собственную функцию, и теперь она работает просто отлично.

...