【问题标题】:ImageMagick: Decreasing RGB values of all pixels in an imageImageMagick:减少图像中所有像素的 RGB 值
【发布时间】:2012-08-09 07:03:26
【问题描述】:

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

有什么想法吗?谢谢!

【问题讨论】:

    标签: imagemagick


    【解决方案1】:

    老实说,我真的不明白你的命令行中 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 文件的格式很容易理解,只要您知道第一列给出了从零开始的像素坐标:123,456: 表示:第 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:
    

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

    现在,如果 那个 的回答没有为我赢得投票,我不知道哪个会... :-)

    【讨论】:

    • 嗨,Kurt - 感谢您的详细回答。然而,虽然这乍一看似乎有效,但它似乎与我的示例存在相同的问题 - 虽然图像整体变暗,但由于某种原因似乎缺乏精度 - 也就是许多像素的 RGB 值不会准确降低.如果您尝试查看随机像素值(使用 Gimp 或其他东西),然后在运行此命令后查看相同的像素值,它可能会减小,但并不完全准确。您知道为什么会发生这种情况以及如何解决吗?谢谢!
    • @Ken:如果您在 Q16(或 Q8)构建 (QuantumRange) 的 ImageMagick 安装上处理具有 8 位(或 16 位)深度的图像,则可能会发生舍入错误。跨度>
    • 非常感谢库尔特!还有一个小问题,我保证赞成/回答是你的:)(无论如何不要担心)。有什么方法可以在不编写我自己的解析器的情况下轻松地对 txt 文件进行这些更改?这里还有一个例子是减去某个像素的 gray39 后的差异: original: 155,117: ( 1, 0, 0) #010000 rgb(1,0,0) after subtraction: 155,117: ( 0, 2, 1) # 000201 rgb(0,2,1) 为什么有些值会增加??
    【解决方案2】:

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

    #!/bin/bash echo " 注意:这个脚本可能需要很长时间才能完成......" echo " (此脚本用于转换带有 Alpha 通道的 PNG 文件。" echo " 对于其他类型的图片,需要稍微修改一下。)" 回声 echo " 此脚本采用 8 位 RGBA 输入图像并创建更暗的输出图像。" echo "它的方法是:每个颜色通道的数值减去100的值。" 回声 输入="${1}" _im_header=$(identify -format "%W,%H" "${input}") echo "# ImageMagick 像素枚举:${_im_header},255,rgba" > input-minus-120.txt 转换 "${input}" input.txt 猫输入.txt \ | \ sed 's#) .*$#)#; s###g; s#:#:#; s#(##; s#)##; s#,##g; s##,#'\ | \ 同时读取坐标红绿蓝阿尔法;做 回声 -n "${坐标}"; 回声-n“(”; echo -n "$(($red - 100)),"; echo -n "$(($green - 100)),"; echo -n "$(($blue - 100)),"; 回声 -n "$(($alpha))"; 回声-n“)”; 回声; 完毕 \ | sed 's#-[0-9]*#0#g' \ >> 输入-减-120.txt 转换 input-minus-120.txt output-minus-120.jpg

    此脚本需要 153 秒才能在 MacBook Pro 上运行,处理 750 kByte 的 1080x889 像素 PNG 文件。

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

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

    【讨论】:

    • 再次感谢 - 不幸的是,这肯定需要很长时间才能实现。您知道为什么某些值会增加(根据我的评论结尾)吗?
    • @Ken:脚本已更新——我还在答案末尾添加了一些基准数字......另外,我现在才看到你想减去 100,而不是 120。
    • @Ken:我没有说这个方法是高效的 :-) 我设计它是为了帮助你调试 real 命令。它为您提供了一个参考,您可以使用该参考来评估实际命令中的 多少 像素未显示预期值、偏差有多少以及是否存在“模式”在这个偏差中......还要看看重复运行真实命令是否会产生不同的结果。
    猜你喜欢
    • 2014-04-24
    • 1970-01-01
    • 1970-01-01
    • 2015-03-07
    • 1970-01-01
    • 1970-01-01
    • 2017-12-12
    • 2012-02-26
    • 1970-01-01
    相关资源
    最近更新 更多