не добавляет белый фон в прозрачный PNG - PullRequest
0 голосов
/ 24 февраля 2012

Ну, у меня небольшая проблема.Мой скрипт проходит через каталог на основе URL-запроса.При этом он создает эскизы для этих изображений.Теперь проблема в том, что он создает миниатюры в формате PNG, но вместо прозрачного или хотя бы белого фона он вставляет стандартный черный цвет.

Вот код, который может указать на мою проблему в коде, или что-то, что я, возможно, пропустил

<?php

$folder = $_GET['folder']; //POST if from form, GET if from URL
$thisdir = getcwd();
if(!file_exists($thisdir ."/"."$folder/thumbs")) {
    mkdir($thisdir ."/"."$folder/thumbs" , 0777);
}

function returnimages($dirname="") {

    $pattern="(\.jpg$)|(\.png$)|(\.jpeg$)|(\.gif$)"; //valid image extensions
    $handle  = opendir($dirname);
    while(false !== ($filename = readdir($handle))) {
        if(eregi($pattern, $filename)){ //if this file is a valid image
            $files[] = $filename;
        }
    }
    if (count($files)<>0) {
        sort($files);
    }

    $curimage=0;

    while($curimage !== count($files)){
        $cropfile=$dirname.'/'.$files[$curimage];echo '<br>'.$cropfile;

         if(preg_match('/[.](jpg)|(jpeg)$/', $cropfile)) {
             $source_img = imagecreatefromjpeg($cropfile);
         } elseif(preg_match('/[.](png)$/', $cropfile)) {
             imagealphablending($source_img, false);
             imagesavealpha($source_img, true);
             $source_img = imagecreatefrompng($cropfile);
         } elseif(preg_match('/[.](gif)$/', $cropfile)) {
             $source_img = imagecreatefromgif($cropfile);
         } else {
             echo "Code 43: Unable to read file type.";
             exit(0);
         }

        if (!$source_img) {
            echo "could not create image handle";
            exit(0);
        }
        $new_w = 480;
        $new_h = 480;

        $orig_w = imagesx($source_img);
        $orig_h = imagesy($source_img);

        $w_ratio = ($new_w / $orig_w);
        $h_ratio = ($new_h / $orig_h);

        if ($orig_w > $orig_h ) {//landscape from here new
            $crop_w = round($orig_w * $h_ratio);
            $crop_h = $new_h;
            $src_x = ceil( ( $orig_w - $orig_h ) / 2 );
            $src_y = 0;
        } elseif ($orig_w < $orig_h ) {//portrait
            $crop_h = round($orig_h * $w_ratio);
            $crop_w = $new_w;
            $src_x = 0;
            $src_y = ceil( ( $orig_h - $orig_w ) / 2 );
        } else {//square
            $crop_w = $new_w;
            $crop_h = $new_h;
            $src_x = 0;
            $src_y = 0;
        }
        $dest_img = imagecreatetruecolor($new_w,$new_h);
        imagecopyresampled($dest_img, $source_img, 0 , 0 , $src_x, $src_y, $crop_w, $crop_h, $orig_w, $orig_h); //till here
        if(imagejpeg($dest_img, $dirname."/thumbs/".$files[$curimage], 80)) {
            imagedestroy($dest_img);
            imagedestroy($source_img);
        } else {
            echo "could not make thumbnail image";
            exit(0);
        }
        $curimage++;
    }
}
returnimages($name=$folder);

?>

1 Ответ

0 голосов
/ 25 февраля 2012

Это потому, что вы используете imagejpeg в качестве функции вывода для всех возможных типов изображений.Я изменил ваш код в цикле while, чтобы он работал:

// Add these defines somewhere at the top
define('TYPE_JPEG', 0);
define('TYPE_PNG', 1);
define('TYPE_GIF', 2);

// ... skipping some code. Here goes while loop iterating over every image
while($curimage !== count($files)){
    $cropfile=$dirname.'/'.$files[$curimage];echo '<br>'.$cropfile;

     // Determine type of the image
     if(preg_match('/[.](jpg)|(jpeg)$/', $cropfile)) {
         $source_img = imagecreatefromjpeg($cropfile);
         $type = TYPE_JPEG;
     } elseif(preg_match('/[.](png)$/', $cropfile)) {
         $source_img = imagecreatefrompng($cropfile);
         $type = TYPE_PNG;
     } elseif(preg_match('/[.](gif)$/', $cropfile)) {
         $source_img = imagecreatefromgif($cropfile);
         $type = TYPE_GIF;
     } else {
         echo "Code 43: Unable to read file type.";
         exit(0);
     }

    if (!$source_img) {
        echo "could not create image handle";
        exit(0);
    }
    $new_w = 480;
    $new_h = 480;

    $orig_w = imagesx($source_img);
    $orig_h = imagesy($source_img);

    $w_ratio = ($new_w / $orig_w);
    $h_ratio = ($new_h / $orig_h);

    if ($orig_w > $orig_h ) {//landscape from here new
        $crop_w = round($orig_w * $h_ratio);
        $crop_h = $new_h;
        $src_x = ceil( ( $orig_w - $orig_h ) / 2 );
        $src_y = 0;
    } elseif ($orig_w < $orig_h ) {//portrait
        $crop_h = round($orig_h * $w_ratio);
        $crop_w = $new_w;
        $src_x = 0;
        $src_y = ceil( ( $orig_h - $orig_w ) / 2 );
    } else {//square
        $crop_w = $new_w;
        $crop_h = $new_h;
        $src_x = 0;
        $src_y = 0;
    }
    $dest_img = imagecreatetruecolor($new_w,$new_h);
    $dest_path = $dirname."/thumbs/".$files[$curimage];
    switch ($type) {
        case TYPE_JPEG:
            imagecopyresampled($dest_img, $source_img, 0 , 0 , $src_x, $src_y, $crop_w, $crop_h, $orig_w, $orig_h);
            $success = imagejpeg($dest_img, $dest_path, 80);
            break;

        case TYPE_PNG:
            // Preserve alpha
            imagesavealpha($dest_img, true);
            // Create transparent color
            $color = imagecolorallocatealpha($dest_img, 0, 0, 0, 127);
            // Fill in background
            imagefill($dest_img, 0, 0, $color);
            // Copy from source
            imagecopyresampled($dest_img, $source_img, 0 , 0 , $src_x, $src_y, $crop_w, $crop_h, $orig_w, $orig_h);
            $success = imagepng($dest_img, $dest_path);
            break;

        default:
            $black = imagecolorallocate($dest_img, 0, 0, 0);
            // This will make the background transparent
            imagecolortransparent($dest_img, $black);
            // Copy from source
            imagecopyresampled($dest_img, $source_img, 0 , 0 , $src_x, $src_y, $crop_w, $crop_h, $orig_w, $orig_h);
            $success = imagegif($dest_img, $dest_path);
            break;
    }
    if($success) {
        imagedestroy($dest_img);
        imagedestroy($source_img);
    } else {
        echo "could not make thumbnail image";
        exit(0);
    }
    $curimage++;
}

Как видите, в зависимости от типа файла мы используем различные функции вывода: imagejpeg , imagepng и imagegif .Файлы PNG и GIF требуют дополнительных действий для сохранения прозрачности.Я протестировал его на PHP 5.2.13 под Windows, используя файлы JPEG, GIF и PNG (прозрачные и обычные), и кажется, что все работает.Вы можете настроить дополнительные параметры, например, imagepng принимает необязательные параметры $quality и $filters.

Также в отношении кода:

  • Наиболее важныеправило: не доверяйте пользовательскому вводу.Вы создаете каталоги в зависимости от значения $_GET, это может быть небезопасно, так как пользователь может передать что-то вроде '/../../../../etc'
  • Некоторая очистка выигранане больно.Используйте foreach вместо while со счетчиком цикла.Я думаю, glob может получить список файлов.И returnimages($name=$folder); звонок не имеет смысла для меня.Вам действительно нужно назначить и позвонить в одну линию?
...