一张图片胜过千言万语...
我想知道如何能够生成这样的图像,其中(1)两个圆显然是完美的圆,(2)我可以根据角度定义每个区域的开始和结束部分,例如第 1 节从垂直的 0 弧度开始,到垂直的 pi/2 弧度结束,等等,并且 (3) 我可以定义每个区域的颜色。
事实上,环的外侧和内侧不应该有黑色边框;每个区域的边框应与每个区域的颜色相同。
我如何使用 ImageMagick 来做到这一点?
一张图片胜过千言万语...
我想知道如何能够生成这样的图像,其中(1)两个圆显然是完美的圆,(2)我可以根据角度定义每个区域的开始和结束部分,例如第 1 节从垂直的 0 弧度开始,到垂直的 pi/2 弧度结束,等等,并且 (3) 我可以定义每个区域的颜色。
事实上,环的外侧和内侧不应该有黑色边框;每个区域的边框应与每个区域的颜色相同。
我如何使用 ImageMagick 来做到这一点?
我对此知之甚少,gnuplot
但认为它很可能符合这里的要求 - 我的命令可能很粗糙,但它们看起来非常清晰有效。比我聪明的人也许可以改进它们!
无论如何,这是我想出的脚本:
set xrange [-1:1]
set yrange [-1:1]
set angles degrees
set size ratio -1
# r1 = annulus outer radius, r2 = annulus inner radius
r1=1.0
r2=0.8
unset border; unset tics; unset key; unset raxis
set terminal png size 1000,1000
set output 'output.png'
set style fill solid noborder
set object circle at first 0,0 front size r1 arc [0:60] fillcolor rgb 'red'
set object circle at first 0,0 front size r1 arc [60:160] fillcolor rgb 'green'
set object circle at first 0,0 front size r1 arc [160:360] fillcolor rgb 'blue'
# Splat a white circle on top to conceal central area
set object circle at first 0,0 front size r2 fillcolor rgb 'white'
plot -10 notitle
结果如下:
因此,如果您将上述脚本保存为annulus.cmd
运行它并output.png
使用命令创建文件
gnuplot annulus.cmd
显然,脚本的核心是 3 行开始,set object circle
每行都以不同的颜色和不同的开始和结束角度创建一个单独的环形段。
闲逛并改变一些东西给出了这个:
set xrange [-1:1]
set yrange [-1:1]
set angles degrees
set size ratio -1
# r1 = annulus outer radius, r2 = annulus inner radius
r1=1.0
r2=0.4
unset border; unset tics; unset key; unset raxis
set terminal png size 1000,1000
set output 'output.png'
set style fill solid noborder
set object circle at first 0,0 front size r1 arc [0:60] fillcolor rgb 'red'
set object circle at first 0,0 front size r1 arc [60:120] fillcolor rgb 'green'
set object circle at first 0,0 front size r1 arc [120:180] fillcolor rgb 'blue'
set object circle at first 0,0 front size r1 arc [180:240] fillcolor rgb 'yellow'
set object circle at first 0,0 front size r1 arc [240:300] fillcolor rgb 'black'
set object circle at first 0,0 front size r1 arc [300:360] fillcolor rgb 'magenta'
# Splat a white circle on top to conceal central area
set object circle at first 0,0 front size r2 fillcolor rgb 'white'
plot -10 notitle
您可以使用 Arc 命令在矢量图形中创建环。有关参数的详细信息,请参阅 Mozilla 的路径文档。
使用 ImageMagick,您可以制作-draw
矢量图的任何部分。例子:
convert -size 100x100 xc:transparent -stroke black -strokewidth 1 \
-fill blue -draw 'path "M 10 50 A 40 40 0 0 1 50 10 L 50 20 A 30 30 0 0 0 20 50 Z"' \
-fill red -draw 'path "M 50 10 A 40 40 0 0 1 90 50 L 80 50 A 30 30 0 0 0 50 20 Z"' \
-fill green -draw 'path "M 90 50 A 40 40 0 0 1 10 50 L 20 50 A 30 30 0 0 0 80 50 Z"' \
annulus.png
更新
要创建更加程序化的方法,请使用任何OOP脚本语言。下面是 Python 和Wand的快速示例,但也强烈推荐使用Ruby 和RMagick 。
#!/usr/bin/env python3
import math
from wand.color import Color
from wand.drawing import Drawing
from wand.image import Image
class Annulus(Image):
def __init__(self, inner, outer, padding=5):
self.Ri = inner
self.Ro = outer
side = (outer + padding) * 2
self.midpoint = side/2
super(Annulus, self).__init__(width=side,
height=side,
background=Color("transparent"))
self.format = 'PNG'
def __iadd__(self, segment):
cos_start, cos_end = math.cos(segment.As), math.cos(segment.Ae)
sin_start, sin_end = math.sin(segment.As), math.sin(segment.Ae)
SiX, SiY = self.midpoint + self.Ri * cos_start, self.midpoint + self.Ri * sin_start
SoX, SoY = self.midpoint + self.Ro * cos_start, self.midpoint + self.Ro * sin_start
EiX, EiY = self.midpoint + self.Ri * cos_end, self.midpoint + self.Ri * sin_end
EoX, EoY = self.midpoint + self.Ro * cos_end, self.midpoint + self.Ro * sin_end
with Drawing() as draw:
for key, value in segment.draw_args.items():
setattr(draw, key, value)
draw.path_start()
draw.path_move(to=(SiX, SiY))
draw.path_elliptic_arc(to=(EiX, EiY),
radius=(self.Ri, self.Ri),
clockwise=True)
draw.path_line(to=(EoX, EoY))
draw.path_elliptic_arc(to=(SoX, SoY),
radius=(self.Ro, self.Ro),
clockwise=False)
draw.path_close()
draw.path_finish()
draw(self)
return self
class Segment(object):
def __init__(self, start=0.0, end=0.0, **kwargs):
self.As = start
self.Ae = end
self.draw_args = kwargs
if __name__ == '__main__':
from wand.display import display
ring = Annulus(20, 40)
ring += Segment(start=0,
end=math.pi/2,
fill_color=Color("yellow"))
ring += Segment(start=math.pi/2,
end=math.pi,
fill_color=Color("pink"),
stroke_color=Color("magenta"),
stroke_width=1)
ring += Segment(start=math.pi,
end=0,
fill_color=Color("lime"),
stroke_color=Color("orange"),
stroke_width=4)
display(ring)
由于我更擅长直线思考而不是圆圈思考,我想我会再试一次,一种完全不同的方式......
首先,将我们的圆环画成一条直线,如下所示:
convert -size 45x40 xc:red xc:lime -size 270x40 xc:blue +append line.png
我偷偷地把线段的长度加起来为 360,所以每度有一个像素 - 我的简单大脑可以应付:-) 所以,红色有 45 px(度),45 px(度)石灰和 270 像素(度)的蓝色,它们都附加在一起+append
以形成线条。请注意,第一个-size 45x40
设置会一直持续到后来更改,因此在我将其更改为准备应用于蓝色之前,它适用于红色和石灰线段。
现在我们将这条线绕一个圆弯曲,如下所示:
convert line.png -virtual-pixel White -distort arc 360 result.png
当你习惯了这个概念后,你也可以一次性完成,如下所示:
convert -size 60x40 xc:red xc:lime xc:blue xc:cyan xc:magenta xc:black +append -virtual-pixel White -distort arc 360 result.png
您可以像这样向环形段添加灰色边框:
convert -size 600x400 xc:red xc:lime xc:blue xc:cyan xc:magenta xc:black -bordercolor "rgb(180,180,180)" -border 20 +append -virtual-pixel White -distort arc 360 result.png
如果您想要透明背景上的所有内容,请将white
以上所有内容更改为none
.