Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ImageMagick:减少图像中所有像素的RGB值_Imagemagick - Fatal编程技术网

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

ImageMagick:减少图像中所有像素的RGB值,imagemagick,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

具体来说,对于给定的图像,我试图将每个像素的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,并增加减去的常数-但它似乎不起作用


有什么想法吗?谢谢

老实说,我真的不明白命令行中的值
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文件的格式很容易理解,一旦知道第一列给出了基于像素零的坐标:
123456:
表示:第124列(!),第457行()

现在,您可以将这两个.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:
一个全白色的平面将意味着“没有差异”,任何红色像素将暗示某种三角形


现在,如果这个答案不能为我赢得选票,我不知道哪一个会…:-)

肯,不,你不需要写一个大的解析器。用几个shell命令就可以很容易地完成。首先测试它们,然后将它们放入Shell或批处理脚本中。类似于以下内容(作为Bash脚本):

#!/bin/bash echo“注意:此脚本可能需要很长时间才能完成…” echo”(此脚本用于使用Alpha通道转换PNG文件 echo“对于其他类型的图像,您需要稍微修改它。)” 回声 echo“此脚本获取8位RGBA输入图像,并创建较暗的输出图像。” 其方法是:从每个颜色通道的数值中减去100 回声 input=“${1}” _im_头=$(标识-格式“%W,%H”“${input}”) echo“#ImageMagick像素枚举:${u im_header},255,rgba”>input-减号-120.txt 转换“${input}”input.txt cat input.txt\ | \ 塞德的#).$#);s####g;s::;############;s#,##g;s###,#'\ | \ 同时读取coord红绿色蓝色alpha;做 echo-n“${coord}”; echo-n“(”; echo-n“$($red-100)),”; echo-n“$($green-100)),”; echo-n“$($blue-100)),”; echo-n“$($alpha))”; echo-n“; 回声; 完成\ |sed的#-[0-9]*#0#g'\ >>输入-减号-120.txt 转换输入-减号-120.txt输出-减号-120.jpg 该脚本需要153秒才能在MacBook Pro上运行,处理一个750 KB的1080x889像素PNG文件

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


因此,这个暴力shell脚本的性能约为6275像素/秒。

嗨,库尔特-我感谢您的详细回答。然而,虽然乍一看这似乎是可行的,但它似乎与我的示例有相同的问题-虽然图像整体变暗,但由于某些原因,它似乎缺乏精度-也就是说,许多像素的RGB值不会精确减小。如果您尝试查看一个随机像素值(使用Gimp或其他方法),然后在运行此命令后查看相同的像素值,它可能会减小,但不会完全精确。你知道为什么会发生这种情况以及如何解决它吗?谢谢@肯:如果你在ImageMagick安装上处理8位(或16位)深度的图像,这是一个Q16(或Q8)内置的(QuantumRange),可能会发生舍入错误。非常感谢Kurt!还有一个小问题,我保证投票/答案是你的:)(无论如何,别担心)。有没有什么方法可以在不编写自己的解析器的情况下轻松地对txt文件进行这些更改?此外,这里还有一个减去某个像素的灰度39后的差异示例:原始:155117:(1,0,0)#010000 rgb(1,0,0)减去:155117:(0,2,1)35201RGB(0,2,1)为什么有些值会增加?再次感谢-不幸的是,这肯定需要很长时间才可行。你知道为什么有些值会增加(在我的评论末尾)?@Ken:Script被更新了——我还在答案末尾添加了一些基准数字。。。还有,我现在才知道你想减去100,不是吗 #!/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