You can create annulus in vector graphics with the Arc command. See Mozilla's Path Document for details on parameter.
With ImageMagick, you could -draw
any part of an vector-graphic. Example:
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

Other great example here, and here
update
To create a more programmatic approach, use any OOP scripting language. Below is quick example with Python & Wand, but Ruby & RMagick are also highly recommended.
#!/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)
