Python 3 Turtle(线仅在 canvas 中途呈现)

Python 3 Turtle (line only renders halfway through canvas)

首先,我在滥用 turtle 模块。我有一个循环遍历目录中所有图像的小脚本。然后使用 PIL 读取图像的每个像素的 RGB 值 "scanning"。它将乌龟更改为相对于该像素的颜色,然后将乌龟移动到相对于图像的位置(在 canvas 中)。实际上,我正在使用 turtle 重新创建图像。

我稍后会考虑更多,但我一直 运行 一个问题,即所有 X 像素都将在当前 Y 轴上呈现,直到下一个 Y 增量;那么前一行只能正确渲染 canvas 的一半,而后半部分是连续的一种像素颜色。

依赖关系

备注 只要图像托盘是 RGBA,任何图像都应该可以工作。如果图像有索引色板,脚本就会出错。

脚本

# Imports
import os
import time
from PIL import Image
import turtle
import canvasvg

wn = turtle.Screen()
wn.tracer(0)

pen = turtle.Turtle()
pen.shape("square")
pen.speed(0)

# Load Image
for image in os.listdir('image'):
    # Create Empty Level
    pixel = []
    # Open and process Image with PIL
    im = Image.open("image/" + image)
    width = im.size[0]
    height = im.size[1]
    wn.setup(width+50, height+50)
    pix = im.load()
    # Loop through the Y of the image
    for y in range(height):
        # Loop through the X of the image
        pen.pendown()
        for x in range(width):
            # Get color of pixel, set color of turtle
            color = pix[x,y]
            pen.color((color[0]/255, color[1]/255, color[2]/255))
            # Move turtle
            pen.goto(-(width/2) + x, (height/2) - y)
            # Debug Info
            print(x,y, pix[x,y])
        # Lift pen so there is not a streak across the window
        pen.penup()
        # Update the window
        wn.update()
        # Add delay so computer doesn't crap pants
        time.sleep(1)
    # Save canvas to SVG file
    canvasvg.saveall(image + ".svg",wn._canvas)
    # Reset window for next image.
    wn.reset()

我发现你的代码有问题:

pen.goto(-(width/2) + x, (height/2) - y)

当它从一行的最后一个像素移动到下一行的第一个像素时,这段代码会产生回溯伪影——它透支了前一行的一半(可以把它想象成一条在相反方向上稍微倾斜的线).你的 penup()pendown() 没有解决这个问题,因为在你回到行首之前笔已经落下了。

我已经用一些 changes/optimizations 重写了您的代码 -- 看看这个版本是否解决了您的问题:

# Imports
import os
import time
from turtle import Turtle, Screen
from PIL import Image
import canvasvg

BORDER = 25

wn = Screen()
wn.colormode(255)
wn.tracer(0)

pen = Turtle("square", visible=False)
pen.speed("fastest")
pen.penup() # Lift pen so there is no streak across the window

# Load Image
for image in os.listdir('image'):
    # Open and process Image with PIL
    im = Image.open("image/" + image)
    pix = im.load()

    width, height = im.size
    wn.setup(width + BORDER*2, height + BORDER*2)

    # Loop through the Y of the image
    for y in range(height):

        pen.sety(height/2 - y)
        pen.pendown()

        # Loop through the X of the image
        for x in range(width):
            # Get color of pixel, set color of turtle
            pen.color(pix[x, y])
            # Move turtle
            pen.setx(x - width/2)
            # Debug Info
            # print(x, y, pix[x, y])

        pen.penup()
        # Update the window
        wn.update()
        # Add delay so computer doesn't crap pants
        time.sleep(1)

    # Save canvas to SVG file
    canvasvg.saveall(image + ".svg", wn.getcanvas())
    # Reset window for next image.
    wn.reset()

wn.mainloop()

更改包括:将颜色模式设置为与您的颜色样本相匹配,以避免划分;分别移动笔的 x 和 y 以避免内循环中的一些计算;使乌龟不可见,这样您就不会浪费时间绘制它。

通常我会使用 stamping,而不是 drawing,用于 turtle 中的这种图像工作,但我知道你需要通过绘图来完成 canvasvg.saveall() 工作。

此外,这似乎是使用 setworldcoordinates() 避免在 Python 级别进行坐标数学运算的机会,但是当我尝试这样做时,我得到了细微的图像伪影,所以我扔掉了它。