3

I have a 64*64px image of a tree:

small image of a tree

I wanted to resize this image for a full screen mode during runtime. I have tried to write some code for this (see below). After executing this program

import pygame, sys

pygame.init()

info = pygame.display.Info()
WINDOWHEIGHT = info.current_h
WINDOWWIDTH = info.current_w

DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),pygame.FULLSCREEN)

spriteImage = pygame.image.load('Sprite-0003.png')
spriteSurf = pygame.Surface((WINDOWWIDTH,WINDOWHEIGHT))
pygame.transform.scale(spriteImage, (WINDOWWIDTH,WINDOWHEIGHT), spriteSurf)

def close():
    pygame.quit()
    sys.exit()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            close()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                close()

    DISPLAYSURF.blit(spriteSurf, (0,0))
    pygame.display.update()

I get this result image. Compare their colors:

same image, resized

At what point did my program decide to change the color of the two images? And how do I fix it?

Jongware
  • 22,200
  • 8
  • 54
  • 100

2 Answers2

3

First: have a look at pygame.image.load():

For alpha transparency, like in .png images use the convert_alpha() method after loading so that the image has per pixel transparency.

http://www.pygame.org/docs/ref/image.html#pygame.image.load

Second: Blit function from documentation and stack overflow explanation of each flag:

  1. Documentation:

blit(source, dest, area=None, special_flags = 0) -> Rect

An optional special flags is for passing in new in 1.8.0: BLEND_ADD, BLEND_SUB, BLEND_MULT, BLEND_MIN, BLEND_MAX new in 1.8.1: BLEND_RGBA_ADD, BLEND_RGBA_SUB, BLEND_RGBA_MULT, BLEND_RGBA_MIN, BLEND_RGBA_MAX BLEND_RGB_ADD, BLEND_RGB_SUB, BLEND_RGB_MULT, BLEND_RGB_MIN, BLEND_RGB_MAX With other special blitting flags perhaps added in the future.

For a surface with colorkey or blanket alpha, a blit to self may give slightly different colors than a non self-blit.

  1. Stack overflow explanation of each flag:

Basically, ADD adds the two source pixels and clips the result at 255. SUB subtracts the two pixels and clips at 0.

MULT: result = (p1 * p2) / 256

MIN: Select the lower value of each channel (not the whole pixel), so if pixel1 is (100,10,0) and pixel2 is (0,10,100), you get (0,10,0)

MAX: Opposite of MIN (i.e. (100,10,100))

And there is an additional blend mode which isn't obvious from the docs: 0 (or just leave the parameter out). This mode will "stamp" source surface into the destination. If the source surface has an alpha channel, this will be determine how "strong" each pixel is (0=no effect, 255=copy pixel, 128: result = .5*source + .5*destination).

Useful effects: To darken a certain area, use blend mode 0, fill the source/stamp surface black and set alpha to 10: (0,0,0,10).

To lighten it, use white (255,255,255,10).

I think your problem came from alpha channel.

So:

spriteImage = pygame.image.load('Sprite-0003.png').convert_alpha()

Fom:

http://www.pygame.org/docs/ref/surface.html#pygame.Surface.blit

What do the blend modes in pygame mean?

Community
  • 1
  • 1
Destrif
  • 2,104
  • 1
  • 14
  • 22
0

Your source Surface (from the image) and your target Surface don't use the same colorkeys.

Using the default constructor pygame.Surgafe you get a Surface without default colokeys.

Surfaces can have many extra attributes like alpha planes, colorkeys, source rectangle clipping. These functions mainly effect how the Surface is blitted to other Surfaces. The blit routines will attempt to use hardware acceleration when possible, otherwise they will use highly optimized software blitting methods.

Let's consider copying the colokeys, or (best) cloning the image Surface and scale it.

Laurent LAPORTE
  • 21,958
  • 6
  • 58
  • 103
  • I've added this codeline `spriteSurf.set_colorkey(spriteImage.get_colorkey())`, but with not effect at all. I am not sure how a transparent colorkey could possibly affect this anyway. – ClassicEndingMusic Jul 04 '16 at 12:23