Python 3 Turtle(仅在画布中间渲染一行)

时间:2017-04-18 15:41:15

标签: python python-3.x python-imaging-library turtle-graphics

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

我稍后会考虑到这一点,但我一直遇到一个问题,即所有X像素将在当前Y轴上呈现,直到下一个Y增量;然后前一行只在画布中间正确渲染,后半部分连续呈现一个像素颜色。

Screenshot

依赖关系

  • PIL /枕头== 4.0.0
  • Canvasvg

注意 只要图像托盘是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()

1 个答案:

答案 0 :(得分:1)

我发现您的代码存在问题:

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

此代码在从一行上的最后一个像素移动到下一行的第一个像素时会产生回扫伪像 - 它会过度绘制前一行的一半(将其视为反向的略微斜线)。您的penup()& pendown()在您回到行首之前,笔不会解决此问题。

我已经通过一些更改/优化重写了您的代码 - 看看这个版本是否解决了您的问题:

# 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以避免在内环中进行一些计算;让乌龟看不见,所以你不要浪费时间画它。

通常我会使用标记而非绘图,以便在乌龟中进行此类图像处理,但我发现您需要通过绘图来实现canvasvg.saveall()工作。

此外,这似乎是一个使用setworldcoordinates()避免在Python级别进行坐标数学运算的机会,但是当我尝试这种情况时,我得到了微妙的图像伪像,所以我把它扔了。