Discuss Scratch

RokCoder
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

Infinite thumbnail zoom project

Background info

I was very impressed by @colinmacc's ZoomQuilt project built upon @Scratch-Minion's Infinite Zoom project (with their links/thumbnais shown below).



I thought the same approach would make for a nice way to display collections of Scratchers' projects. To this aim, I've created a project with accompanying Python script to automate this task! My Infinite RokCoder project can be very easily and quickly remixed using the instructions in this post.



The Python script described below scans through your profile (or specified studio if preferred), collects all the thumbnails and creates transitional costumes which simply replace the ones in the Infinite RokCoder project to make your own remix!

Python script

This is Python script for Python 3.0.
import json
import requests
from pathlib import Path
from sys import stdout
from PIL import Image
def CreateImages(targetName, path, count):
    for index in range(1, count + 1):
        ProgressBar(targetName, 50 + (index - 1) * 50 / count)
        image1 = Image.open(path / ("thumb" + str(index) + ".png"))
        image2 = Image.open(path / ("thumb" + str((index % count) + 1) + ".png"))
        image3 = Image.open(path / ("thumb" + str(((index + 1) % count) + 1) + ".png"))
        for stage in range(0, 4):
            w = 480 * 2**stage
            h = 360 * 2**stage
            image = image1.resize((w, h), Image.ANTIALIAS).crop((w / 2 - 240, h / 2 - 180, w / 2 + 240, h / 2 + 180))
            w = 480 * 2**(stage - 4)
            h = 360 * 2**(stage - 4)
            image.paste(image2.resize(((int)(480 * 2**(stage - 4)), (int)(360 * 2**(stage - 4))), Image.ANTIALIAS), ((int)(240 - w / 2), (int)(180 - h / 2)))
            w = 480 * 2**(stage - 8)
            h = 360 * 2**(stage - 8)
            image.paste(image3.resize(((int)(480 * 2**(stage - 8)), (int)(360 * 2**(stage - 8))), Image.ANTIALIAS), ((int)(240 - w / 2), (int)(180 - h / 2)))
            image.save(path / ("frame" + str(index * 4 + stage - 3) + ".png"))
def ProgressBar(name, percent):
    n = 100
    j = percent / n
    stdout.write('\r')
    stdout.write(name + "[%-20s] %d%%" % ('='*int(20*j), 100*j))
    stdout.flush()
def ParseEndpoint(endpoint, target, isUsername):
    if isUsername:
        pathname = requests.get(endpoint).json()["username"]
        targetName = 'Username: "' + pathname + '" - '
    else:
        pathname = requests.get(endpoint).json()["title"]
        targetName = 'Studio: "' + pathname + '" - '
    endpoint += "/projects"
    projects = []
    offset = 0
    progress = 0
    Path(pathname).mkdir(exist_ok=True)
    path = Path(pathname)
    while True:
        response = requests.get(endpoint + "?offset=" + str(offset) + "&limit=40")
        if not response.json():
            break
        projects += response.json()
        offset += 40
    progressStep = 50 / len(projects)
    projectNum = 1
    for project in projects:
        response = requests.get("https://cdn2.scratch.mit.edu/get_image/project/" + str(project["id"]) + "_480x360.png")
        with (path / ("thumb" + str(projectNum) + ".png")).open("wb") as imageOutput:
            imageOutput.write(response.content)
            projectNum += 1
            progress += progressStep
            ProgressBar(targetName, progress)
    CreateImages(targetName, path, len(projects))
    ProgressBar(targetName, 100)
target = input("Enter username or studio number:")
userEndpoint = "https://api.scratch.mit.edu/users/" + target
studioEndpoint = "https://api.scratch.mit.edu/studios/" + target
response = requests.get(userEndpoint)
validUser = response.status_code == 200
validStudio = False
if target.isnumeric():
    response = requests.get(studioEndpoint)
    validStudio = response.status_code == 200
if validStudio and not validUser:
    ParseEndpoint(studioEndpoint, target, False)
elif not validStudio and validUser:
    ParseEndpoint(userEndpoint, target, True)
elif not (validStudio or validUser):
    print('"' + target + '" is not a valid username or studio id')
else:
    while True:
        targetType = input("Is this (1) a username or (2) a studio?")
        if targetType == "1":
            ParseEndPoint(userEndpoint, target, True)
            break
        elif targetType =="2":
            ParseEndpoint(studioEndpoint, target, False)
            break
If you're new to Python

For Windows:
  1. If you don't have Python on your computer then download the installer from python.org and execute it.
  2. You need a couple of support libraries in order to access the Scratch website data and manipulate the images so go to a command prompt and type py -m pip install requests and then py -m pip install pillow
  3. Highlight all of the Python script (in the window above), copy it to your clipboard, paste it into the text editor of your choice and save the file on your computer as zoom.py
  4. When the instructions tell you to run the Python program, simply double click zoom.py in your file explorer.
For Linux/Mac:
  1. You need a couple of support libraries in order to access the Scratch website data and manipulate the images so go to a terminal and type python3 -m pip install requests and then python3 -m pip install pillow
  2. Highlight all of the Python script (in the window above), copy it to your clipboard, paste it into the text editor of your choice and save the file on your computer as zoom.py
  3. When the instructions tell you to run the Python program, simply open a terminal and enter python3 zoom.py.
Steps to remix your own infinite zoom page
  1. Execute the Python program. This will create a subfolder using your username and fill it with thumb images and frame images. You can delete the thumb images - the frame images are the ones to be used in the Scratch project.

  2. Open the Infinite RokCoder project and hit the remix button.

  3. Select the zoomer sprite, go to costumes, remove all but the first costume and then upload all the frame*.png costumes that were created when you executed the Python script.

  4. Select the thumb sprite, update the thumbnail and frame costumes if you want to and save the project.
Feedback, comments and suggestions

Any feedback, comments and suggestions would be very much appreciated!

Last edited by RokCoder (Aug. 3, 2020 09:49:48)

Boomer001
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

Cool!
Also, you don't have to install the ‘requests’ module, Python has a module pre-installed.
Maximouse
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

Boomer001 wrote:

Cool!
Also, you don't have to install the ‘requests’ module, Python has a module pre-installed.
Requests is better though.
Boomer001
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

Maximouse wrote:

Boomer001 wrote:

Cool!
Also, you don't have to install the ‘requests’ module, Python has a module pre-installed.
Requests is better though.
With what?
Maximouse
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

Boomer001 wrote:

With what?
Simpler API, for example.
Jeffalo
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

i am currently in the process of deleting a bunch of costumes i will edit this with my findings

its very cool project but for some reason mine keeps repeating only 2

id:415217774

Last edited by Jeffalo (Aug. 1, 2020 14:09:33)

--Explosion--
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

Cool! I'll try it out!
RokCoder
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

Jeffalo wrote:

i am currently in the process of deleting a bunch of costumes i will edit this with my findings

its very cool project but for some reason mine keeps repeating only 2

id:415217774
You haven't shared your project. I took a look anyway and noticed you've added six frame*.png costumes and eight thumb*.png costumes. The thumb ones aren't necessary to add to the project - I might update the Python script to delete those after it's finished using them. When I run the Python script here using your profile name I get 32 frame*.png files. Are you sure you only got six?
Jeffalo
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

RokCoder wrote:

Jeffalo wrote:

i am currently in the process of deleting a bunch of costumes i will edit this with my findings

its very cool project but for some reason mine keeps repeating only 2

id:415217774
You haven't shared your project. I took a look anyway and noticed you've added six frame*.png costumes and eight thumb*.png costumes. The thumb ones aren't necessary to add to the project - I might update the Python script to delete those after it's finished using them. When I run the Python script here using your profile name I get 32 frame*.png files. Are you sure you only got six?
yeah, but maybe i messed something up because i ran it and yeah.

but it's a very cool project i must admit. i wish i chose to learn python instead of nodejs because i would love to take it apart and find out how it works. maybe I'll recreate it in nodejs that might be fun
Za-Chary
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

A note in case anyone wants to try this out in the future — I use a Mac, and had to type python3 zoom.py at the terminal. I was not able to run zoom.py by double-clicking it in my file explorer.

Nevertheless, I got it to work eventually! The results are shown here.
RokCoder
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

Jeffalo wrote:

[i wish i chose to learn python instead of nodejs because i would love to take it apart and find out how it works. maybe I'll recreate it in nodejs that might be fun
I rarely code Python just because of a lack of time but it always proves very straightforward and easy to use when I give it a go - there are libraries for everything. The thing I've found about coding is that once you know a few languages really well it gets easier and quicker to pick up new ones. I would suggest not porting it but going through it in Python itself. Add another language to your arsenal.
colinmacc
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

If you get an error saying “No module named ‘PIL’” try doing…

pip install pillow

… then it should work
37_Scratch
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

nvm

Last edited by 37_Scratch (Aug. 18, 2020 16:43:24)

RokCoder
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

37_Scratch wrote:

nvm
If you've successfully run the Python script with your username then follow the instructions in the Steps to remix your own infinite zoom page section.
Cool--Scratcher
Scratcher
100+ posts

Python script to create costumes for infinite thumbnail zoom

This is very interesting. I'll try it out some time
god286
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

Za-Chary wrote:

A note in case anyone wants to try this out in the future — I use a Mac, and had to type python3 zoom.py at the terminal. I was not able to run zoom.py by double-clicking it in my file explorer.

Nevertheless, I got it to work eventually! The results are shown here.
I think if you use something like VS Code you can just go and Run with Debugging.
mysterious-neutron
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

I am not able to find the module PIL. I tried to install it in command prompt but it said No matching distribution for PIL
Maximouse
Scratcher
1000+ posts

Python script to create costumes for infinite thumbnail zoom

mysterious-neutron wrote:

I am not able to find the module PIL. I tried to install it in command prompt but it said No matching distribution for PIL
Try installing Pillow instead (a fork of PIL).
CuckieScratchycuff
Scratcher
100+ posts

Python script to create costumes for infinite thumbnail zoom

  1. Python was stupid so I downgraded from 3.11 to 3.8.
  2. Pillow said a command was deprecated, so I'm glad I got an older version
  3. frame1340.png
bigspeedfpv
Scratcher
500+ posts

Python script to create costumes for infinite thumbnail zoom

CuckieScratchycuff wrote:

  1. Python was stupid so I downgraded from 3.11 to 3.8.
  2. Pillow said a command was deprecated, so I'm glad I got an older version
  3. frame1340.png
this is quite possibly one of the worst lines of thinking I've witnessed

Powered by DjangoBB