PHP或JS:在将图像转换为黑白时调整颜色通道级别

时间:2014-12-16 21:51:06

标签: javascript php image-processing imagemagick gd

我正在寻找有关如何调整黑白(或灰度)图像的颜色通道级别的帮助。在Photoshop中,此功能称为黑白滤镜。

以下示例演示了我的流程。红色衬衫(这是一个完美的中灰色)在最终图像中是黑色的。

原始图片 enter image description here

将Hue更改为绿色 enter image description here

最终影像现在黑白(中灰/红衬衫黑) enter image description here

2 个答案:

答案 0 :(得分:2)

使用Imagemagick,您可以使用-level运算符来调整黑色&白色终点,可以应用于特定颜色channel

示例:

 convert source.png -level 45%,80% out.png

使用PHP的Imagick library,您可以使用Imagick::levelImage方法。

$img = new Imagick('source.png');
$quantum = $img->getQuantumRange()['quantumRangeLong'];
$img->levelImage(0.45 * $quantum, 1.0, 0.80 * $quantum, Imagick::CHANNEL_ALL);

<强>更新

要生成中间图像(绿色衬衫),您可以使用-modulate的“红色 - &gt;绿色”色调调制。 Hue Modulation文档中的示例。

convert source.jpg -modulate 100,100,166.6 green.png
// or in PHP
Imagick::modulateImage ( float $brightness , float $saturation , float $hue )

Red to Green modulate

现在要将颜色换成黑色,只需使用-fuzz-opaque即可。但老实说,所有的绿色色调都让我想起Chroma Key,它被定义为......

chroma key

一旦隔离了面具,交换颜色,背景或更复杂的图像就非常简单。

convert green.png -fx '1 * b - 1 * g + 1' mask.png

shirt mask

遮罩方法的主要好处是颜色细节(阴影,高光和线条)将保留在最终图像中。在PHP中将它们全部拉到一起:

$img = new Imagick("source.jpg");
$org = clone $img; // Copy source for final composite
$img->modulateImage(100,100,166.6); // Convert hues from red to green
/*
 Apply fx operations. Remember: K0, K1, & K2 are constants
 that need to be adjusted to match the chroma-key that you
 want to knockout.
 */
$mask = $img->fxImage('1.35 * b - 0.95 * g + 1');
// Copy the mask as the new alpha channel
$org->compositeImage($mask, Imagick::COMPOSITE_COPYOPACITY, 0, 0, Imagick::CHANNEL_ALPHA);

original image with alpha mask applied

用黑色80%(或灰色20%)填充衬衫。在纯色图像上构图新图像,然后降至灰度。

$fin = new Imagick();
$fin->setSize($org->width, $org->height);
$fin->readImage("xc:gray20");
$fin->compositeImage($org, Imagick::COMPOSITE_DEFAULT, 0, 0);
$fin->setImageColorspace(Imagick::COLORSPACE_GRAY);
$fin->writeImage('fin.jpg');

Black 80% with highlights

这是用衬衫图案填充衬衫的例子。

$pattern = new Imagick();
$pattern->setSize($org->width, $org->height);
$pattern->readImage("pattern:VERTICALSAW");
$pattern->negateImage(false);
$pattern->compositeImage($org, Imagick::COMPOSITE_DEFAULT, 0, 0);
$pattern->setImageColorspace(Imagick::COLORSPACE_GRAY);
$pattern->writeImage('pattern.jpg');

Pattern Example

同样,如果您想保留详细信息,这是理想的选择。如果你想要完全淘汰(例如,所有绿色到黑色80%),只需使用-fill-opaque&amp; -fuzz

示例:

convert green.png  -fill gray20 -fuzz 30% -opaque hsl\(33%,100%,50%\) black80.png
convert black80.png -colorspace Gray bw_shirt.png

final shirt

答案 1 :(得分:1)

这是你要找的这个命令吗?

convert                              \
  http://i.stack.imgur.com/QW5M0.jpg \
 -colorspace gray                    \
  b+w.jpg

结果(左侧原始红色衬衫,右侧黑色+白色图像):

或者您是否希望原始的不同红色调成为(几乎)纯黑色? - 在这种情况下,添加一些-gamma调整,可能:

convert                              \
  http://i.stack.imgur.com/QW5M0.jpg \
 -colorspace gray                    \
 -level 0%,100%,0.5                  \
  b+w-2.jpg

convert                              \
  http://i.stack.imgur.com/QW5M0.jpg \
 -colorspace gray                    \
 -level 0%,80%,0.5                   \
  b+w-3.jpg

以下是两张图片:

当然,你可以使用我在这里使用的确切参数玩一点......

更新

以下命令首先更改红色通道的颜色级别,然后将此中间结果转换为灰度:

convert              \
   red---QW5M0.jpg   \
  -channel R         \
  -level 0%,40%      \
  -colorspace gray   \
  -level 0%,100%,0.5 \
   b+w-4.jpg

convert              \
   red---QW5M0.jpg   \
  -channel R         \
  -level 0%,80%      \
  -colorspace gray   \
  -level 0%,100%,0.5 \
   b+w-5.jpg