使用 PHP 生成缩略图会导致图像质量较差

发布于 2024-07-08 17:22:38 字数 974 浏览 10 评论 0原文

$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=''>";

上面的代码给了我一个缩略图,这很棒,但图像质量很糟糕。 图像看起来颜色颠倒了,而且看起来像是被压扁了。 我做这个一整天都头疼。 有人有主意吗?

$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=''>";

The above code gives me a thumbnail and that's great, but the image quality is awful. It looks like the image has had the colours inverted and it looks like it has been squashed. I've had headaches all day doing this. Any one have any ideas?

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

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

发布评论

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

评论(3

烟花易冷人易散 2024-07-15 17:22:38

使用 imagecreatetruecolor 而不是 imagecreate 和 imagecopyresampled 而不是 imagecopyresized。

Use imagecreatetruecolor instead of imagecreate and imagecopyresampled instead of imagecopyresized.

青柠芒果 2024-07-15 17:22:38

正如多米尼克指出的那样,第三个参数值得包括在内。 它指定 jpeg 质量。

关于“它看起来像是被压扁了”的问题,请记住,您正在从源图像制作一个方形缩略图,该缩略图本身可能是方形的,也可能不是方形的。

解决此问题的一种方法是使用源尺寸来计算出全宽或全高(取决于图像是纵向还是横向)正方形以从源复制。 这意味着用动态计算的内容替换 imagecopyresized() 参数中的“0,0,0,0”。

(编辑:示例)

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

The third parameter is worth including as Dominic points out. It specifies the jpeg quality.

On the issue of "and it looks like it has been squashed", remember, you're making a square thumbnail from a source image which itself may or may not be square.

One way to get around this is to work with the source dimensions to work out a full width or full height (depending on whether the image is portrait or landscape) square to copy from the source. This means replacing the "0,0,0,0" in your arguments to imagecopyresized() with something dynamically calculated.

(EDIT: example)

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);
}
不美如何 2024-07-15 17:22:38

尝试:

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

Try:

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