带有 Python PILLOW 的虚线或虚线

Posted

技术标签:

【中文标题】带有 Python PILLOW 的虚线或虚线【英文标题】:Dotted or dashed line with Python PILLOW 【发布时间】:2019-01-25 06:34:39 【问题描述】:

如何使用 Python PILLOW 绘制虚线或虚线或矩形。谁能帮我?使用 openCV 我可以做到这一点。但我希望它使用 Pillow。

【问题讨论】:

您能否发布一个示例,说明您尝试过的方法和无效的方法? AFIK, pillow 不直接支持这一点。您可以编写自己的函数,使用ImageDraw.line() 绘制多个短线段来模拟效果,另一种可能是使用支持虚线的tkinter 模块进行绘制,然后将结果保存到枕头之后的图像 - 请参阅 How can I convert canvas content to an image? 了解如何做到这一点。 嗨@payne 我用 draw.polygon(pts, outline=color) 绘制多边形。但我想要虚线或虚线轮廓。 如果你真的很热衷,你可以使用 Bresenham 的 Line Drawing 算法来绘制你的线条并在每次推进 y 坐标时反转填充颜色en.m.wikipedia.org/wiki/Bresenham%27s_line_algorithm @martineau 感谢您的评论。我使用 ImageDraw.Draw.point() 编写了自己的函数来绘制虚线。 【参考方案1】:

感谢@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))

这将绘制一条灰色虚线。

【讨论】:

【参考方案2】:

我决定写下我在 cmets 中提出的想法 - 即用实线绘制形状,然后覆盖阈值噪声图像以消除部分线条。

我在较小的图像上制作了所有噪点,然后将其放大,使噪点“更聚集”,而不是微小的斑点。

所以这只是测试图像的生成:

#!/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')

结果是这样的:

实心绘制的图像是这样的:

噪音是这样的:

【讨论】:

【参考方案3】:

以下函数绘制虚线。它可能很慢,但它有效,我需要它。

“dashlen”是虚线的长度,以像素为单位。 - “比率”是空白空间与破折号长度的比率(值越高,您获得的空白空间越多)

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: len=dx
    elif dx==0: len=dy
    else: len=math.sqrt(dx*dx+dy*dy) # length of line
    xa=dx/len # x add for 1px line length
    ya=dy/len # y add for 1px line length
    step=dashlen*ratio # step to the next dash
    a0=0
    while a0<len:
        a1=a0+dashlen
        if a1>len: a1=len
        draw.line((x0+xa*a0, y0+ya*a0, x0+xa*a1, y0+ya*a1), fill = (0,0,0))
        a0+=step 

【讨论】:

以上是关于带有 Python PILLOW 的虚线或虚线的主要内容,如果未能解决你的问题,请参考以下文章

带有虚线或虚线边框的 Plotly 条形图 - 如何实现?

带有两种颜色的 SVG/CSS 笔划虚线 - 有可能吗?

带有灰色和黑色虚线的线图

使用 Python 分割数据并用实线和虚线绘制它们

如何在相应的滚动上获得虚线(带有向下箭头图标)SVG动画?

绘制 svg 虚线的动画