gpt4 book ai didi

python - 从 PIL 中绘制点线或虚线矩形

转载 作者:行者123 更新时间:2023-12-02 02:36:16 24 4
gpt4 key购买 nike

我想使用PIL绘制一个虚线矩形。

我知道我可以绘制 4 条不同的虚线,使其看起来像一个矩形:

for x in range(0, Width_of_image, 5):
d.line([(x, 30), (x + 2, 30)],fill ="black", width =2)

但是有没有办法使用draw.rectangle绘制一个矩形,即不绘制4条不同的线?

最佳答案

正如其他用户所说,PIL 库(特别是 PIL.ImageDraw.ImageDraw)不提供绘制虚线的功能。我查看了StackOverflow问题(以及其他地方)有关PIL中虚线的问题,但我还没有找到在PIL中绘制虚线的令人满意的方法。我找到的答案都没有以预期的方式绘制虚线(其他 Python 库提供虚线的方式,例如使用 Tkinter canvas )。

所以我编写了类DashedImageDraw(它扩展了PIL.ImageDraw.ImageDraw),它具有绘制虚线和虚线矩形的功能。以下是代码和如何使用它的示例:

from PIL import Image, ImageDraw
import math


class DashedImageDraw(ImageDraw.ImageDraw):

def thick_line(self, xy, direction, fill=None, width=0):
#xy – Sequence of 2-tuples like [(x, y), (x, y), ...]
#direction – Sequence of 2-tuples like [(x, y), (x, y), ...]
if xy[0] != xy[1]:
self.line(xy, fill = fill, width = width)
else:
x1, y1 = xy[0]
dx1, dy1 = direction[0]
dx2, dy2 = direction[1]
if dy2 - dy1 < 0:
x1 -= 1
if dx2 - dx1 < 0:
y1 -= 1
if dy2 - dy1 != 0:
if dx2 - dx1 != 0:
k = - (dx2 - dx1)/(dy2 - dy1)
a = 1/math.sqrt(1 + k**2)
b = (width*a - 1) /2
else:
k = 0
b = (width - 1)/2
x3 = x1 - math.floor(b)
y3 = y1 - int(k*b)
x4 = x1 + math.ceil(b)
y4 = y1 + int(k*b)
else:
x3 = x1
y3 = y1 - math.floor((width - 1)/2)
x4 = x1
y4 = y1 + math.ceil((width - 1)/2)
self.line([(x3, y3), (x4, y4)], fill = fill, width = 1)
return

def dashed_line(self, xy, dash=(2,2), fill=None, width=0):
#xy – Sequence of 2-tuples like [(x, y), (x, y), ...]
for i in range(len(xy) - 1):
x1, y1 = xy[i]
x2, y2 = xy[i + 1]
x_length = x2 - x1
y_length = y2 - y1
length = math.sqrt(x_length**2 + y_length**2)
dash_enabled = True
postion = 0
while postion <= length:
for dash_step in dash:
if postion > length:
break
if dash_enabled:
start = postion/length
end = min((postion + dash_step - 1) / length, 1)
self.thick_line([(round(x1 + start*x_length),
round(y1 + start*y_length)),
(round(x1 + end*x_length),
round(y1 + end*y_length))],
xy, fill, width)
dash_enabled = not dash_enabled
postion += dash_step
return

def dashed_rectangle(self, xy, dash=(2,2), outline=None, width=0):
#xy - Sequence of [(x1, y1), (x2, y2)] where (x1, y1) is top left corner and (x2, y2) is bottom right corner
x1, y1 = xy[0]
x2, y2 = xy[1]
halfwidth1 = math.floor((width - 1)/2)
halfwidth2 = math.ceil((width - 1)/2)
min_dash_gap = min(dash[1::2])
end_change1 = halfwidth1 + min_dash_gap + 1
end_change2 = halfwidth2 + min_dash_gap + 1
odd_width_change = (width - 1)%2
self.dashed_line([(x1 - halfwidth1, y1), (x2 - end_change1, y1)],
dash, outline, width)
self.dashed_line([(x2, y1 - halfwidth1), (x2, y2 - end_change1)],
dash, outline, width)
self.dashed_line([(x2 + halfwidth2, y2 + odd_width_change),
(x1 + end_change2, y2 + odd_width_change)],
dash, outline, width)
self.dashed_line([(x1 + odd_width_change, y2 + halfwidth2),
(x1 + odd_width_change, y1 + end_change2)],
dash, outline, width)
return



image = Image.new('RGB', (300, 200), (255, 255, 255))
d = DashedImageDraw(image)

d.dashed_rectangle([(20, 20), (280, 180)],
dash = (5, 3), outline = 'black', width = 2)

image.save("image.png", "PNG")

这条线绘制了矩形:

d.dashed_rectangle([(20, 20), (280, 180)], dash = (5, 3), outline  = 'black', width = 2)

(20, 20) 是左上角,(280, 180) 是右下角,outline 是颜色线的宽度,width 是线的宽度,dash 是表示虚线模式的元组。例如:

  • dash = (5, 3) 将画线:

    ----- ----- ----- ----- ----- -----

  • dash = (4, 2, 3, 1) 将绘制线条:

    ---- --- ---- --- ---- --- ---- --- ----

这是上面代码生成的虚线矩形的图像:

Dashed rectangle

关于python - 从 PIL 中绘制点线或虚线矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64276513/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com