如何在ImageMagick中为边缘像素设置边框颜色

时间:2015-03-13 00:02:36

标签: imagemagick

为了防止在我选择的图形引擎中缩放精灵或将其显示在非全像素上时出现伪影,我需要仔细检查所有精灵并为每一个精灵添加边缘。边缘需要是相邻像素的颜色,如下所示:

Expected effect

左图像是原始图像,右图像是预期结果。

是否可以在ImageMagick中实现此效果?换句话说,您可以将所有四个方向的图像扩展一个像素,将边缘像素复制到新添加的边框中吗?

3 个答案:

答案 0 :(得分:4)

首先,您应该了解以下基本图像操作,它们将作为完整命令的构建块:

  1. image.ext[NxM+x+y]会从 image.ext 中删除一个NxM像素大小的区域,该区域向右偏移+x像素,+y }像素到底部,从左上角计算。
  2. +append附加两个(或更多)图片水平
  3. -append附加两个(或更多)图片垂直
  4. image.ext[1x+0+0]会切断图片中最左侧的像素列。
  5. -flop将从左到右镜像图像。
  6. -flip将从上到下镜像图像。
  7. image.ext[x1+0+0]会删除图片中最顶部的像素行。
  8. image.ext[1x+0+0]会删除图片中最左侧的像素列。
  9. -crop NxM+x+y1.完全相同。
  10. mpr:ABC会使用标签 ABC 将图像写入 Magick Persistent Registry 。从驻留在特殊内存位置的MPR,ImageMagick可以通过调用标签名称来检索图像的副本。
  11. -delete 0将删除当前图像序列中索引为0的图像。
  12. +write将以给定的名称编写图像序列。
  13. +repage再次规范化图片画布。
  14. 现在,您可以将5.8.合并,以剪切最右侧的像素行:

    -flop image.ext[1x+0+0]
    

    您还可以将6.7.合并,以删除最底部的像素列:

    -flip image.ext[x1+0+0]
    

    现在将这些效果与括号语法\( ... \)结合使用,以便对完整命令的图像进行边处理:

    convert image.png                     \
      -respect-parentheses                \
      +write mpr:ABC                      \
      -delete 0                           \
        \( mpr:ABC[1x+0+0] \)             \
        \( mpr:ABC \)                     \
        \( mpr:ABC -flop -crop 1x+0+0 \)  \
      +append +repage                     \
      +write mpr:XYZ                      \
      -delete 0                           \
        \( mpr:XYZ[x1+0+0] \)             \
        \( mpr:XYZ \)                     \
        \( mpr:XYZ -flip -crop x1+0+0 \)  \
      -append +repage                     \
      extended-edges.png
    

    将此应用于内置rose:图片:

    convert rose:                         \
      -respect-parentheses                \
      +write mpr:ABC                      \
      -delete 0                           \
        \( mpr:ABC[1x+0+0] \)             \
        \( mpr:ABC \)                     \
        \( mpr:ABC -flop -crop 1x+0+0 \)  \
      +append +repage                     \
      +write mpr:XYZ                      \
      -delete 0                           \
        \( mpr:XYZ[x1+0+0] \)             \
        \( mpr:XYZ \)                     \
        \( mpr:XYZ -flip -crop x1+0+0 \)  \
      -append +repage                     \
      extend.png
    

    快速检查新图像的大小

    identify rose: extend.png 
     rose:=>ROSE   PPM 70x46 70x46+0+0 8-bit sRGB 9.67KB 0.000u 0:00.000
     extend.png[1] PNG 72x48 72x48+0+0 8-bit sRGB 7.11KB 0.000u 0:00.000
    

    检查前2行像素是否相同

    排在最前一行:

    convert extend.png[x1+0+0] txt:- | md5sum
     12b639cd1606559633ee23a062ae42a6  -
    

    从顶部开始的第二行:

    convert extend.png[x1+0+1] txt:- | md5sum
     12b639cd1606559633ee23a062ae42a6  -
    

    从顶部开始的第三行:

    convert extend.png[x1+0+2] txt:- | md5sum
     88fc6f9bac3f8ab4cbf2374fbef6fcf0  -
    

    检查两个最左侧的列是否相同

    最左列:

    convert extend.png[1x+0+0] txt:- | md5sum
     4d2223b74901f9ce1fb4456dacb4315c  -
    

    左起第二栏:

    convert extend.png[1x+1+0] txt:- | md5sum
     4d2223b74901f9ce1fb4456dacb4315c  -
    

    左起第三栏:

    convert extend.png[1x+2+0] txt:- | md5sum
     07794b4423f5b6515142d15a5c652743  -
    

    我没有展示如何检查两个最底行和两个最右列是否也相同......


    使用-virtual-pixel edge操作还有一种方法可以达到同样的效果,但是更难理解......

答案 1 :(得分:1)

我认为解决这个问题的最简单方法是将原始图像调整为比原始图像高2像素,宽2像素,然后为了避免内部像素的扭曲,将未更改的原始图像复合到顶部中心。

因此,要获得输出图像的尺寸,请在宽度和高度上加2,

geom=$(identify -format "%[fx:w+2]x%[fx:h+2]" sprite.png)

提供类似

的内容
34x34

如果原始图像是32x32。

然后我将图像调整为这个新尺寸,以填充边框像素,并将未更改的原件复合到顶部

convert sprite.png -resize $geom -gravity center sprite.png -composite out.png

enter image description here

答案 2 :(得分:0)

使用虚拟像素:

convert -resize "%[fx:w+4]x%[fx:h+4]" "./input.png" -set option:distort:viewport "%[fx:w+4]x%[fx:h+4]"-2-2 -virtual-pixel Edge -distort SRT 0 +repage ./output.png

input.png是输入图像。 output.png将使用原始边缘的颜色将其边框扩展2个像素。通过添加两倍扩展宽度来调整图像大小。视口偏移设置为扩展宽度。

有关详细信息,请参阅this page