【问题标题】:PHP Imagick - convert image to greyscale (very bad result)PHP Imagick - 将图像转换为灰度(非常糟糕的结果)
【发布时间】:2012-11-12 21:41:24
【问题描述】:

我在用 PHP 做一些图像编辑,因为 GD 提供的功能较少,所以我切换到了 Imagick。

其中一个过程是灰度图像。在我将脚本上传到我的网络托管服务器(Linux、Imagick 3.0.1、6.2.8、2010-10-20、 Q16)。

我试图改变质量,但没有任何改善。

$img->setImageCompression(imagick::COMPRESSION_JPEG);
$img->setImageCompressionQuality(100);

这是来自 GD、Imagick 和 Photoshop 的结果

我认为版本 3.0.1 有问题。有人可以确认一下吗?

Q1:有没有其他方法可以使用Imagick 将图像转换为灰度?

Q2:是否可以将 GD 资源转换为 Imagick?所以我可以用imagefilter($img, IMG_FILTER_GRAYSCALE);得到正确的结果,然后用Imagick输出。

ps:对于 Q2,你可能会建议我只使用 GD 来处理图像。但问题是imagejpeg() 无法保存保留分辨率的图像。这实际上是我切换到 Imagick 的原因。

【问题讨论】:

  • 您使用什么代码通过 Imagick 转换为灰度?你在使用 $image->setColorspace(imagick::COLORSPACE_GRAY);看看这个stackoverflow.com/questions/4539307/…
  • 它是$img->modulateImage(100, 0, 100);,其中参数是(brightness, saturation, hue)。我相信它是正确使用的功能,而且它确实适用于 2.2.1 版本。
  • 仅仅因为它适用于特定版本并不意味着它是正确使用的功能。使用 Jeremy 提到的内容可以确保您的图片实际上是灰度的,即使是 JPEG 文件格式也是如此。你正在做的只是一个过滤器。 编辑: Google 上五分之三的搜索结果表明了 Jeremy 的方法。
  • 看起来是从 6.5.7 版本开始才有的,而且你服务器上的版本可能更旧。 modulateImage 应该可以工作,但显然不如它可以工作。 php.net/manual/en/imagick.setcolorspace.php
  • @Christian 来吧,你读过手册吗? modulateImage 确实是改变亮度,饱和度和色调的功能。为什么它不是正确使用的功能? 2.2.1 版产生与 Photoshop 几乎相同的结果。 3.0.1 的结果显然是错误的。

标签: php imagick gd2 grayscale


【解决方案1】:

这是我在 php/imagick 中制作黑白照片的首选方式:$im = $im->fxImage('intensity');

将函数应用于图像,其中强度等于0.299*red+0.587*green+0.114*blue

该公式基于我们的眼睛对不同颜色的敏感程度,因此它与“平面”灰度图像之间的区别实际上是白天和黑夜。

更多细节在这里:

【讨论】:

    【解决方案2】:

    您可以使用您喜欢的图像类,然后使用方法 readImageBlob 将其发送到 imagick http://www.php.net/manual/en/imagick.readimageblob.php

    【讨论】:

      【解决方案3】:

      参考这个网站并查看图片 Magick 操作员在这里找到www.rubblewebs.co.uk/imagemagick/

      也可以使用www.fmwconcepts.com/imagemagick/,您会在这里找到一些示例...

      【讨论】:

      • ImageMagick 和 Imagick 在这种情况下是完全不同的东西。我说的是编程,而不是桌面应用程序......
      【解决方案4】:
      function ImagickToGD($imagick){
          $tmpfile = tmpfile();
          $imagick->writeImage($tmpfile);
          return imagecreatefromstring(file_get_contents($tmpfile));
      }
      

      请注意,此函数不进行任何清理(临时文件除外,PHP 会自动清理该文件)。

      因此,例如,您的代码应如下所示:

      $img = new Imagick();
      // ...
      $gd = ImagickToGD($img);
      unset($img); // destroy imagick
      imagefilter($gd, IMG_FILTER_GRAYSCALE);
      imagejpeg($gd, $target_name, 100);
      imagedestroy($gd);
      

      另外,我不明白关于“保留分辨率”的部分。这些操作中没有任何与解析相关的内容。我猜你的意思是压缩?如果您想要完整的质量(即不压缩),只需使用 100 作为压缩值(就像我一样)。

      这会导致保持现有质量,因为打开 70% 质量的图像并以 70% 质量将其保存回来实际上会使最终质量降低 49%(70% 的 70%)。


      function GDToImagickTo($gd){
          $tmpfile = tmpfile();
          imagepng($tmpfile); // Png is our best image deal:
                              // lossless compression, transparency etc..
          $imagick = new Imagick()
          $imagick->readImage($tmpfile);
          return $imagick;
      }
      

      【讨论】:

      • 对不起,我的意思是GDToImagick....所以我可以用 gd -> gd2imagick() -> 进行灰度化,然后用 imagick 输出图像。
      • 不,我的意思是分辨率。 72dpi、150dpi、300dpi ......即使它们通常对 jpeg 文件无关紧要。我在这里做的事情是让客户上传扫描的图像(150dpi 或 300dpi),然后他们选择一些水印来结合。然后他们下载文件并打印出来。如果你在 Photoshop 中点击Print Preview,你会看到图像变小了,因为 GD 的 imagejpeg() 只输出 72dpi 的图像,这与 imagick 不同,你可以保留 dpi(150 或 300)。
      • 我已经用你想要的功能更新了答案。关于DPI问题;它可以从客户端更改(与压缩不同,它实际上会破坏图像)。此外,我还看到了一些用于更改 DPI 的脚本。你可以随时imagejpg(); $imagick->readImage(); $imagick->setImageResolution(); $imagick->writeImage();(保持简短)
      • ... imagepng(), imagejpeg()...它们是一回事。只要使用这些功能。图像的分辨率将降低到 72dpi,但在显示器上仍会清晰可见。但是当你用打印机打印出来时。它只是原始图像的一半大小(150 个中的 72 个)。而且,你不能指望客户知道图像编辑,既没有脚本也没有 Photoshop,至少我的客户不是。他们扫描、上传、合并、下载、打印……
      • 错误!分辨率只告诉打印机如何打印图像;图像数据不变。例如,使用扫描仪将同一张图像扫描两次,但分辨率不同;正如您将看到的,两者都是不同的图像,因为光栅化图像包含像素,而分辨率仅说明像素在纸上应该看起来有多大。因此,高密度图像只是放大的图像(即,实际图像必须改变)。对于输入与输出完全相同的图像,情况并非如此。
      猜你喜欢
      • 2016-07-14
      • 2013-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-20
      相关资源
      最近更新 更多