2

我有一个 php 脚本,用户可以在其中上传图片。如果文件大小大于“X”千字节,我想让脚本降低图像质量(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:我不想改变图像的宽度和高度。

4

2 回答 2

4

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

$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 支持的任何图像格式(假设它已安装在您的服务器上。很可能是)。如果图像小于限制,它只会将原始图像上传到您指定的路径。

于 2012-09-24T00:20:39.107 回答
4

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

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

正如下面评论中所指出的,从 PNG 等文件格式迁移到 JPEG 通常最终会明显变小(尽管没有任何透明度),但是从 JPEG -> JPEG(或 GIF->JPEG,特别是对于简单或小尺寸图像)往往无济于事。

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

于 2012-09-24T01:08:02.407 回答