如何阻止 GD2 在调整图像大小时洗掉颜色? [英] How to stop GD2 from washing away the colors upon resizing images?

查看:25
本文介绍了如何阻止 GD2 在调整图像大小时洗掉颜色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 CodeIgniter 1.7 开发了一个照片共享社区网站.成员上传的照片会自动调整为多种格式,为此我使用了 CodeIgniter Image Manipulation 类.此类内置于框架中,基本上是围绕多个图像处理库(例如 GD、GD2、ImageMagick 和 NETPBM)的包装器.在我的主机上,我只能使用 GD2,所以这就是这个问题的所在.

解决我的问题.这是我网站上调整大小的照片的示例.请注意,原始文件非常大,宽度超过 3000 像素:

更新 2:我很震惊.以一种好的方式.安装ImageMagick花了我很多痛苦,但是切换到它之后(这是将'imagemagick'设置为在Code Igniter图像处理类中使用的库的问题,测试图像的结果如下:

ImageMagick 的大小调整完全符合预期.保留了颜色,锐度也在那里.是的,我禁用了我的自定义锐化程序,因为 ImageMagick 不再需要它.最重要的是,这个过程要快得多,而且内存消耗也更少.这是另一个重要部分:我无法解释它,但我绝对没有告诉 ImageMagick 使用用户@Alix 建议的特定颜色配置文件.到目前为止,在我的测试中,无论有没有嵌入的配置文件,颜色信息都得到了尊重.输出只是输入的较小版本.ImageMagick 真的那么聪明还是我在做梦?

解决方案

我已经设法用 Imagick 进一步测试:

图像的左半部分使用 Imagick 和 sRGB_IEC61966-2-1_no_black_scaling.icc 颜色配置文件,右半部分没有关联的颜色配置文件,如果使用 Imagick 或 GD 处理,则显示完全相同;这是我使用的代码:

header('Content-type: image/jpeg');$image = new Imagick('/path/to/DSC07275.jpg');if (($srgb = file_get_contents('http://www.color.org/sRGB_IEC61966-2-1_no_black_scaling.icc')) !== false){$image->profileImage('icc', $srgb);$image->setImageColorSpace(Imagick::COLORSPACE_SRGB);}$image->thumbnailImage(1024, 0);回声$图像;

<小时>

以下是 color.org 网站上提供的几种 sRGB 配置文件的比较:

在我看来,第三个配置文件产生了最生动的结果,除此之外我不知道人们会如何做出明确的选择.

<小时>

编辑:显然,Imagick 附带了一个捆绑的 sRGB 配置文件,因此您无需从 Image Color Consortium 网站下载该配置文件,以下代码应该可以处理所有情况:

header('Content-type: image/jpeg');$image = new Imagick('/path/to/DSC07275.jpg');$version = $image->getVersion();$profile = 'http://www.color.org/sRGB_IEC61966-2-1_no_black_scaling.icc';if ((is_array($version) === true) && (array_key_exists('versionString', $version) === true)){$version = preg_replace('~ImageMagick ([^-]*).*~', '$1', $version['versionString']);if (is_file(sprintf('/usr/share/ImageMagick-%s/config/sRGB.icm', $version)) === true){$profile = sprintf('/usr/share/ImageMagick-%s/config/sRGB.icm', $version);}}if (($srgb = file_get_contents($profile)) !== false){$image->profileImage('icc', $srgb);$image->setImageColorSpace(Imagick::COLORSPACE_SRGB);}$image->thumbnailImage(1024, 0);回声$图像;

I have developed a photo sharing community site using CodeIgniter 1.7. Photos that are uploaded by members are automatically resized in a number of formats, for which I use the CodeIgniter Image Manipulation class. This class is built into the framework and basically a wrapper around multiple image manipulation libraries, such as GD, GD2, ImageMagick, and NETPBM. On my host, I can only make use of GD2, so that's where this question will be about.

On to my problem. Here is an example of a resized photo on my site. Note that the original was very large, over 3000px wide:

http://www.jungledragon.com/image/195/female_impala_close-up.html

Now, look at that same image, also resized, just a bit larger at Flickr:

http://www.flickr.com/photos/fledder/3763538865/in/set-72157621744113979

See the dramatic difference? I'm trying to bridge that huge gap. The first thing I did was to apply a sharpen filter to the images. You can see the result here:

Although still not perfect, it at least approaches the sharpness level of the Flickr image. The remaining problem is that the colors are washed away, as if their saturation is decreased. This happens before the sharpening filter already, so it must be in GD2.

This issue is vitally important to me, but I don't know where to look. I've found some .NET threads talking about chroma sub sampling but I don't know what to do with that information in my setup. I'm looking for any solution that works within the constraints of my setup.

Update: Hereby the original file, exactly as I uploaded it both to my site and Flickr:

http://www.jungledragon.com/img/DSC07275.jpg

Update 2: I'm shocked. In a good way. It took me a lot of pain to install ImageMagick but after switching to it (which was a matter of setting 'imagemagick' as the library to use at the Code Igniter image manipulation class, the result of the test image is as follow:

ImageMagick's resizing is doing it exactly as intended. The colors are preserved, and the sharpness is there. Yes, I disabled my custom sharpening routine since it is no longer needed due to ImageMagick. On top of that, the process is a lot faster and less memory hungry too. And here comes another great part: I cannot explain it, but I did absolutely nothing to tell ImageMagick to use a specific color profile, which was suggested by user @Alix. In my testing so far it looks like the color information is respected with or without an embedded profile. The output simply is a smaller version of the input. Is ImageMagick really that smart or am I dreaming?

解决方案

I've managed to further test this with Imagick:

The left half of the image was processed with Imagick and the sRGB_IEC61966-2-1_no_black_scaling.icc color profile, the right half has no color profile associated and shows exactly the same if processed with Imagick or GD; here is the code I used:

header('Content-type: image/jpeg');

$image = new Imagick('/path/to/DSC07275.jpg');

if (($srgb = file_get_contents('http://www.color.org/sRGB_IEC61966-2-1_no_black_scaling.icc')) !== false)
{
    $image->profileImage('icc', $srgb);
    $image->setImageColorSpace(Imagick::COLORSPACE_SRGB);
}

$image->thumbnailImage(1024, 0);

echo $image;


Here is a comparison of the several sRGB profiles available on the color.org website:

It seems to me that the third profile produces the most vivid results, other than that I have no idea how one would make a definitive choice.


EDIT: Apparently, Imagick comes with a bundled sRGB profile, so you don't need to download the one from the Image Color Consortium website, the following code should handle all scenarios:

header('Content-type: image/jpeg');

$image = new Imagick('/path/to/DSC07275.jpg');
$version = $image->getVersion();
$profile = 'http://www.color.org/sRGB_IEC61966-2-1_no_black_scaling.icc';

if ((is_array($version) === true) && (array_key_exists('versionString', $version) === true))
{
    $version = preg_replace('~ImageMagick ([^-]*).*~', '$1', $version['versionString']);

    if (is_file(sprintf('/usr/share/ImageMagick-%s/config/sRGB.icm', $version)) === true)
    {
        $profile = sprintf('/usr/share/ImageMagick-%s/config/sRGB.icm', $version);
    }
}

if (($srgb = file_get_contents($profile)) !== false)
{
    $image->profileImage('icc', $srgb);
    $image->setImageColorSpace(Imagick::COLORSPACE_SRGB);
}

$image->thumbnailImage(1024, 0);

echo $image;

这篇关于如何阻止 GD2 在调整图像大小时洗掉颜色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆