PyGameExamplesAndAnswers

StackOverflow            reply.it reply.it

“Programmers must avoid leaving false clues that obscure the meaning of code.”
Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship


Blending and transparency

Blending

Related Stack Overflow questions:

The blending mode can be changed by setting the optional special_flags argument of pygame.Surface.blit:

blit(source, dest, area=None, special_flags=0) -> Rect
[…]
New in pygame 1.8: Optional special_flags: BLEND_ADD, BLEND_SUB, BLEND_MULT, BLEND_MIN, BLEND_MAX.
New in pygame 1.8.1: Optional special_flags: 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.
New in pygame 1.9.2: Optional special_flags: BLEND_PREMULTIPLIED
New in pygame 2.0.0: Optional special_flags: BLEND_ALPHA_SDL2 […]

e.g.:

screen.blit(image, (x, y), special_flags = pygame.BLEND_RGBA_SUB)

Unfortunately, Pygame doesn’t have a blending mode that gives the absolute difference of 2 images. However it can be achieved with

MAX(SUB(image1, imgage2), SUB(image2, image1))

image1 = pygame.image.load('image2.png')
image2 = pygame.image.load('image1.png')
temp_image = image1.copy() 
temp_image.blit(image2, (0, 0), special_flags = pygame.BLEND_RGBA_SUB)
final_image = image2.copy() 
final_image.blit(image1, (0, 0), special_flags = pygame.BLEND_RGBA_SUB)
final_image.blit(temp_image, (0, 0), special_flags = pygame.BLEND_RGBA_MAX)

blend mode difference

Transparency

Related Stack Overflow questions:

Fade in and out

Related Stack Overflow questions:

Change color of an image

Change the color of the full image area

Change the brightness, hue, or transparency of an entire image.

Related Stack Overflow questions:

Tint a grayscale image

Related Stack Overflow questions:

remove “duplicate”

Change the color of a surface area (mask)

Related Stack Overflow questions:

If you want to brighten an image, thenA I recommend to add a constant color to the surface. This can be achieved by .fill(), wby the use of the special parameter BLEND_RGB_ADD. If the fill color is black (0, 0, 0) then the image won’t change at all. If the fill color is white (255, 255, 255), then the entire image will become white. e.g.:

image = pygame.image.load(my_imagename)
brighten = 128
image.fill((brighten, brighten, brighten), special_flags=pygame.BLEND_RGB_ADD)

If you want to increase the transparency of the image, then yo can “blend” the image with a transparent color, by the use of the special flag BLEND_RGBA_MULT . Of course you’ve to ensure that the image format provides an alpha channel (e.g. .convert_alpha()):

image = pygame.image.load(my_imagename).convert_alpha()
transparency = 128
image.fill((255, 255, 255, transparency), special_flags=pygame.BLEND_RGBA_MULT)

If you want to change the color of a sprite, you actually need an image

image

and a mask image. The mask image has just 2 color, black and white. The white areas of the mask define the areas in the image whose color needs to be changed:

mask

The following function uses a pygame.Surface object image, pygame.Surface object maskImage and a color (newColor), to create a new Surface. In the new Surface the color of the regions which are defined by maskImage, is changed to newColor:

def changColor(image, maskImage, newColor):
    colouredImage = pygame.Surface(image.get_size())
    colouredImage.fill(newColor)

    masked = maskImage.copy()
    masked.set_colorkey((0, 0, 0))
    masked.blit(colouredImage, (0, 0), None, pygame.BLEND_RGBA_MULT)

    finalImage = image.copy()
    finalImage.blit(masked, (0, 0), None)

    return finalImage

📁 Minimal example - Change color of Surface 3

repl.it/@Rabbid76/PyGame-ChangeColorOfSurfaceArea-3

Trying to make sections of sprite change colour, but whole sprite changes instead

Intersection area

Create 2 pygame.Surface objects with per pixel alpha (pygame.SRCALPHA):

surf1 = pygame.Surface((500, 500), pygame.SRCALPHA)
surf2 = pygame.Surface((500, 500), pygame.SRCALPHA)

Define the center point and radius of the 2 circles:

pos1, rad1 = (250, 200), 100
pos2, rad2 = (250, 250), 80

Draw the circles on the 2 surfaces, with the same color:

pygame.draw.circle(surf1, (255, 0, 0, 255), pos1, rad1)
pygame.draw.circle(surf2, (255, 0, 0, 255), pos2, rad2)

Blend one surface on the other, using the blend mode pygame.BLEND_RGBA_MIN:

surf1.blit(surf2, (0, 0), special_flags = pygame.BLEND_RGBA_MIN)

At this point surf1 contains the intersection area of the 2 circles.

Fill the area of intersection of two Circles in PyGame

To get the outer section, another step is required. Blend surf1 on surf2, using the blend mode pygame.BLEND_RGBA_MIN:

surf2.blit(surf1, (0, 0), special_flags = pygame.BLEND_RGBA_SUB)

Now surf2 contains the the part of circle B which is left if circle A is subtracted:

Fill the area of intersection of two Circles in PyGame


PyGame Negative Color / Surface

You can use pygame.Surface.blit with the special_flag argument BLEND_SUB for this.
Create a completely white image with the same size and subtract the original image:

neg = pygame.Surface(image.get_size())
neg.fill((255, 255, 255))
neg.blit(image, (0, 0), special_flags=pygame.BLEND_SUB)

📁 Minimal example - Fill the area of intersection

repl.it/@Rabbid76/PyGame-CircleIntersection

Fill the area of intersection of two Circles in PyGame Fill the area of intersection of two Circles in PyGame