Drawing an ellipse in Python PIL with line thickness

I am trying to draw a circle on an image using Python. I tried this with PIL, but I would like to specify linewidth . Currently, PIL draws a circle, but the border is too thin.

Here is what I did.

For the test image: I created a 1632 X 1200 image in MS Paint and filled it with green. I called it test_1.jpg . Here is the input file: entrance

 from PIL import Image, ImageDraw im = Image.open('test_1.jpg') width, height = im.size eX, eY = 816,816 #Size of Bounding Box for ellipse bbox = (width/2 - eX/2, height/2 - eY/2, width/2 + eX/2, height/2 + eY/2) draw = ImageDraw.Draw(im) bbox_L = [] for j in range(0,5): bbox_L.append([element+j for element in bbox]) draw.ellipse(tuple(bbox_L[j]), outline ='white') im.show() 

Basically, I tried to draw several circles that would be centered in the same place, but with a different radius. I thought this would create the effect of a thicker line.

However, this leads to the conclusion shown in the attached file below: Output

Problem: As you can see, the lower left and upper right are too thin. In addition, there are gaps between the various circles (see Upper Left and Right Right).

The circle has a different thickness. I watch a circle with uniform thickness.

Question: Is there a way to draw a circle in Python on an image like test_1.jpg using PIL, NumPy, etc. And indicate the thickness of the string?

+6
source share
3 answers

I had the same problem and decided to write a helper function similar to yours. This function draws two concentric ellipses in the black and white layers of the mask, and the intended color of the contours is applied to the original image through the mask. To get smoother results (antialiases), ellipses and a mask are drawn in higher resolution.

Exit with and without smoothing

ellipses with pil

A white ellipse is 20 pixels wide and a black ellipse is 0.5 pixels wide.

Code

 from PIL import Image, ImageDraw def draw_ellipse(image, bounds, width=1, outline='white', antialias=4): """Improved ellipse drawing function, based on PIL.ImageDraw.""" # Use a single channel image (mode='L') as mask. # The size of the mask can be increased relative to the imput image # to get smoother looking results. mask = Image.new( size=[int(dim * antialias) for dim in image.size], mode='L', color='black') draw = ImageDraw.Draw(mask) # draw outer shape in white (color) and inner shape in black (transparent) for offset, fill in (width/-2.0, 'white'), (width/2.0, 'black'): left, top = [(value + offset) * antialias for value in bounds[:2]] right, bottom = [(value - offset) * antialias for value in bounds[2:]] draw.ellipse([left, top, right, bottom], fill=fill) # downsample the mask using PIL.Image.LANCZOS # (a high-quality downsampling filter). mask = mask.resize(image.size, Image.LANCZOS) # paste outline color to input image through the mask image.paste(outline, mask=mask) # green background image image = Image.new(mode='RGB', size=(700, 300), color='green') ellipse_box = [50, 50, 300, 250] # draw a thick white ellipse and a thin black ellipse draw_ellipse(image, ellipse_box, width=20) # draw a thin black line, using higher antialias to preserve finer detail draw_ellipse(image, ellipse_box, outline='black', width=.5, antialias=8) # Lets try without antialiasing ellipse_box[0] += 350 ellipse_box[2] += 350 draw_ellipse(image, ellipse_box, width=20, antialias=1) draw_ellipse(image, ellipse_box, outline='black', width=1, antialias=1) image.show() 

I tested this code only on python 3.4, but I think that it should work with 2.7 without significant changes.

+5
source

A simple (but not pleasant) solution is to draw two circles (smaller with a background color):

 outline = 10 # line thickness draw.ellipse((x1-outline, y1-outline, x2+outline, y2+outline), fill=outline_color) draw.ellipse((x1, y1, x2, y2), fill=background_color) 
+2
source

I don't think there is a way to specify the thickness of the ellipse, but you can probably draw lines on each pixel where the ellipse passes, with the argument width = ...

NB: I'm a stranger, sorry if my English is wrong.

0
source

All Articles