Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Turtle recreating image too slow

I got curious and wondered if I could have the pyautogui module detect the color from every few pixels from an image and have turtle recreate them in it's canvas using small circles. I ended up finding a way to make it work, and I liked how the images were turning out! The only issue with my code is that it takes a while to finish. Depending on the size of the image, it can take almost 10-30 minutes to finish. Is there any way to optimize my code? I'm fairly new and have been experimenting with different modules, so I'd greatly appreciate any advice or help! If you need me to clarify anything, I'd be happy tooThis took about 30 minutes?

import time
import turtle
import pyautogui

time.sleep(2)
minimum = pyautogui.position()
print(minimum)
time.sleep(2)
max_x, max_y = pyautogui.position()
print(max_x, max_y)#I use the first point as the top left corner, and the second as the bottom right.

wn = turtle.Screen()
t = turtle.Turtle()
wn.colormode(255)#Allows RGB colors
t.pensize(2)
t.speed(0)
wn.setup(width = 1.0, height = 1.0)
wn.bgcolor("black")
x, y = minimum
min_x, min_y = minimum

def turtlemove(x, y):
    t.pu()
    t.goto(x - 965, 565 - y)#Compared coordinates in pyautogui with positions in turtle so they match.

def circle():
    t.pd()
    t.begin_fill()
    t.circle(2.9)
    t.end_fill()
    t.pu()

screenshot = pyautogui.screenshot()
while x != max_x and y != max_y:
    coordinate = x, y
    color = screenshot.getpixel(coordinate)
    t.pencolor(color)
    t.fillcolor(color)
    turtlemove(x, y)
    circle()
    if x < max_x:
        x += 6
    else:
        x = min_x
        y += 6
        #if y >= max_y:
            #break
print(t.pos())

wn.exitonclick()
like image 385
Jam_T Avatar asked Nov 06 '22 06:11

Jam_T


1 Answers

The most significant change speed-wise below is the use of tracer() and update() to minimize turtle's movements on the screen. You'll be amazed by the difference. However, I also changed the way coordinates are handled, how the dots are drawn, and other stuff:

from time import sleep
from turtle import Screen, Turtle
from pyautogui import position, screenshot

DOT_DIAMETER = 6
CHROME = 14  # borders and other such overhead of turtle window

# Obtain the top left corner, and the bottom right:
print("Move mouse to upper left corner.")
sleep(2)
min_x, min_y = position()
print(min_x, min_y)

print("Move mouse to lower right corner.")
sleep(2)
max_x, max_y = position()
print(max_x, max_y)

screenshot = screenshot()

screen = Screen()
screen.setup(width=max_x - min_x + 1 + CHROME, height=max_y - min_y + 1 + CHROME)
screen.setworldcoordinates(min_x, max_y, max_x, min_y)
screen.bgcolor('black')
screen.colormode(255)
screen.tracer(False)

turtle = Turtle()
turtle.penup()

for y in range(min_y, max_y, DOT_DIAMETER):
    for x in range(min_x, max_x, DOT_DIAMETER):
        coordinate = x, y
        # on my system getpixel() returned four values
        *color, alpha = screenshot.getpixel(coordinate)
        turtle.goto(coordinate)
        turtle.dot(DOT_DIAMETER * 1.333, color)  # * 1.333 for color overlap

    screen.update()

screen.tracer(True)
screen.exitonclick()

I found that screenshot.getpixel() was returning four values on my system, but the turtle colors are only three so I had to do:

*color, alpha = screenshot.getpixel(coordinate)

Which you might need to change back on your system.

enter image description here

like image 77
cdlane Avatar answered Nov 14 '22 22:11

cdlane