ImageMagick:减少图像中所有像素的RGB值

时间:2012-08-07 17:42:32

标签: imagemagick

具体来说,对于给定的图像,我试图将每个像素的RGB值减少100。

例如,如果像素具有R:232,G:40,B:120,那么我希望新的RGB值为R:132,G:0,B:20。

我尝试过在ImageMagick论坛上找到的解决方案:

convert input.jpg -channel R -evaluate subtract 25700 \
-channel G -evaluate subtract 25700 \
-channel B -evaluate subtract 25700 output.jpg

编辑:我使用25700的原因是因为显然你需要将rgb值乘以257. 100 * 257 = 25700。

虽然它似乎首先工作(显然使图像变暗),但似乎某些像素不会改变,而且我正在做的事情对他们来说至关重要(我正在对生成的图像进行修剪,尝试用像素值0)修剪边界。

一个常见的问题是,我最终会得到一个RGB值为3,0,0的像素,但我希望该像素的RGB值为0,并增加常数I减去 - 但它似乎不起作用。

有什么想法吗?谢谢!

2 个答案:

答案 0 :(得分:4)

老实说,我真的不明白命令行中的值25700应该达到的目的。

但是,我建议使用功能更强大的-fx运算符,为您提供不同的命令行。看起来有点复杂,但希望更直观地理解......

但首先,我正在查看您的说明,并且您希望从每个当前的R,G和B颜色值中减去固定数量的120。所以这是一个灰色的像素颜色...你可以在ImageMagick的颜色内置颜色列表中查找,它的名字是gray47

convert -list color | grep '(120,120,120)'
  gray47                srgb(120,120,120)                             X11 XPM 
  grey47                srgb(120,120,120)                             SVG X11 

这引出了以下命令:

   convert \
       input.jpg \
      -channel red   -fx 'r - gray47' \
      -channel green -fx 'g - gray47' \
      -channel blue  -fx 'b - gray47' \
       output.jpg

这种方式或编写命令可能会让你看到一些容易导出的修改,如果你将来需要这些修改......

要弹出结果的即时预览窗口(不将其写入文件),您还可以使用-show:作为输出,如下所示:

   convert \
       input.jpg \
      -channel red   -fx 'r - gray47' \
      -channel green -fx 'g - gray47' \
      -channel blue  -fx 'b - gray47' \
      -show:

更新

如果要检查每个像素的真实差异,可以让ImageMagick打印出每个像素的颜色值:

convert  input.jpg   input.txt
convert  output.jpg  output.txt

.txt文件的格式很容易理解,一旦你知道第一列给出Pixel从零开始的坐标:123,456:表示:第124(!)列,第457()行。< / p>

现在,即使在自动化的脚本版本中,您也可以将两个.txt文件与心脏内容进行比较,而无需使用Gimp。 : - )

你甚至可以使用input.txt并在每个像素值上应用Perl,Ruby,Python或Shellscript来分散每个通道的120值,将其保存为output2.txt然后将其转换回JPEG:

convert  output2.txt  output2.jpg

然后查找两个输出图像之间的像素差异:

compare  output.jpg  output2.jpg  delta.jpg
compare  output.jpg  output2.jpg  view:

全白平面将意味着'没有差异',任何红色像素都会暗示某种增量。

现在,如果那个答案没有给我一个upvote,我不知道哪个会...: - )

答案 1 :(得分:1)

肯,不,你不需要写一个大的解析器。使用一些shell命令很容易完成。首先测试它们,然后将它们放入Shell或Batch脚本中。像这样的东西(作为Bash脚本):

#!/bin/bash

echo " ATTENTION: this script can take a loooong time to complete..."
echo " (This script is made to convert PNG files with an Alpha channel."
echo "  for other types of images, you need to slightly  modify it.)"
echo
echo " This script takes an 8-bit RGBA input image and creates a darker output image."
echo " Its method is: subtract the value of 100 from each color channel's numeric value."
echo

input="${1}"

_im_header=$(identify -format "%W,%H"  "${input}")

echo "# ImageMagick pixel enumeration: ${_im_header},255,rgba" > input-minus-120.txt

convert  "${input}"  input.txt

cat input.txt \
   | \
     sed 's#) .*$#)#;  s# ##g;  s#:#: #;  s#(# #;  s#)##; s#,# #g; s# #,#' \
   | \
     while read coord red green blue alpha; do
        echo -n "${coord}";
        echo -n " (";
        echo -n " $(($red   - 100)),";
        echo -n " $(($green - 100)),";
        echo -n " $(($blue  - 100)),";
        echo -n " $(($alpha))";
        echo -n " ) ";
        echo;
     done \
   | sed 's#-[0-9]*#0#g' \
>> input-minus-120.txt

convert  input-minus-120.txt  output-minus-120.jpg

这个脚本需要153秒才能在MacBook Pro上运行,处理750x字节的1080x889像素PNG文件。

生成的input.txt有960120行(PNG中的像素数)。

所以这个暴力shell脚本的性能大约是6275像素/秒。