How to save an image after changing its resolution in Pygame?

Question:

Currently, I am a beginner when it comes to Pygame, and have been trying to allow the user to hand-draw digits into a canvas. I have managed to get the code to draw and clear the canvas to work. However, the pictures I want to save must be 28 by 28 pixels big. My idea was to save what the user drew on the canvas surface as a PNG file, load it back in, smoothscale that down into 28 by 28 pixels, .blit() that into another surface that is 28 by 28 pixels big, then save it from there.

Here is my code:

import pygame
screen = pygame.display.set_mode((600, 600))
canvas = pygame.Surface((555, 405))
new_res_canvas = pygame.Surface((28, 28))

clock = pygame.time.Clock()
black = [0, 0, 0]
white = [255, 255, 255]
rect_size = 30
out = False
pos_draw_list = []


def predict_screen():
    pygame.image.save(canvas, 'digit_large.png') #img of the canvas with drawing
    predict_img = pygame.image.load('digit_large.png') #load the img
    predict_img = pygame.transform.smoothscale(predict_img.convert_alpha(), (28, 28)) #change it to 28 by 28
    predict_img.blit(new_res_canvas, (28, 28)) #put it onto a surface to save it
    pygame.image.save(new_res_canvas, 'digit.png') #save it

When I check my files, I find that the picture of the user’s drawing (‘digit_large.png’) is correct and working fine. However, the smaller scale picture is completely empty (black). Instead, it should have a black background with a smaller scale version of what the user has drawn. For reference, the canvas the user is drawing on is black, while the user draws 30 by 30 white rectangles.

Asked By: Help_Me_Please

||

Answers:

You have to blit the image at the top right instead of (28, 28). Note, the size of predict_img is just 28×28, so blit at (28, 28) means to blit it completely out of bounds. Also you have to blit predict_img on new_res_canvas, but not the other way around:

predict_img.blit(new_res_canvas, (28, 28))

new_res_canvas.blit(predict_img, (0, 0))

Actually, you don’t need to blit at all if you use the dest_surface argument of pygame.transform.smoothscale():

pygame.transform.smoothscale(
    predict_img.convert_alpha(), (28, 28), dest_surface = new_res_canvas) 
Answered By: Rabbid76