imagemagick检测透明区域的坐标

时间:2014-10-07 19:57:48

标签: ruby-on-rails imagemagick transparency alpha

我的PNG图像包含透明区域,正方形/矩形区域包含透明度。 我想知道是否有某种方法可以让我知道图像中这些透明区域的顶部,左侧,宽度,高度。

感谢您的帮助

1 个答案:

答案 0 :(得分:5)

更新了答案

在这几年中,我遇到了一个更简单的解决方案,所以我想我会更新它,以便其他人看到它可以获得最新和最好的好处。

从相同开始,通过将alpha图层提取到自己的图像并将其反转:

convert start.png -alpha extract -negate intermediate.png

enter image description here

现在执行“连接组件分析”

convert start.png -alpha extract -negate           \
   -define connected-components:verbose=true       \
   -define connected-components:area-threshold=100 \
   -connected-components 8 -auto-level  result.png

Objects (id: bounding-box centroid area mean-color):
  0: 256x256+0+0 128.7,130.4 62740 srgb(0,0,0)
  3: 146x8+103+65 175.5,68.5 1168 srgb(255,255,255)
  2: 9x93+29+42 33.0,88.0 837 srgb(255,255,255)
  1: 113x7+4+21 60.0,24.0 791 srgb(255,255,255)

你会看到有一个标题行和4行输出,每一行都有一个颜色,第一行是黑色,对应整个形状,最后三行是白色,对应三个透明的区域。它基本上是你想要的最后三行中每一行的第二个字段。因此,146x8+103+65表示一个宽146px的盒子,103px高的偏移103px到左上角的右边,65px从左上角向下。

如果我用红色绘制它们,你可以看到它已经识别出来的东西:

convert result.png -stroke red -fill none -strokewidth 1 \
   -draw "rectangle 103,65 249,73"                       \
   -draw "rectangle 29,42 38,135"                        \
   -draw "rectangle 4,21 117,28" result.png

enter image description here


原始答案

以下内容可能会帮助您找到答案,但我还没有完成整个过程 - 人们经常提出问题,然后再也没有登录,而且需要付出相当多的努力...

让我们从这个输入图像开始 - 白色区域是透明的:

enter image description here

您可以使用ImageMagick从图像中提取Alpha通道,如下所示:

convert input.png -alpha extract -negate alpha.png

给出了这个,白色区域是透明的

enter image description here

好的,一种方法是找到白色区域的边界框,你可以使用trim执行此操作,它将为您提供包围白色区域的边界框:

convert input.png -alpha extract -format "%@" info:
245x114+4+21

因此边界框宽245px,高114px,从左上角偏移+4 + 21开始。我可以在图像上绘制它来显示它:

enter image description here

所以,这是一个开始。

此外,您可以让ImageMagick以文本格式枚举像素,因此您可以运行此命令

convert input.png -alpha extract -negate txt: | more
# ImageMagick pixel enumeration: 256,256,255,gray
0,0: (0,0,0)  #000000  gray(0)
1,0: (0,0,0)  #000000  gray(0)
2,0: (0,0,0)  #000000  gray(0)

告诉您图像为256x256,前3个像素全部为黑色。如果你想要白色的(即透明的),你可以这样做:

convert input.png -alpha extract -negate txt: | grep FFFFFF | more
4,21: (255,255,255)  #FFFFFF  gray(255)
5,21: (255,255,255)  #FFFFFF  gray(255)
6,21: (255,255,255)  #FFFFFF  gray(255)
7,21: (255,255,255)  #FFFFFF  gray(255)

这告诉你像素4,21是透明区域的左上角 - 我很高兴它匹配上面边界框方法的输出: - )

因此,您可以轻松获取所有透明像素的列表。可以开发这种方法,或者在Ruby(RMagick)中编写类似的东西来找到黑色的连续区域 - 但目前超出了这个答案的范围 - 因为我不是Ruby程序员: - )

好的,我今天下午学到了一些Ruby,请不要笑,这是我的第一个Ruby程序。它可能非常难看,更像是Perl或C(我的首选语言),但它可以工作并找到矩形透明区域。

#!/usr/bin/ruby

require 'RMagick'
include Magick
infile=ARGV[0]
img = ImageList.new(infile)
w=img.columns
h=img.rows
#Extract alpha channel into pixel array
px=img.export_pixels(0,0,w,h,"A")

for row in 0..h-1
   for col in 0..w-1
      thispx=px[w*row+col]
      if thispx<32768 then
         a=row
         b=col
         # Find extent (c) of rectangle towards right
         for r in col..w-1
            thispx=px[w*row+r]
            if thispx<32768
               c=r
            else
               break
            end
         end
         # Find extent (d) of rectangle towards bottom
         for s in row..h-1
            thispx=px[w*s+col]
            if thispx<32768
               d=s
            else
               break
            end
         end
         # Blank this rectangle as we have located it
         for r in row..d
            for s in col..c
               px[w*r+s]=65535
            end
         end

         # Tell caller about this rectangle
         printf "%d,%d %d,%d\n",a,b,d,c
      end
   end
end

像这样运行:

bounds.rb input.png