德玛西亚99
PIL 不提供绘制箭头的简单方法,因此我建议将PIL Image转换为NumPy数组,并使用OpenCV、Matplotlib、Cairo或Wand在其上绘制箭头,然后转换回PIL Image:#!/usr/bin/env python3import cv2import numpy as npfrom PIL import Image# Create an empty solid blue imagew, h = 640, 480im = Image.new('RGB', (w,h), (0,0,255))# Make into Numpy array so we can use OpenCV drawing functionsna = np.array(im)# Draw arrowed line, from 10,20 to w-40,h-60 in black with thickness 8 pixelsna = cv2.arrowedLine(na, (10,20), (w-40, h-60), (0,0,0), 8)# Revert back to PIL Image and saveImage.fromarray(na).save('result.png')请注意,OpenCV 使用 BGR 而不是 RGB 排序,因此如果您想要 PIL 中的红线,则需要在 OpenCV 中使用(0, 0, 255) 。如果您真的非常想使用PIL绘制带有箭头的线,您可以绘制一条线,然后在其末端添加一个三角形,draw.polygon()如下所示:#!/usr/bin/env python3import mathimport randomfrom PIL import Image, ImageDrawdef 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 imagew, h = 640, 480im = Image.new('RGB', (w,h), (0,0,255))# Get some controlled randomnessrandom.seed(58)# Draw some random arrowsfor _ 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)# Saveim.save('result.png')关键词:Python、图像处理、PIL、Pillow、箭头、箭头、箭头线、OpenCV。