【问题标题】:PHP: Changing the image quality when condition is met?PHP:满足条件时更改图像质量?
【发布时间】:2012-09-15 10:58:04
【问题描述】:

我有一个 php 脚本,用户可以在其中上传图片。 如果文件大小大于“X”kbytes,我想让脚本降低图像质量(jpeg)。

类似这样的:

if( $_FILES['uploaded_img']['size'] > $file_size_limit ){
     // code that lowers the quality of the uploaded image but keeps the image width and height
}

最好的方法是什么?

ps:我不想改变图片的宽度和高度。

【问题讨论】:

  • 了解图像功能:php.net/manual/en/ref.image.php 您可以使用imagejpeg 将图像保存为另一种质量,但您不会知道原始质量。
  • 是的,我想我无法判断图像质量。这就是为什么我只会在文件大小超过一定限制时运行这段代码。

标签: php


【解决方案1】:

当然可以。做这样的事情。

$upload = $_FILES['uploaded_img'];
$uploadPath = 'new/path/for/upload/';
$uploadName = pathinfo($upload['name'], PATHINFO_FILENAME);
$restrainedQuality = 75; //0 = lowest, 100 = highest. ~75 = default
$sizeLimit = 2000;

if($upload['size'] > $sizeLimit) {
    //open a stream for the uploaded image
    $streamHandle = @fopen($upload['tmp_name'], 'r');
    //create a image resource from the contents of the uploaded image
    $resource = imagecreatefromstring(stream_get_contents($streamHandle));

    if(!$resource)
        die('Something wrong with the upload!');

    //close our file stream
    @fclose($streamHandle);

    //move the uploaded file with a lesser quality
    imagejpeg($resource, $uploadPath . $uploadName . '.jpg', $restrainedQuality); 
    //delete the temporary upload
    @unlink($upload['tmp_name']);
} else {
    //the file size is less than the limit, just move the temp file into its appropriate directory
    move_uploaded_file($upload['tmp_name'], $uploadPath . $upload['name']);
}

这将接受 PHP GD 支持的任何图像格式(假设它已安装在您的服务器上。很可能是)。如果图片小于限制,它只会将原始图片上传到您指定的路径。

【讨论】:

  • WOW 从未想过这在 PHP 中会如此简单。谢谢。
  • 没问题。很高兴我能帮上忙。
  • 我知道这与我的问题没有直接关系,但是否有必要“取消链接”临时文件???服务器不会自动为我做吗?
  • 是的,服务器会自动完成。但是,当您可以选择执行该脚本时,为什么要同时在服务器上有两个图像实例呢?
  • 这个脚本看起来不错,只是它没有解决它试图解决的问题。原始图像可能太大,因为图像太大,在这种情况下,重新采样并不能解决问题,甚至可能使问题变得更糟。最起码,在重采样之后,新的字节大小应该与原来的大小进行比较,并且只有在更好的情况下才使用。
【解决方案2】:

您的基本方法(在 Austin 的回答中实施)有时会奏效,但请务必记住 quality != file size。虽然它们通常是相关的,但完全有可能(甚至很常见)降低 jpeg 文件的质量实际上会导致文件更大。这是因为任何上传到您系统的 JPEG 都已经通过了 JPEG 压缩公式(通常质量为 79 或 80)。根据原始图像,此过程将创建伪影/更改结果图像。当您通过 jpeg 压缩算法再次运行这个已经优化的图像时,它不会“知道”原始图像的样子......所以它将传入的 jpeg 视为一个全新的无损文件并尝试复制它尽可能接近...包括在原始过程中创建的任何工件。再加上原始 jpeg 压缩已经利用了大多数“简单”压缩技巧的事实,最终很可能第二次压缩会导致看起来更糟糕的图像(复制问题的副本)但不会更小文件。

我做了一些测试来查看截止点在哪里,不出所料,如果原始图像具有低压缩比 (q=99),则在重新压缩到 q=75 时会节省大量空间。如果原始文件以 q=75 压缩(对于图形程序默认值来说很常见),那么二次 q=75 压缩看起来更糟,但实际上导致的文件大小与原始文件大小相同。如果原件的压缩级别较低(q=50),那么二次 q=75 压缩会导致文件显着变大(对于这些测试,我使用了三张复杂的照片……显然,具有特定口味/成分的图像会有不同的表现通过这些压缩)。 注意:我正在使用 Fireworks cs4 进行此测试...我意识到这些 quality indicators have no standardization between platforms

如下面的 cmets 所述,从 PNG 等文件格式迁移到 JPEG 通常最终会显着变小(尽管没有任何透明度),但是从 JPEG -> JPEG(或 GIF->JPEG,尤其是对于简单或小型的 -味觉图像)通常无济于事。

无论如何,您仍然可以尝试使用 Austin 描述的压缩方法,但请确保在完成后比较两个图像的文件大小。如果只有很小的增量增益或新文件较大,则默认返回原始图像。

【讨论】:

  • 好吧,我在这里唯一的目标是防止用户上传大量图像文件,这是我迄今为止找到的唯一解决方案
  • 您对 JPEG 的实例是正确的,但是转换 png -> jpg 通常会产生很大的大小差异。
  • 是的。不仅如此,我还尝试将此代码与具有透明背景的 png 一起使用,新的 jpeg 全部搞砸了。但这仍然比简单地告诉用户他们必须压缩图像而不做任何事情要好。
  • 是的,jpeg 不支持透明度,但从 PNG->jpeg 迁移通常会节省成本...只要确保您正在检查压缩结果以确保它能给您带来显着的效果足够的节省来证明损失是合理的。
猜你喜欢
  • 1970-01-01
  • 2014-09-02
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-09
相关资源
最近更新 更多