J'essaie de dessiner des rectangles épais sur une image en utilisant le module ImageDraw de PIL/oreiller.
J'ai essayé d'utiliser draw.rectangle([x1, y1, x2, y2], outline='yellow', width=3)
mais il ne semble pas aimer le paramètre width.
Je peux imiter ce que je veux faire avec un tas de lignes, mais je me demandais s'il y avait une bonne façon de le faire.
'''
coordinates = [(x1, y1), (x2, y2)]
(x1, y1)
*--------------
| |
| |
| |
| |
| |
| |
--------------*
(x2, y2)
'''
def draw_rectangle(drawing, xy, outline='yellow', width=10):
top_left = xy[0]
bottom_right = xy[1]
top_right = (xy[1][0], xy[0][1])
bottom_left= (xy[0][0], xy[1][1])
drawing.line([top_left, top_right], fill=outline, width=width)
drawing.line([top_right, bottom_right], fill=outline, width=width)
drawing.line([bottom_right, bottom_left], fill=outline, width=width)
drawing.line([bottom_left, top_left], fill=outline, width=width)
UPDATE - Pillow> = 5.3.0 rectangle
supporte désormais l'argument width
: PIL.ImageDraw.ImageDraw.rectangle(xy, fill=None, outline=None, width=0)
Réponse précédente:
Voici une méthode qui dessine un premier rectangle initial, puis d'autres rectangles vers l'intérieur - notez que la largeur de la ligne est pas centrée le long de la bordure.
def draw_rectangle(draw, coordinates, color, width=1):
for i in range(width):
rect_start = (coordinates[0][0] - i, coordinates[0][1] - i)
rect_end = (coordinates[1][0] + i, coordinates[1][1] + i)
draw.rectangle((rect_start, rect_end), outline = color)
# example usage
im = Image.open(image_path)
drawing = ImageDraw.Draw(im)
top_left = (50, 50)
bottom_right = (100, 100)
outline_width = 10
outline_color = "black"
draw_rectangle(drawing, (top_left, bottom_right), color=outline_color, width=outline_width)
Au lieu de quatre lignes, vous pouvez également tracer une ligne avec quatre points, en faisant un rectangle:
def drawrect(drawcontext, xy, outline=None, width=0):
(x1, y1), (x2, y2) = xy
points = (x1, y1), (x2, y1), (x2, y2), (x1, y2), (x1, y1)
drawcontext.line(points, fill=outline, width=width)
# example
from PIL import Image, ImageDraw
im = Image.new("RGB", (150, 150), color="white")
draw = ImageDraw.Draw(im)
drawrect(draw, [(50, 50), (100, 100)], outline="red", width=5)
im.show()
Cette méthode fonctionne avec PIL v1.1.7 et pillow v 5.3.0 sur Ubuntu 18.04. Les coins ne sont pas carrés, mais au moins ils ne sont décalés que de 1/2 pixel contrairement à l'approche consistant à dessiner 4 lignes avec un paramètre de largeur pour créer un rectangle, qui est désactivé d'au moins 1 pixel pour chaque coin. Je pense qu'il y a encore un bug dans l'algorithme de dessin au trait dans pillow/pil.
def drawrect(drawcontext, xy, color=None, width=1):
(x1, y1), (x2, y2) = xy
offset = 1
for i in range(0, width):
drawcontext.rectangle(((x1, y1), (x2, y2)), outline=color)
x1 = x1 - offset
y1 = y1 + offset
x2 = x2 + offset
y2 = y2 - offset
puis dans votre code vous auriez:
# example
from PIL import Image, ImageDraw
im = Image.new("RGB", (150, 150), color="white")
draw = ImageDraw.Draw(im)
drawrect(draw, [(50, 50), (100, 100)], outline="red", width=5)
del draw
im.show()
Merci à gdwarf pour sa solution qui m'a mis sur le chemin de celle-ci.
Le rectangle PIL prend désormais en charge le paramètre width
.
from PIL import Image, ImageDraw
height = width = 800
img = Image.new('RGB', (height, width), (255, 255, 255))
draw = ImageDraw.Draw(img)
draw.rectangle([100,100,500,400], width = 10, outline="#0000ff")
img.show()
Vous pouvez dessiner une vue par exemple:
draw.rectangle([(x, y),(x+w,y+h) ], outline=(0,0,255,255))
draw.rectangle([(x+1, y+1),(x+w-1,y+h-1) ], outline=(0,0,255,255))
draw.rectangle([(x+2, y+2),(x+w-2,y+h-2) ], outline=(0,0,255,255))
...
de cause dans une boucle et une fonction.