【问题标题】:Image color ruined while resizing it using imagecopyresampled使用 imagecopyresampled 调整大小时图像颜色损坏
【发布时间】:2016-04-13 17:31:34
【问题描述】:

将图片上传到我的网站后,正在调整图片大小。我正在使用imagecreatefromjpegimagecopyresampled 函数。我注意到颜色与原始图像中的颜色不同。

在这里您可以看到不同之处。您可以从我的网站上看到具有正确颜色的闪烁图像和图像背后的图像。

原图:https://c2.staticflickr.com/6/5754/23693488109_74c67f012a_k.jpg

调整大小后: https://www.isrart.co.il/img/uploads/art/viewer/big/photo-2b971e861c7aa2c57b8f7667ec666c3d.jpg

这是我的 PHP 代码:

    $type = @getImageSize($_FILES['photo']['tmp_name'])[2];
    switch ($type) { 
        case 1 : 
            $img = imageCreateFromGif($_FILES['photo']['tmp_name']); 
        break; 
        case 2 : 
            $img = imageCreateFromJpeg($_FILES['photo']['tmp_name']); 
        break; 
        case 3 : 
            $img = imageCreateFromPng($_FILES['photo']['tmp_name']); 
        break; 
        case 6 : 
            $img = imageCreateFromBmp($_FILES['photo']['tmp_name']); 
        break; 
    }    

    $orig_width = imagesx($img);
    if($orig_width < $width)
        return $img;

    $orig_height = imagesy($img);

    $height = (($orig_height * $width) / $orig_width);

    $new_image = imagecreatetruecolor($width, $height);

    imagecopyresampled($new_image, $img, 0, 0, 0, 0, $width, $height, $orig_width, $orig_height);

    imagejpeg($new_image, $_SERVER['DOCUMENT_ROOT'] . "/img/uploads/" . $path, 100);

【问题讨论】:

  • 你去看看 cmets 吧,它可能会有所帮助php.net/manual/en/function.imagecreatefromjpeg.php
  • 请发布实际的原始图像和重新采样的图像 - 而不是它们的图片。
  • @zod 有没有让你印象深刻的?我从手册页浏览了 cmets,但只有几个可能与此问题相关,而且大多数都已使用多年,以至于它们的持续有效性值得怀疑。
  • 这是因为压缩 - 即使在 100% 质量下,由于 jpeg 的工作方式,它也会通过压缩 - 它们不是无损的。 stackoverflow.com/questions/2345605/… - 请查看此线程。您应该考虑为此迁移到 PNG,因为 PNG 是一种无损格式。您也可以查看stackoverflow.com/questions/7421200/… 了解更多详情。

标签: php image gd


【解决方案1】:

您的原始图像有一个 560 字节的 ICC 配置文件与之关联,而您重新采样的图像没有。

您可以像这样使用 ImageMagick 从原始图像中提取配置文件:

convert orig.jpg profile.icm

如果我区分这两个文件,你可以在这里看到它:

我注意到,如果我在命令行中使用 ImageMagick 重新采样您的原始图像,如下所示:

convert orig.jpg -resize 1110x1570! myresampled.jpg

然后 ICC 配置文件将被结转。我可以这样检查:

identify -verbose orig.jpg myresampled.jpg | grep -i profile

  Profiles:
    Profile-icc: 560 bytes
  Profiles:
    Profile-icc: 560 bytes

【讨论】:

  • 谢谢,但是如何在 PHP 中使用它?
  • 很简单,这里有例子...php.net/manual/en/imagick.resizeimage.php
  • 有没有办法使用 PHP 的 GD 库来做到这一点,而无需安装 ImageMagick?最初的问题没有引用 ImageMagick,总的来说,除非绝对必要,否则我不愿意使用需要安装新软件包的解决方案。
【解决方案2】:

扩展@Mark Setchell 的回答:

使用此文件将原始图像的 ICC 配置文件复制到调整大小的图像的 ICC 配置文件。比问题解决了。它是一个没有任何依赖关系的单个文件。

https://github.com/slavicv/jpeg-icc/blob/master/class.jpeg_icc.php

对于我的用例,我编辑了文件,因此它适用于内存中不使用文件系统的图像。

【讨论】:

    【解决方案3】:

    我确定这是一个 PNG 文件,其中有一个名为“gAMA”的信息块。这是一种伽玛校正,有些观众使用它,有些则不使用。加载图像时,GD 库会忽略此信息。但 Imagick 应该可以解决问题:

    http://php.net/manual/en/imagick.getimageproperties.php

    希望这会有所帮助。

    【讨论】:

    • 原图是JPG :S
    【解决方案4】:

    与原始图像相比,压缩图像看起来暗淡的原因是它的颜色格式。原始使用 4:4:4 色度子采样,而压缩后使用 4:2:0 子采样。这会导致颜色信息丢失。

    为了克服这个问题,我们可以使用 ffmpeg 或 avconv 进行缩放,并且可以在 PHP 中从 shell 执行。

    我使用 avconv 和以下 2 个命令制作了高质量的缩放图像。

    avconv -i Input.jpg -pix_fmt yuvj444p -vf scale=1110:1570 Output.yuv
    
    avconv -y -s 1110x1570 -f rawvideo -pix_fmt yuv444p -i Output.yuv Output.jpg
    

    【讨论】:

      猜你喜欢
      • 2014-06-02
      • 2013-06-08
      • 2014-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 2011-06-05
      相关资源
      最近更新 更多