Создание миниатюр с использованием PHP приводит к плохому качеству изображения - PullRequest
0 голосов
/ 18 ноября 2008
$sourcePath = 'images/'; // Path of original image
$sourceUrl = '';
$sourceName = 'photo1.jpg'; // Name of original image
$thumbPath = 'thumbs/'; // Writeable thumb path
$thumbUrl = 'thumbs/';
$thumbName = "test_thumb.jpg"; // Tip: Name dynamically
$thumbWidth = 100; // Intended dimension of thumb

// Beyond this point is simply code.
$sourceImage = imagecreatefromjpeg("$sourcePath/$sourceName");
$sourceWidth = imagesx($sourceImage);
$sourceHeight = imagesy($sourceImage);

$targetImage = imagecreate($thumbWidth,$thumbWidth);
imagecopyresized($targetImage,$sourceImage,0,0,0,0,$thumbWidth,$thumbWidth,imagesx($sourceImage),imagesy($sourceImage));
imagejpeg($targetImage, "$thumbPath/$thumbName");

// By now, the thumbnail is copied into the $thumbpath
// as the file name specified in $thumbName, so display
echo "<img src='$thumbUrl$thumbName' alt=''>";

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

Ответы [ 3 ]

18 голосов
/ 18 ноября 2008

Используйте imagecreatetruecolor вместо imagecreate и imagecopyresampled вместо imagecopyresized.

7 голосов
/ 18 ноября 2008

Третий параметр стоит включить, как указывает Доминик. Это определяет качество JPEG.

Что касается вопроса "и похоже, что он был раздавлен", помните, что вы делаете квадратный эскиз из исходного изображения, которое само может быть или не быть квадратным.

Один из способов обойти это - работать с исходными размерами, чтобы получить квадрат шириной или высотой (в зависимости от того, является ли изображение книжным или альбомным) квадратным для копирования из источника. Это означает замену «0,0,0,0» в ваших аргументах для imagecopyresized () чем-то динамически вычисляемым.

(РЕДАКТИРОВАТЬ: пример)

function makeSquareThumb($srcImage, $destSize, $destImage = null) {
    //I'm sure there's a better way than this, but it works...
    //I don't like my folder and file checking in the middle, but need to illustrate the need for this. 

    $srcFolder = dirname($srcImage); //source folder
    $srcName = basename($srcImage); //original image filename

    //the IF ELSEIF ELSE below is NOT comprehensive - eg: what if the dest folder is the same as the source?
    //writeable nature of the destination is not checked!
    if(!destImage) {
        $destFolder = $srcFolder.'/thumbs/';
        if(!is_dir($destFolder)) {
            //make the thumbs folder if there isn't one!
            mkdir($destFolder);
        }
        $destImage = $destFolder.$srcName;
    } elseif (is_dir($destImage)) {
        $destFolder = $destImage;
        $destImage = $destFolder.'/'.$srcName;
    } else {
        $destFolder = dirname($destImage);
    }


    //Now make it!
    $srcCanvas = imagecreatefromjpeg($srcImage);
    $srcWidth = imagesx($srcCanvas);
    $srcHeight = imagesy($srcCanvas);

    //this let's us easily sample a square from the middle, regardless of apsect ratio.
    $shortSide = array($srcWidth,$srcHeight);
    sort($shortSide);

    $src_x = $srcWidth/2 - $shortSide[0]/2;
    $src_y = $srcHeight/2 - $shortSide[0]/2;

    //do it!
    $destCanvas = imagecreatetruecolor($destSize, $destSize);
    imagecopyresampled($destCanvas,$srcCanvas,0,0,$src_x,$src_y,$destSize,$destSize,$shortSide[0],$shortSide[0]);
    imagejpeg($destCanvas, $destImage);
}
1 голос
/ 18 ноября 2008

Попробуйте:

imagejpeg($targetImage, "$thumbPath/$thumbName", 100);
...