1 回答

TA貢獻(xiàn)1770條經(jīng)驗(yàn) 獲得超3個贊
PIL 不提供繪制箭頭的簡單方法,因此我建議將PIL?Image
轉(zhuǎn)換為NumPy數(shù)組,并使用OpenCV、Matplotlib、Cairo或Wand在其上繪制箭頭,然后轉(zhuǎn)換回PIL?Image
:
#!/usr/bin/env python3
import cv2
import numpy as np
from PIL import Image
# Create an empty solid blue image
w, h = 640, 480
im = Image.new('RGB', (w,h), (0,0,255))
# Make into Numpy array so we can use OpenCV drawing functions
na = np.array(im)
# Draw arrowed line, from 10,20 to w-40,h-60 in black with thickness 8 pixels
na = cv2.arrowedLine(na, (10,20), (w-40, h-60), (0,0,0), 8)
# Revert back to PIL Image and save
Image.fromarray(na).save('result.png')
請注意,OpenCV 使用 BGR 而不是 RGB 排序,因此如果您想要 PIL 中的紅線,則需要在 OpenCV 中使用(0, 0, 255) 。
如果您真的非常想使用PIL繪制帶有箭頭的線,您可以繪制一條線,然后在其末端添加一個三角形,draw.polygon()如下所示:
#!/usr/bin/env python3
import math
import random
from PIL import Image, ImageDraw
def arrowedLine(im, ptA, ptB, width=1, color=(0,255,0)):
? ? """Draw line from ptA to ptB with arrowhead at ptB"""
? ? # Get drawing context
? ? draw = ImageDraw.Draw(im)
? ? # Draw the line without arrows
? ? draw.line((ptA,ptB), width=width, fill=color)
? ? # Now work out the arrowhead
? ? # = it will be a triangle with one vertex at ptB
? ? # - it will start at 95% of the length of the line
? ? # - it will extend 8 pixels either side of the line
? ? x0, y0 = ptA
? ? x1, y1 = ptB
? ? # Now we can work out the x,y coordinates of the bottom of the arrowhead triangle
? ? xb = 0.95*(x1-x0)+x0
? ? yb = 0.95*(y1-y0)+y0
? ? # Work out the other two vertices of the triangle
? ? # Check if line is vertical
? ? if x0==x1:
? ? ? ?vtx0 = (xb-5, yb)
? ? ? ?vtx1 = (xb+5, yb)
? ? # Check if line is horizontal
? ? elif y0==y1:
? ? ? ?vtx0 = (xb, yb+5)
? ? ? ?vtx1 = (xb, yb-5)
? ? else:
? ? ? ?alpha = math.atan2(y1-y0,x1-x0)-90*math.pi/180
? ? ? ?a = 8*math.cos(alpha)
? ? ? ?b = 8*math.sin(alpha)
? ? ? ?vtx0 = (xb+a, yb+b)
? ? ? ?vtx1 = (xb-a, yb-b)
? ? #draw.point((xb,yb), fill=(255,0,0))? ? # DEBUG: draw point of base in red - comment out draw.polygon() below if using this line
? ? #im.save('DEBUG-base.png')? ? ? ? ? ? ? # DEBUG: save
? ? # Now draw the arrowhead triangle
? ? draw.polygon([vtx0, vtx1, ptB], fill=color)
? ? return im
# Create an empty solid blue image
w, h = 640, 480
im = Image.new('RGB', (w,h), (0,0,255))
# Get some controlled randomness
random.seed(58)
# Draw some random arrows
for _ in range(10):
? ? ptA = (random.randint(0,w), random.randint(0,h))
? ? ptB = (random.randint(0,w), random.randint(0,h))
? ? im = arrowedLine(im, ptA, ptB)
# Save
im.save('result.png')
關(guān)鍵詞:Python、圖像處理、PIL、Pillow、箭頭、箭頭、箭頭線、OpenCV。
添加回答
舉報(bào)