Python PILLOW如何绘制虚线或点线?

8
如何使用Python PILLOW绘制虚线或点线的线条或矩形。 有人可以帮我吗?使用openCV我可以做到。但我想使用Pillow。

1
你能否发布一个你尝试过的并且出现问题的例子? - payne
2
据我所知,pillow 不直接支持此功能。您可以编写自己的函数,使用 ImageDraw.line() 来绘制多个短线段以模拟效果。另一个可能性是使用 tkinter 模块,它支持虚线,进行绘图,然后将结果保存到 pillow 图像中——请参阅 如何将画布内容转换为图像? 了解如何实现。 - martineau
如果你真的很热衷,你可以使用Bresenham线段绘制算法来绘制你的线条,并在每次推进y坐标时反转填充颜色。https://en.m.wikipedia.org/wiki/Bresenham%27s_line_algorithm - Mark Setchell
1
@martineau 感谢您的评论。我使用ImageDraw.Draw.point()编写了自己的函数来绘制虚线。 - prosenjit
prosenjit:听到这个消息很好...不用谢。我建议你将代码发布为自己问题的答案并接受它。在这里,你是被允许这样做的——更重要的是,它会提供代码,其他有类似需求的人可能会使用。 - martineau
显示剩余2条评论
4个回答

3

感谢@martineau的评论,我弄清了如何画虚线。这是我的代码。

cur_x = 0
cur_y = 0
image_width = 600
for x in range(cur_x, image_width, 4):
    draw.line([(x, cur_y), (x + 2, cur_y)], fill=(170, 170, 170))

这会绘制一条灰色的虚线。


0
我决定将我在评论中提出的想法写下来 - 即用实线绘制形状,然后叠加阈值噪声图像以消除部分线条。我在较小的图像上制造了所有噪声,然后将其放大,使噪声更加聚集而不是小斑点。因此,这只是测试图像的生成:
#!/usr/local/bin/python3

import numpy as np
from PIL import Image, ImageDraw

# Make empty black image
im = Image.new('L', (640,480))

# Draw white rectangle and ellipse
draw = ImageDraw.Draw(im)
draw.rectangle([20,20,620,460],outline=255)
draw.ellipse([100,100,540,380],outline=255)

这会生成噪声叠加层并将其覆盖 - 您可以删除此句并将两个代码块连接在一起:
# Make noisy overlay, 1/4 the size, threshold at 50%, scale up to full-size
noise = np.random.randint(0,256,(120,160),dtype=np.uint8)
noise = (noise>128)*255
noiseim = Image.fromarray(noise.astype(np.uint8))
noiseim = noiseim.resize((640,480), resample=Image.NEAREST)

# Paste the noise in, but only allowing the white shape outlines to be affected
im.paste(noiseim,mask=im)
im.save('result.png')

结果是这样的:

enter image description here

实心图像如下:

enter image description here

这句话的意思是:“噪声就像这样:”(保留了HTML格式)。

enter image description here


0

我知道这个问题有点老(在我写这篇答案时已经4年了),但恰好我需要画一个带图案的线。

所以我在这里想出了自己的解决方案:https://codereview.stackexchange.com/questions/281582/algorithm-to-traverse-a-path-through-several-data-points-and-draw-a-patterned-li

(抱歉,解决方案有点长,最好去那里看看。不过代码是可行的,这就是为什么它在CodeReview SE中的原因)。

提供正确的“模式字典”,其中空白段由将color设置为None来表示,然后你就可以开始了。


0
下面的函数绘制了一条虚线。它可能会比较慢,但是它能够正常工作,而且我需要它。
"dashlen" 是虚线的长度,以像素为单位。 "ratio" 是空白间隔与虚线长度的比例(数值越高,空白间隔越大)。
import math # math has the fastest sqrt

def linedashed(x0, y0, x1, y1, dashlen=4, ratio=3): 
    dx=x1-x0 # delta x
    dy=y1-y0 # delta y
    # check whether we can avoid sqrt
    if dy==0: vlen=dx
    elif dx==0: vlen=dy
    else: vlen=math.sqrt(dx*dx+dy*dy) # length of line
    xa=dx/vlen # x add for 1px line length
    ya=dy/vlen # y add for 1px line length
    step=dashlen*ratio # step to the next dash
    a0=0
    while a0<vlen:
        a1=a0+dashlen
        if a1>vlen: a1=vlen
        draw.line((x0+xa*a0, y0+ya*a0, x0+xa*a1, y0+ya*a1), fill = (0,0,0))
        a0+=step 

1
不要使用变量名len来表示长度。这是一个内置函数名称。 - thoroc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接