【发布时间】:2015-11-24 03:03:20
【问题描述】:
为了防止在我选择的图形引擎中缩放精灵或在不完整的像素上显示它们时出现伪影,我需要检查所有精灵并为每个精灵添加边缘。边缘需要是相邻像素的颜色,就像这样:
左图为原图,右图为预期结果。
在ImageMagick中可以实现这个效果吗?也就是说,你能不能把图片在四个方向都扩大一个像素,把边缘像素复制到新添加的边框里?
【问题讨论】:
标签: imagemagick
为了防止在我选择的图形引擎中缩放精灵或在不完整的像素上显示它们时出现伪影,我需要检查所有精灵并为每个精灵添加边缘。边缘需要是相邻像素的颜色,就像这样:
左图为原图,右图为预期结果。
在ImageMagick中可以实现这个效果吗?也就是说,你能不能把图片在四个方向都扩大一个像素,把边缘像素复制到新添加的边框里?
【问题讨论】:
标签: imagemagick
首先,您应该了解以下基本图像操作,它们将作为完整命令的构建块:
image.ext[NxM+x+y] 将从 image.ext 中切出一个NxM 像素大小的区域,该区域向右偏移+x 像素,向底部偏移+y 像素,从左上角计算角落。+append 附加两个(或更多)图像水平。-append 附加两个(或更多)图像垂直。image.ext[1x+0+0] 切断图像中最左侧的像素列。-flop 将从左到右镜像图像。-flip 将从上到下镜像图像。image.ext[x1+0+0] 截取图像中最顶部的一行像素。image.ext[1x+0+0] 截取图像中最左侧的像素列。-crop NxM+x+y 与 1. 的作用相同。mpr:ABC 将使用标签 ABC 将图像写入 Magick Persistent Registry。从位于特殊内存位置的 MPR 中,ImageMagick 只需调用标签名称即可检索图像的副本。-delete 0 将从当前图像序列中删除索引为 0 的图像。+write 将在给定的名称下写入图像序列。+repage 再次规范化图像画布。现在您可以将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
最顶行:
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操作达到同样的效果,但是比较难理解……
【讨论】:
[1x+0+0]-thing(代码中第 5 行使用的第 4 点)总是为我生成 1x3px 的图像。通过使用 -crop 1x+0+0 来解决问题,因为它可以按预期工作。 [x1+0+0] 似乎工作正常。我正在运行 ImageMagick 6.9.7-4。
我认为解决此问题的最简单方法是将原始图像的大小调整为比原始图像高 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
【讨论】:
-resize 运算符隐式应用 -filter lanczos(如果未另外设置),它将在计算附加像素的颜色值时应用一些数学。 ——我仍然需要找时间提出一个明显偏差的例子。但我当然承认,无论如何,您的方法都将是一个非常好的近似值。黑色边框像素不会突然变白:-)
使用虚拟像素:
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。
【讨论】: