5

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()
xilpex
  • 2,716
  • 2
  • 10
  • 38
Jam_T
  • 75
  • 3

2 Answers2

3

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

cdlane
  • 33,404
  • 4
  • 23
  • 63
  • This is fantastic! Thank you so much, I was completely unaware of tracer() and update(), and now it runs significantly faster! Thank you for taking the time to help me out! Have a fantastic day! :D – Jam_T Jun 25 '20 at 02:20
-2

Here is three main tips :

  1. Avoid concatenating strings with the + operator
  2. Use the map function
  3. Avoid reevaluating functions

https://towardsdatascience.com/3-techniques-to-make-your-python-code-faster-193ffab5eb36[Read this Blog to get more info.][1]