How can I make my code more optimised by not drawing a rect on each pixel?

Question:

I am using the cv2.imread() function to make a a level editor in pygame that works with images, the only problem is that cv2.imread() gives me information on pixels thus I can only display one rect per pixel.This makes the code really slow and makes it impossible to work with it. I have tried storing all the values in a list but the problem is in the pygame rect function because it foes not have the ability to display all the pixels with collisions and all.

code:

import sys
import pygame
from pygame import *
import cv2

pygame.init()

screen = pygame.display.set_mode((388, 404))

lib = ['Map1.png']

Read = list(cv2.imread(lib[0]))

clock = pygame.time.Clock()
while True:
    screen.fill((15, 15, 15))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
            
    for i in range(len(Read)):#y coords
        for j in range(len(Read[i])):#x coords
            blue = list(Read[i][j])[0]
            green = list(Read[i][j])[0]
            red = list(Read[i][j])[0]
            if blue > 240 and green > 240 and red > 240:
                pygame.draw.rect(screen, (255,255,255), pygame.Rect(j, i, 32,32))
            else:
                pygame.draw.rect(screen, (0), pygame.Rect(j, i, 32, 32))
        
    pygame.display.update()
    clock.tick(120)

map1:

enter image description here

Asked By: BOOTRE

||

Answers:

I recommend to use pygame.image.load and a pygame.mask.Mask:

  • Create a mask form the surface (pygame.mask.from_surface)
  • Invert the mask (invert())
  • Create a black and whit Surfcae from the mask (to_surface())
  • Scale up the black and white Surface (pygame.transform.scale)
import sys
import pygame
from pygame import *

pygame.init()

screen = pygame.display.set_mode((388, 404))


read_surf = pygame.image.load("Map1.png")
w, h = read_surf.get_size()
mask = pygame.mask.from_surface(read_surf)
# mask.invert() # optional
mask_surf = pygame.transform.scale(mask.to_surface(), (w*32, h*32))

clock = pygame.time.Clock()
while True:
    screen.fill((15, 15, 15))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
            
    screen.blit(mask_surf, (0, 0))
        
    pygame.display.update()
    clock.tick(120)
Answered By: Rabbid76
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.