在图像上绘制具有特定大小的单元格网格。

6
如何在图像上绘制网格,边框为1px黑色无填充?
每个网格的大小应为480x360px。
例如,给定这个1440x1080px的纯白输入:

enter image description here

它应该有一个3x3的网格绘制在上面(因为9个480x360像素的矩形适合其中),以使输出类似于这样:

enter image description here

这个命令不如我希望的那么准确(我只是靠眼睛画了矩形),但我希望它能说明我想要的东西。


您可以使用ImageMagick中的-draw“line…”函数来完成此操作。如果在Unix imagemagick系统上,您可能可以使用我的bash unix shell脚本grid。请参见http://www.fmwconcepts.com/imagemagick/index.php。 - fmw42
5个回答

5

这里有一个命令,可以读取输入图像,并创建一个带有黑色边框的480x360透明单元格,将这些单元格创建成与输入图像大小相同的网格,然后将该网格合成到输入图像上...

infile="MyPic.png"

convert "$infile" -size 480x360 -set option:distort:viewport "%[w]x%[h]" \
   \( xc:none -shave 1x1 -compose copy -bordercolor black -border 1x1 \) \
   -virtual-pixel tile -distort SRT 0 -compose over -composite output.png

这将使网格的线条变粗2像素。如果要使线条变细1像素,可以使用类似以下命令的方法...

convert "$infile" -size 480x360 -set option:distort:viewport "%[w]x%[h]" \
   \( xc:none -chop 1x1 -background black -splice 1x1 \) \
   -virtual-pixel tile -distort SRT 0 -compose over -composite \
   -bordercolor black -shave 1x1 -compose copy -border 1x1 output.png

修改后添加:如果目标是将网格分成特定数量的单元格而不是指定尺寸的单元格,则应该使用以下命令...
convert "$infile" \( +clone -channel A -evaluate set 0 +channel \
  -crop 3x4@ -chop 1x1 -background black -splice 1x1 \) -background none \
  -flatten -shave 1x1 -bordercolor black -border 1x1  output.png

该命令将创建输入图像的克隆并使其透明,使用“-crop 3x4@”将其裁剪成3x4个单元格的网格,在单元格的上边缘和左边缘放置黑色边框,然后通过将它们压平到输入图像上重新组装它们成为一个网格。最后,保留输入图像的原始尺寸,在右侧和底部边缘添加边框。

显然,如果输入图像不能被单元格数量均匀地分割,则这种方法可能导致单元格的尺寸不完全相同。

再次编辑:如果您实际上不需要网格作为覆盖层,您可以直接将图像裁剪成瓷砖,将黑线围绕瓷砖放置,并重新组装它们以创建所需的输出图像。可以使用以下简单命令完成此操作,以制作480x360大小的单元格...

convert "$infile" -background black -bordercolor black \
   -crop 480x360 -chop 1x1 -splice 1x1 -flatten -shave 1x1 -border 1x1 output.png

或者你可以使用"-crop 3x3@",就像这样制作一个3行3列的网格,让ImageMagick尽可能地计算大小...

convert "$infile" -background black -bordercolor black \
   -crop 3x3@ -chop 1x1 -splice 1x1 -flatten -shave 1x1 -border 1x1 output.png

如果图像大小不能被单元格数整除,那么某些单元格的尺寸将会有一个像素的差异。


太棒了!好方法! - Mark Setchell

4

我尝试过这个,但每一步都陷入了困境。以下是我目前得到的最好结果。

convert xc:white[1440x1080\!] -colorspace gray -fx "(i==0||i==479||i==959||i==1439||j==0||j==359||j==719||j==1079)?0:1" grid.png

在此输入图片描述

因此,在实际使用中,您需要克隆您的雪景。然后将其转换为灰度图像(以将处理时间减少3倍),并将所有线条设置为黑色,其他像素设置为白色。然后覆盖到雪景上,在每个位置选择最暗的像素:

convert scene.jpg \( +clone -colorspace gray \
   -fx "(i==0||i==479||i==959||i==1439||j==0||j==359||j==719||j==1079)?0:1" \) -compose darken -composite result.png

在此输入图片描述


如果您希望它稍微更加智能并且适应不同大小的图像,您可以根据图像大小计算第三点:

magick scene.jpg \( +clone -colorspace gray \
  -fx "(i==0||i==int(w/3)||i==2*int(w/3)||i==w-1||j==0||j==int(h/3)||j==2*int(h/3)||j==h-1)?0:1" \) \
  -compose darken -composite result.png

enter image description here


太好了!我需要一个大小为w x h的规则网格,并使用“-fx”“(i%w == 0 || j%h == 0)?0:1”来实现它。谢谢。帮了大忙。 - sl0815

1
到目前为止,我想到的最好的方案是:
convert blank.png -fill black -draw 'line 480,0 480,1080 line 960,0 960,1080 line 0,360 1440,360 line 0,720 1440,720' level1.png

但这一切都是手动的。

有没有自动化的方法?


这里已经发布了几个回复和建议。一些成员花费了不少精力来帮助您解决问题。您对其中任何一个没有任何评论吗? - GeeMack
@GeeMack 他们的速度太慢了,所以我按照这个答案手动完成了,自那以后就没有再需要这样做了。下次需要这样做时,我会测试一下他们的方法,看起来确实更好,但因为我没有进行任何测试,所以我不觉得我能接受任何东西。 - theonlygusti
好的,你的评论“有没有自动化的方法?”其实并不是一个请求回复的问题。问号让我们误解了。 - GeeMack
@GeeMack 不是陈述,而是一个问题。下次我需要完成这个任务时,由于所有有用的答案(包括我的答案)和我对ImageMagick功能的了解,我将能够更轻松、更快地完成它,并且我也学到了很多关于ImageMagick的能力。 - theonlygusti

0

这里有另一种变体,快速易懂 - 虽然不完全符合您的要求,但可能已经足够好了。

创建一个带有黑色边框的起始框,复制两次并在页面上附加,再复制两次并向下附加,对大小进行微小更正:

convert xc:red[478x358\!] -bordercolor black -border 1  \
  -duplicate 2,0 +smush -1                              \
  -duplicate 2,0 -smush -1 -transparent red -scale 1440x1080\! result.png

enter image description here


0

或者你可以制作你的初始框,复制它8次,然后让montage布置出9个结果框:

convert xc:red[478x358\!] -bordercolor black -border 1 \
   -transparent red -duplicate 8,0 miff:- | montage -background none -geometry +0+0 miff:- result.png

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接