1421 lines
52 KiB
Python
1421 lines
52 KiB
Python
|
import unittest
|
||
|
import os
|
||
|
import platform
|
||
|
|
||
|
from pygame.tests import test_utils
|
||
|
from pygame.tests.test_utils import example_path
|
||
|
|
||
|
import pygame
|
||
|
import pygame.transform
|
||
|
from pygame.locals import *
|
||
|
|
||
|
|
||
|
def show_image(s, images=[]):
|
||
|
# pygame.display.init()
|
||
|
size = s.get_rect()[2:]
|
||
|
screen = pygame.display.set_mode(size)
|
||
|
screen.blit(s, (0, 0))
|
||
|
pygame.display.flip()
|
||
|
pygame.event.pump()
|
||
|
going = True
|
||
|
idx = 0
|
||
|
while going:
|
||
|
events = pygame.event.get()
|
||
|
for e in events:
|
||
|
if e.type == QUIT:
|
||
|
going = False
|
||
|
if e.type == KEYDOWN:
|
||
|
if e.key in [K_s, K_a]:
|
||
|
if e.key == K_s:
|
||
|
idx += 1
|
||
|
if e.key == K_a:
|
||
|
idx -= 1
|
||
|
s = images[idx]
|
||
|
screen.blit(s, (0, 0))
|
||
|
pygame.display.flip()
|
||
|
pygame.event.pump()
|
||
|
elif e.key in [K_ESCAPE]:
|
||
|
going = False
|
||
|
pygame.display.quit()
|
||
|
pygame.display.init()
|
||
|
|
||
|
|
||
|
def threshold(
|
||
|
return_surf,
|
||
|
surf,
|
||
|
color,
|
||
|
threshold=(0, 0, 0),
|
||
|
diff_color=(0, 0, 0),
|
||
|
change_return=True,
|
||
|
):
|
||
|
"""given the color it makes return_surf only have areas with the given colour."""
|
||
|
|
||
|
width, height = surf.get_width(), surf.get_height()
|
||
|
|
||
|
if change_return:
|
||
|
return_surf.fill(diff_color)
|
||
|
|
||
|
try:
|
||
|
r, g, b = color
|
||
|
except ValueError:
|
||
|
r, g, b, a = color
|
||
|
|
||
|
try:
|
||
|
tr, tg, tb = color
|
||
|
except ValueError:
|
||
|
tr, tg, tb, ta = color
|
||
|
|
||
|
similar = 0
|
||
|
for y in range(height):
|
||
|
for x in range(width):
|
||
|
c1 = surf.get_at((x, y))
|
||
|
|
||
|
if (abs(c1[0] - r) < tr) & (abs(c1[1] - g) < tg) & (abs(c1[2] - b) < tb):
|
||
|
# this pixel is within the threshold.
|
||
|
if change_return:
|
||
|
return_surf.set_at((x, y), c1)
|
||
|
similar += 1
|
||
|
# else:
|
||
|
# print(c1, c2)
|
||
|
|
||
|
return similar
|
||
|
|
||
|
|
||
|
class TransformModuleTest(unittest.TestCase):
|
||
|
def test_scale__alpha(self):
|
||
|
"""see if set_alpha information is kept."""
|
||
|
|
||
|
s = pygame.Surface((32, 32))
|
||
|
s.set_alpha(55)
|
||
|
self.assertEqual(s.get_alpha(), 55)
|
||
|
|
||
|
s = pygame.Surface((32, 32))
|
||
|
s.set_alpha(55)
|
||
|
s2 = pygame.transform.scale(s, (64, 64))
|
||
|
s3 = s.copy()
|
||
|
self.assertEqual(s.get_alpha(), s3.get_alpha())
|
||
|
self.assertEqual(s.get_alpha(), s2.get_alpha())
|
||
|
|
||
|
def test_scale__destination(self):
|
||
|
"""see if the destination surface can be passed in to use."""
|
||
|
|
||
|
s = pygame.Surface((32, 32))
|
||
|
s2 = pygame.transform.scale(s, (64, 64))
|
||
|
s3 = s2.copy()
|
||
|
|
||
|
# Also validate keyword arguments
|
||
|
s3 = pygame.transform.scale(surface=s, size=(64, 64), dest_surface=s3)
|
||
|
pygame.transform.scale(s, (64, 64), s2)
|
||
|
|
||
|
# the wrong size surface is past in. Should raise an error.
|
||
|
self.assertRaises(ValueError, pygame.transform.scale, s, (33, 64), s3)
|
||
|
|
||
|
s = pygame.Surface((32, 32))
|
||
|
s2 = pygame.transform.smoothscale(s, (64, 64))
|
||
|
s3 = s2.copy()
|
||
|
|
||
|
# Also validate keyword arguments
|
||
|
s3 = pygame.transform.smoothscale(surface=s, size=(64, 64), dest_surface=s3)
|
||
|
|
||
|
# the wrong size surface is past in. Should raise an error.
|
||
|
self.assertRaises(ValueError, pygame.transform.smoothscale, s, (33, 64), s3)
|
||
|
|
||
|
def test_scale__vector2(self):
|
||
|
s = pygame.Surface((32, 32))
|
||
|
s2 = pygame.transform.scale(s, pygame.Vector2(64, 64))
|
||
|
s3 = pygame.transform.smoothscale(s, pygame.Vector2(64, 64))
|
||
|
|
||
|
self.assertEqual((64, 64), s2.get_size())
|
||
|
self.assertEqual((64, 64), s3.get_size())
|
||
|
|
||
|
def test_scale__zero_surface_transform(self):
|
||
|
tmp_surface = pygame.transform.scale(pygame.Surface((128, 128)), (0, 0))
|
||
|
self.assertEqual(tmp_surface.get_size(), (0, 0))
|
||
|
tmp_surface = pygame.transform.scale(tmp_surface, (128, 128))
|
||
|
self.assertEqual(tmp_surface.get_size(), (128, 128))
|
||
|
|
||
|
def test_scale_by(self):
|
||
|
s = pygame.Surface((32, 32))
|
||
|
|
||
|
s2 = pygame.transform.scale_by(s, 2)
|
||
|
self.assertEqual((64, 64), s2.get_size())
|
||
|
|
||
|
s2 = pygame.transform.scale_by(s, factor=(2.0, 1.5))
|
||
|
self.assertEqual((64, 48), s2.get_size())
|
||
|
|
||
|
dest = pygame.Surface((64, 48))
|
||
|
pygame.transform.scale_by(s, (2.0, 1.5), dest_surface=dest)
|
||
|
|
||
|
def test_smoothscale_by(self):
|
||
|
s = pygame.Surface((32, 32))
|
||
|
|
||
|
s2 = pygame.transform.smoothscale_by(s, 2)
|
||
|
self.assertEqual((64, 64), s2.get_size())
|
||
|
|
||
|
s2 = pygame.transform.smoothscale_by(s, factor=(2.0, 1.5))
|
||
|
self.assertEqual((64, 48), s2.get_size())
|
||
|
|
||
|
dest = pygame.Surface((64, 48))
|
||
|
pygame.transform.smoothscale_by(s, (2.0, 1.5), dest_surface=dest)
|
||
|
|
||
|
def test_grayscale(self):
|
||
|
s = pygame.Surface((32, 32))
|
||
|
s.fill((255, 0, 0))
|
||
|
|
||
|
s2 = pygame.transform.grayscale(s)
|
||
|
self.assertEqual(pygame.transform.average_color(s2)[0], 76)
|
||
|
self.assertEqual(pygame.transform.average_color(s2)[1], 76)
|
||
|
self.assertEqual(pygame.transform.average_color(s2)[2], 76)
|
||
|
|
||
|
dest = pygame.Surface((32, 32), depth=32)
|
||
|
pygame.transform.grayscale(s, dest)
|
||
|
self.assertEqual(pygame.transform.average_color(dest)[0], 76)
|
||
|
self.assertEqual(pygame.transform.average_color(dest)[1], 76)
|
||
|
self.assertEqual(pygame.transform.average_color(dest)[2], 76)
|
||
|
|
||
|
dest = pygame.Surface((32, 32), depth=32)
|
||
|
s.fill((34, 12, 65))
|
||
|
pygame.transform.grayscale(s, dest)
|
||
|
self.assertEqual(pygame.transform.average_color(dest)[0], 24)
|
||
|
self.assertEqual(pygame.transform.average_color(dest)[1], 24)
|
||
|
self.assertEqual(pygame.transform.average_color(dest)[2], 24)
|
||
|
|
||
|
dest = pygame.Surface((32, 32), depth=32)
|
||
|
s.fill((123, 123, 123))
|
||
|
pygame.transform.grayscale(s, dest)
|
||
|
self.assertIn(pygame.transform.average_color(dest)[0], [123, 122])
|
||
|
self.assertIn(pygame.transform.average_color(dest)[1], [123, 122])
|
||
|
self.assertIn(pygame.transform.average_color(dest)[2], [123, 122])
|
||
|
|
||
|
s = pygame.Surface((32, 32), depth=24)
|
||
|
s.fill((255, 0, 0))
|
||
|
dest = pygame.Surface((32, 32), depth=24)
|
||
|
pygame.transform.grayscale(s, dest)
|
||
|
self.assertEqual(pygame.transform.average_color(dest)[0], 76)
|
||
|
self.assertEqual(pygame.transform.average_color(dest)[1], 76)
|
||
|
self.assertEqual(pygame.transform.average_color(dest)[2], 76)
|
||
|
|
||
|
s = pygame.Surface((32, 32), depth=16)
|
||
|
s.fill((255, 0, 0))
|
||
|
dest = pygame.Surface((32, 32), depth=16)
|
||
|
pygame.transform.grayscale(s, dest)
|
||
|
self.assertEqual(pygame.transform.average_color(dest)[0], 72)
|
||
|
self.assertEqual(pygame.transform.average_color(dest)[1], 76)
|
||
|
self.assertEqual(pygame.transform.average_color(dest)[2], 72)
|
||
|
|
||
|
def test_threshold__honors_third_surface(self):
|
||
|
# __doc__ for threshold as of Tue 07/15/2008
|
||
|
|
||
|
# pygame.transform.threshold(DestSurface, Surface, color, threshold =
|
||
|
# (0,0,0,0), diff_color = (0,0,0,0), change_return = True, Surface =
|
||
|
# None): return num_threshold_pixels
|
||
|
|
||
|
# When given the optional third
|
||
|
# surface, it would use the colors in that rather than the "color"
|
||
|
# specified in the function to check against.
|
||
|
|
||
|
# New in pygame 1.8
|
||
|
|
||
|
################################################################
|
||
|
# Sizes
|
||
|
(w, h) = size = (32, 32)
|
||
|
|
||
|
# the original_color is within the threshold of the threshold_color
|
||
|
threshold = (20, 20, 20, 20)
|
||
|
|
||
|
original_color = (25, 25, 25, 25)
|
||
|
threshold_color = (10, 10, 10, 10)
|
||
|
|
||
|
# Surfaces
|
||
|
original_surface = pygame.Surface(size, pygame.SRCALPHA, 32)
|
||
|
dest_surface = pygame.Surface(size, pygame.SRCALPHA, 32)
|
||
|
|
||
|
# Third surface is used in lieu of 3rd position arg color
|
||
|
third_surface = pygame.Surface(size, pygame.SRCALPHA, 32)
|
||
|
|
||
|
# Color filling
|
||
|
original_surface.fill(original_color)
|
||
|
third_surface.fill(threshold_color)
|
||
|
|
||
|
################################################################
|
||
|
# All pixels for color should be within threshold
|
||
|
#
|
||
|
pixels_within_threshold = pygame.transform.threshold(
|
||
|
dest_surface=None,
|
||
|
surface=original_surface,
|
||
|
search_color=threshold_color,
|
||
|
threshold=threshold,
|
||
|
set_color=None,
|
||
|
set_behavior=0,
|
||
|
)
|
||
|
|
||
|
self.assertEqual(w * h, pixels_within_threshold)
|
||
|
|
||
|
################################################################
|
||
|
# This should respect third_surface colors in place of 3rd arg
|
||
|
# color Should be the same as: surface.fill(threshold_color)
|
||
|
# all within threshold
|
||
|
|
||
|
pixels_within_threshold = pygame.transform.threshold(
|
||
|
dest_surface=None,
|
||
|
surface=original_surface,
|
||
|
search_color=None,
|
||
|
threshold=threshold,
|
||
|
set_color=None,
|
||
|
set_behavior=0,
|
||
|
search_surf=third_surface,
|
||
|
)
|
||
|
self.assertEqual(w * h, pixels_within_threshold)
|
||
|
|
||
|
def test_threshold_dest_surf_not_change(self):
|
||
|
"""the pixels within the threshold.
|
||
|
|
||
|
All pixels not within threshold are changed to set_color.
|
||
|
So there should be none changed in this test.
|
||
|
"""
|
||
|
(w, h) = size = (32, 32)
|
||
|
threshold = (20, 20, 20, 20)
|
||
|
original_color = (25, 25, 25, 25)
|
||
|
original_dest_color = (65, 65, 65, 55)
|
||
|
threshold_color = (10, 10, 10, 10)
|
||
|
set_color = (255, 10, 10, 10)
|
||
|
|
||
|
surf = pygame.Surface(size, pygame.SRCALPHA, 32)
|
||
|
dest_surf = pygame.Surface(size, pygame.SRCALPHA, 32)
|
||
|
search_surf = pygame.Surface(size, pygame.SRCALPHA, 32)
|
||
|
|
||
|
surf.fill(original_color)
|
||
|
search_surf.fill(threshold_color)
|
||
|
dest_surf.fill(original_dest_color)
|
||
|
|
||
|
# set_behavior=1, set dest_surface from set_color.
|
||
|
# all within threshold of third_surface, so no color is set.
|
||
|
|
||
|
THRESHOLD_BEHAVIOR_FROM_SEARCH_COLOR = 1
|
||
|
pixels_within_threshold = pygame.transform.threshold(
|
||
|
dest_surface=dest_surf,
|
||
|
surface=surf,
|
||
|
search_color=None,
|
||
|
threshold=threshold,
|
||
|
set_color=set_color,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_COLOR,
|
||
|
search_surf=search_surf,
|
||
|
)
|
||
|
|
||
|
# # Return, of pixels within threshold is correct
|
||
|
self.assertEqual(w * h, pixels_within_threshold)
|
||
|
|
||
|
# # Size of dest surface is correct
|
||
|
dest_rect = dest_surf.get_rect()
|
||
|
dest_size = dest_rect.size
|
||
|
self.assertEqual(size, dest_size)
|
||
|
|
||
|
# The color is not the change_color specified for every pixel As all
|
||
|
# pixels are within threshold
|
||
|
|
||
|
for pt in test_utils.rect_area_pts(dest_rect):
|
||
|
self.assertNotEqual(dest_surf.get_at(pt), set_color)
|
||
|
self.assertEqual(dest_surf.get_at(pt), original_dest_color)
|
||
|
|
||
|
def test_threshold_dest_surf_all_changed(self):
|
||
|
"""Lowering the threshold, expecting changed surface"""
|
||
|
|
||
|
(w, h) = size = (32, 32)
|
||
|
threshold = (20, 20, 20, 20)
|
||
|
original_color = (25, 25, 25, 25)
|
||
|
original_dest_color = (65, 65, 65, 55)
|
||
|
threshold_color = (10, 10, 10, 10)
|
||
|
set_color = (255, 10, 10, 10)
|
||
|
|
||
|
surf = pygame.Surface(size, pygame.SRCALPHA, 32)
|
||
|
dest_surf = pygame.Surface(size, pygame.SRCALPHA, 32)
|
||
|
search_surf = pygame.Surface(size, pygame.SRCALPHA, 32)
|
||
|
|
||
|
surf.fill(original_color)
|
||
|
search_surf.fill(threshold_color)
|
||
|
dest_surf.fill(original_dest_color)
|
||
|
|
||
|
THRESHOLD_BEHAVIOR_FROM_SEARCH_COLOR = 1
|
||
|
pixels_within_threshold = pygame.transform.threshold(
|
||
|
dest_surf,
|
||
|
surf,
|
||
|
search_color=None,
|
||
|
set_color=set_color,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_COLOR,
|
||
|
search_surf=search_surf,
|
||
|
)
|
||
|
|
||
|
self.assertEqual(0, pixels_within_threshold)
|
||
|
|
||
|
dest_rect = dest_surf.get_rect()
|
||
|
dest_size = dest_rect.size
|
||
|
self.assertEqual(size, dest_size)
|
||
|
|
||
|
# The color is the set_color specified for every pixel As all
|
||
|
# pixels are not within threshold
|
||
|
for pt in test_utils.rect_area_pts(dest_rect):
|
||
|
self.assertEqual(dest_surf.get_at(pt), set_color)
|
||
|
|
||
|
def test_threshold_count(self):
|
||
|
"""counts the colors, and not changes them."""
|
||
|
surf_size = (32, 32)
|
||
|
surf = pygame.Surface(surf_size, pygame.SRCALPHA, 32)
|
||
|
search_surf = pygame.Surface(surf_size, pygame.SRCALPHA, 32)
|
||
|
search_color = (55, 55, 55, 255)
|
||
|
original_color = (10, 10, 10, 255)
|
||
|
|
||
|
surf.fill(original_color)
|
||
|
# set 2 pixels to the color we are searching for.
|
||
|
surf.set_at((0, 0), search_color)
|
||
|
surf.set_at((12, 5), search_color)
|
||
|
|
||
|
# There is no destination surface, but we ask to change it.
|
||
|
# This should be an error.
|
||
|
self.assertRaises(
|
||
|
TypeError, pygame.transform.threshold, None, surf, search_color
|
||
|
)
|
||
|
# from pygame.transform import THRESHOLD_BEHAVIOR_COUNT
|
||
|
THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF = 2
|
||
|
self.assertRaises(
|
||
|
TypeError,
|
||
|
pygame.transform.threshold,
|
||
|
None,
|
||
|
surf,
|
||
|
search_color,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF,
|
||
|
)
|
||
|
|
||
|
THRESHOLD_BEHAVIOR_COUNT = 0
|
||
|
num_threshold_pixels = pygame.transform.threshold(
|
||
|
dest_surface=None,
|
||
|
surface=surf,
|
||
|
search_color=search_color,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_COUNT,
|
||
|
)
|
||
|
self.assertEqual(num_threshold_pixels, 2)
|
||
|
|
||
|
def test_threshold_search_surf(self):
|
||
|
surf_size = (32, 32)
|
||
|
surf = pygame.Surface(surf_size, pygame.SRCALPHA, 32)
|
||
|
search_surf = pygame.Surface(surf_size, pygame.SRCALPHA, 32)
|
||
|
dest_surf = pygame.Surface(surf_size, pygame.SRCALPHA, 32)
|
||
|
|
||
|
original_color = (10, 10, 10, 255)
|
||
|
search_color = (55, 55, 55, 255)
|
||
|
|
||
|
surf.fill(original_color)
|
||
|
dest_surf.fill(original_color)
|
||
|
# set 2 pixels to the color we are searching for.
|
||
|
surf.set_at((0, 0), search_color)
|
||
|
surf.set_at((12, 5), search_color)
|
||
|
|
||
|
search_surf.fill(search_color)
|
||
|
|
||
|
# We look in the other surface for matching colors.
|
||
|
# Change it in dest_surf
|
||
|
THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF = 2
|
||
|
|
||
|
# TypeError: if search_surf is used, search_color should be None
|
||
|
self.assertRaises(
|
||
|
TypeError,
|
||
|
pygame.transform.threshold,
|
||
|
dest_surf,
|
||
|
surf,
|
||
|
search_color,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF,
|
||
|
search_surf=search_surf,
|
||
|
)
|
||
|
|
||
|
# surf, dest_surf, and search_surf should all be the same size.
|
||
|
# Check surface sizes are the same size.
|
||
|
different_sized_surf = pygame.Surface((22, 33), pygame.SRCALPHA, 32)
|
||
|
self.assertRaises(
|
||
|
TypeError,
|
||
|
pygame.transform.threshold,
|
||
|
different_sized_surf,
|
||
|
surf,
|
||
|
search_color=None,
|
||
|
set_color=None,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF,
|
||
|
search_surf=search_surf,
|
||
|
)
|
||
|
|
||
|
self.assertRaises(
|
||
|
TypeError,
|
||
|
pygame.transform.threshold,
|
||
|
dest_surf,
|
||
|
surf,
|
||
|
search_color=None,
|
||
|
set_color=None,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF,
|
||
|
search_surf=different_sized_surf,
|
||
|
)
|
||
|
|
||
|
# We look to see if colors in search_surf are in surf.
|
||
|
num_threshold_pixels = pygame.transform.threshold(
|
||
|
dest_surface=dest_surf,
|
||
|
surface=surf,
|
||
|
search_color=None,
|
||
|
set_color=None,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF,
|
||
|
search_surf=search_surf,
|
||
|
)
|
||
|
|
||
|
num_pixels_within = 2
|
||
|
self.assertEqual(num_threshold_pixels, num_pixels_within)
|
||
|
|
||
|
dest_surf.fill(original_color)
|
||
|
num_threshold_pixels = pygame.transform.threshold(
|
||
|
dest_surf,
|
||
|
surf,
|
||
|
search_color=None,
|
||
|
set_color=None,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF,
|
||
|
search_surf=search_surf,
|
||
|
inverse_set=True,
|
||
|
)
|
||
|
|
||
|
self.assertEqual(num_threshold_pixels, 2)
|
||
|
|
||
|
def test_threshold_inverse_set(self):
|
||
|
"""changes the pixels within the threshold, and not outside."""
|
||
|
surf_size = (32, 32)
|
||
|
_dest_surf = pygame.Surface(surf_size, pygame.SRCALPHA, 32)
|
||
|
_surf = pygame.Surface(surf_size, pygame.SRCALPHA, 32)
|
||
|
|
||
|
dest_surf = _dest_surf # surface we are changing.
|
||
|
surf = _surf # surface we are looking at
|
||
|
search_color = (55, 55, 55, 255) # color we are searching for.
|
||
|
threshold = (0, 0, 0, 0) # within this distance from search_color.
|
||
|
set_color = (245, 245, 245, 255) # color we set.
|
||
|
inverse_set = 1 # pixels within threshold are changed to 'set_color'
|
||
|
|
||
|
original_color = (10, 10, 10, 255)
|
||
|
surf.fill(original_color)
|
||
|
# set 2 pixels to the color we are searching for.
|
||
|
surf.set_at((0, 0), search_color)
|
||
|
surf.set_at((12, 5), search_color)
|
||
|
|
||
|
dest_surf.fill(original_color)
|
||
|
# set 2 pixels to the color we are searching for.
|
||
|
dest_surf.set_at((0, 0), search_color)
|
||
|
dest_surf.set_at((12, 5), search_color)
|
||
|
|
||
|
THRESHOLD_BEHAVIOR_FROM_SEARCH_COLOR = 1
|
||
|
num_threshold_pixels = pygame.transform.threshold(
|
||
|
dest_surf,
|
||
|
surf,
|
||
|
search_color=search_color,
|
||
|
threshold=threshold,
|
||
|
set_color=set_color,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_COLOR,
|
||
|
inverse_set=1,
|
||
|
)
|
||
|
|
||
|
self.assertEqual(num_threshold_pixels, 2)
|
||
|
# only two pixels changed to diff_color.
|
||
|
self.assertEqual(dest_surf.get_at((0, 0)), set_color)
|
||
|
self.assertEqual(dest_surf.get_at((12, 5)), set_color)
|
||
|
|
||
|
# other pixels should be the same as they were before.
|
||
|
# We just check one other pixel, not all of them.
|
||
|
self.assertEqual(dest_surf.get_at((2, 2)), original_color)
|
||
|
|
||
|
# XXX
|
||
|
def test_threshold_non_src_alpha(self):
|
||
|
result = pygame.Surface((10, 10))
|
||
|
s1 = pygame.Surface((10, 10))
|
||
|
s2 = pygame.Surface((10, 10))
|
||
|
s3 = pygame.Surface((10, 10))
|
||
|
s4 = pygame.Surface((10, 10))
|
||
|
|
||
|
x = s1.fill((0, 0, 0))
|
||
|
s1.set_at((0, 0), (32, 20, 0))
|
||
|
|
||
|
x = s2.fill((0, 20, 0))
|
||
|
x = s3.fill((0, 0, 0))
|
||
|
x = s4.fill((0, 0, 0))
|
||
|
s2.set_at((0, 0), (33, 21, 0))
|
||
|
s2.set_at((3, 0), (63, 61, 0))
|
||
|
s3.set_at((0, 0), (112, 31, 0))
|
||
|
s4.set_at((0, 0), (11, 31, 0))
|
||
|
s4.set_at((1, 1), (12, 31, 0))
|
||
|
|
||
|
self.assertEqual(s1.get_at((0, 0)), (32, 20, 0, 255))
|
||
|
self.assertEqual(s2.get_at((0, 0)), (33, 21, 0, 255))
|
||
|
self.assertEqual((0, 0), (s1.get_flags(), s2.get_flags()))
|
||
|
|
||
|
similar_color = (255, 255, 255, 255)
|
||
|
diff_color = (222, 0, 0, 255)
|
||
|
threshold_color = (20, 20, 20, 255)
|
||
|
|
||
|
THRESHOLD_BEHAVIOR_FROM_SEARCH_COLOR = 1
|
||
|
num_threshold_pixels = pygame.transform.threshold(
|
||
|
dest_surface=result,
|
||
|
surface=s1,
|
||
|
search_color=similar_color,
|
||
|
threshold=threshold_color,
|
||
|
set_color=diff_color,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_COLOR,
|
||
|
)
|
||
|
self.assertEqual(num_threshold_pixels, 0)
|
||
|
|
||
|
num_threshold_pixels = pygame.transform.threshold(
|
||
|
dest_surface=result,
|
||
|
surface=s1,
|
||
|
search_color=(40, 40, 0),
|
||
|
threshold=threshold_color,
|
||
|
set_color=diff_color,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_COLOR,
|
||
|
)
|
||
|
self.assertEqual(num_threshold_pixels, 1)
|
||
|
|
||
|
self.assertEqual(result.get_at((0, 0)), diff_color)
|
||
|
|
||
|
def test_threshold__uneven_colors(self):
|
||
|
(w, h) = size = (16, 16)
|
||
|
|
||
|
original_surface = pygame.Surface(size, pygame.SRCALPHA, 32)
|
||
|
dest_surface = pygame.Surface(size, pygame.SRCALPHA, 32)
|
||
|
|
||
|
original_surface.fill(0)
|
||
|
|
||
|
threshold_color_template = [5, 5, 5, 5]
|
||
|
threshold_template = [6, 6, 6, 6]
|
||
|
|
||
|
################################################################
|
||
|
|
||
|
for pos in range(len("rgb")):
|
||
|
threshold_color = threshold_color_template[:]
|
||
|
threshold = threshold_template[:]
|
||
|
|
||
|
threshold_color[pos] = 45
|
||
|
threshold[pos] = 50
|
||
|
|
||
|
pixels_within_threshold = pygame.transform.threshold(
|
||
|
None,
|
||
|
original_surface,
|
||
|
threshold_color,
|
||
|
threshold,
|
||
|
set_color=None,
|
||
|
set_behavior=0,
|
||
|
)
|
||
|
|
||
|
self.assertEqual(w * h, pixels_within_threshold)
|
||
|
|
||
|
################################################################
|
||
|
|
||
|
def test_threshold_set_behavior2(self):
|
||
|
"""raises an error when set_behavior=2 and set_color is not None."""
|
||
|
from pygame.transform import threshold
|
||
|
|
||
|
s1 = pygame.Surface((32, 32), SRCALPHA, 32)
|
||
|
s2 = pygame.Surface((32, 32), SRCALPHA, 32)
|
||
|
THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF = 2
|
||
|
self.assertRaises(
|
||
|
TypeError,
|
||
|
threshold,
|
||
|
dest_surface=s2,
|
||
|
surface=s1,
|
||
|
search_color=(30, 30, 30),
|
||
|
threshold=(11, 11, 11),
|
||
|
set_color=(255, 0, 0),
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF,
|
||
|
)
|
||
|
|
||
|
def test_threshold_set_behavior0(self):
|
||
|
"""raises an error when set_behavior=1
|
||
|
and set_color is not None,
|
||
|
and dest_surf is not None.
|
||
|
"""
|
||
|
from pygame.transform import threshold
|
||
|
|
||
|
s1 = pygame.Surface((32, 32), SRCALPHA, 32)
|
||
|
s2 = pygame.Surface((32, 32), SRCALPHA, 32)
|
||
|
THRESHOLD_BEHAVIOR_COUNT = 0
|
||
|
|
||
|
self.assertRaises(
|
||
|
TypeError,
|
||
|
threshold,
|
||
|
dest_surface=None,
|
||
|
surface=s2,
|
||
|
search_color=(30, 30, 30),
|
||
|
threshold=(11, 11, 11),
|
||
|
set_color=(0, 0, 0),
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_COUNT,
|
||
|
)
|
||
|
|
||
|
self.assertRaises(
|
||
|
TypeError,
|
||
|
threshold,
|
||
|
dest_surface=s1,
|
||
|
surface=s2,
|
||
|
search_color=(30, 30, 30),
|
||
|
threshold=(11, 11, 11),
|
||
|
set_color=None,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_COUNT,
|
||
|
)
|
||
|
|
||
|
threshold(
|
||
|
dest_surface=None,
|
||
|
surface=s2,
|
||
|
search_color=(30, 30, 30),
|
||
|
threshold=(11, 11, 11),
|
||
|
set_color=None,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_COUNT,
|
||
|
)
|
||
|
|
||
|
def test_threshold_from_surface(self):
|
||
|
"""Set similar pixels in 'dest_surf' to color in the 'surf'."""
|
||
|
from pygame.transform import threshold
|
||
|
|
||
|
surf = pygame.Surface((32, 32), SRCALPHA, 32)
|
||
|
dest_surf = pygame.Surface((32, 32), SRCALPHA, 32)
|
||
|
surf_color = (40, 40, 40, 255)
|
||
|
dest_color = (255, 255, 255)
|
||
|
surf.fill(surf_color)
|
||
|
dest_surf.fill(dest_color)
|
||
|
THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF = 2
|
||
|
|
||
|
num_threshold_pixels = threshold(
|
||
|
dest_surface=dest_surf,
|
||
|
surface=surf,
|
||
|
search_color=(30, 30, 30),
|
||
|
threshold=(11, 11, 11),
|
||
|
set_color=None,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF,
|
||
|
inverse_set=1,
|
||
|
)
|
||
|
|
||
|
self.assertEqual(
|
||
|
num_threshold_pixels, dest_surf.get_height() * dest_surf.get_width()
|
||
|
)
|
||
|
self.assertEqual(dest_surf.get_at((0, 0)), surf_color)
|
||
|
|
||
|
def test_threshold__surface(self):
|
||
|
""" """
|
||
|
from pygame.transform import threshold
|
||
|
|
||
|
s1 = pygame.Surface((32, 32), SRCALPHA, 32)
|
||
|
s2 = pygame.Surface((32, 32), SRCALPHA, 32)
|
||
|
s3 = pygame.Surface((1, 1), SRCALPHA, 32)
|
||
|
THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF = 2
|
||
|
|
||
|
# # only one pixel should not be changed.
|
||
|
# s1.fill((40,40,40))
|
||
|
# s2.fill((255,255,255))
|
||
|
# s1.set_at( (0,0), (170, 170, 170) )
|
||
|
# # set the similar pixels in destination surface to the color
|
||
|
# # in the first surface.
|
||
|
# num_threshold_pixels = threshold(
|
||
|
# dest_surface=s2,
|
||
|
# surface=s1,
|
||
|
# search_color=(30,30,30),
|
||
|
# threshold=(11,11,11),
|
||
|
# set_color=None,
|
||
|
# set_behavior=THRESHOLD_BEHAVIOR_FROM_SEARCH_SURF)
|
||
|
|
||
|
# #num_threshold_pixels = threshold(s2, s1, (30,30,30))
|
||
|
# self.assertEqual(num_threshold_pixels, (s1.get_height() * s1.get_width()) -1)
|
||
|
# self.assertEqual(s2.get_at((0,0)), (0,0,0, 255))
|
||
|
# self.assertEqual(s2.get_at((0,1)), (40, 40, 40, 255))
|
||
|
# self.assertEqual(s2.get_at((17,1)), (40, 40, 40, 255))
|
||
|
|
||
|
# # abs(40 - 255) < 100
|
||
|
# #(abs(c1[0] - r) < tr)
|
||
|
|
||
|
# s1.fill((160,160,160))
|
||
|
# s2.fill((255,255,255))
|
||
|
# num_threshold_pixels = threshold(s2, s1, (255,255,255), (100,100,100), (0,0,0), True)
|
||
|
|
||
|
# self.assertEqual(num_threshold_pixels, (s1.get_height() * s1.get_width()))
|
||
|
|
||
|
# only one pixel should not be changed.
|
||
|
s1.fill((40, 40, 40))
|
||
|
s1.set_at((0, 0), (170, 170, 170))
|
||
|
THRESHOLD_BEHAVIOR_COUNT = 0
|
||
|
|
||
|
num_threshold_pixels = threshold(
|
||
|
dest_surface=None,
|
||
|
surface=s1,
|
||
|
search_color=(30, 30, 30),
|
||
|
threshold=(11, 11, 11),
|
||
|
set_color=None,
|
||
|
set_behavior=THRESHOLD_BEHAVIOR_COUNT,
|
||
|
)
|
||
|
|
||
|
# num_threshold_pixels = threshold(s2, s1, (30,30,30))
|
||
|
self.assertEqual(num_threshold_pixels, (s1.get_height() * s1.get_width()) - 1)
|
||
|
|
||
|
# test end markers. 0, and 255
|
||
|
|
||
|
# the pixels are different by 1.
|
||
|
s1.fill((254, 254, 254))
|
||
|
s2.fill((255, 255, 255))
|
||
|
s3.fill((255, 255, 255))
|
||
|
s1.set_at((0, 0), (170, 170, 170))
|
||
|
num_threshold_pixels = threshold(
|
||
|
None, s1, (254, 254, 254), (1, 1, 1), None, THRESHOLD_BEHAVIOR_COUNT
|
||
|
)
|
||
|
self.assertEqual(num_threshold_pixels, (s1.get_height() * s1.get_width()) - 1)
|
||
|
|
||
|
# compare the two surfaces. Should be all but one matching.
|
||
|
num_threshold_pixels = threshold(
|
||
|
None, s1, None, (1, 1, 1), None, THRESHOLD_BEHAVIOR_COUNT, s2
|
||
|
)
|
||
|
self.assertEqual(num_threshold_pixels, (s1.get_height() * s1.get_width()) - 1)
|
||
|
|
||
|
# within (0,0,0) threshold? Should match no pixels.
|
||
|
num_threshold_pixels = threshold(
|
||
|
None, s1, (253, 253, 253), (0, 0, 0), None, THRESHOLD_BEHAVIOR_COUNT
|
||
|
)
|
||
|
self.assertEqual(num_threshold_pixels, 0)
|
||
|
|
||
|
# other surface within (0,0,0) threshold? Should match no pixels.
|
||
|
num_threshold_pixels = threshold(
|
||
|
None, s1, None, (0, 0, 0), None, THRESHOLD_BEHAVIOR_COUNT, s2
|
||
|
)
|
||
|
self.assertEqual(num_threshold_pixels, 0)
|
||
|
|
||
|
def test_threshold__subclassed_surface(self):
|
||
|
"""Ensure threshold accepts subclassed surfaces."""
|
||
|
expected_size = (13, 11)
|
||
|
expected_flags = 0
|
||
|
expected_depth = 32
|
||
|
expected_color = (90, 80, 70, 255)
|
||
|
expected_count = 0
|
||
|
surface = test_utils.SurfaceSubclass(
|
||
|
expected_size, expected_flags, expected_depth
|
||
|
)
|
||
|
dest_surface = test_utils.SurfaceSubclass(
|
||
|
expected_size, expected_flags, expected_depth
|
||
|
)
|
||
|
search_surface = test_utils.SurfaceSubclass(
|
||
|
expected_size, expected_flags, expected_depth
|
||
|
)
|
||
|
surface.fill((10, 10, 10))
|
||
|
dest_surface.fill((255, 255, 255))
|
||
|
search_surface.fill((20, 20, 20))
|
||
|
|
||
|
count = pygame.transform.threshold(
|
||
|
dest_surface=dest_surface,
|
||
|
surface=surface,
|
||
|
threshold=(1, 1, 1),
|
||
|
set_color=expected_color,
|
||
|
search_color=None,
|
||
|
search_surf=search_surface,
|
||
|
)
|
||
|
|
||
|
self.assertIsInstance(dest_surface, pygame.Surface)
|
||
|
self.assertIsInstance(dest_surface, test_utils.SurfaceSubclass)
|
||
|
self.assertEqual(count, expected_count)
|
||
|
self.assertEqual(dest_surface.get_at((0, 0)), expected_color)
|
||
|
self.assertEqual(dest_surface.get_bitsize(), expected_depth)
|
||
|
self.assertEqual(dest_surface.get_size(), expected_size)
|
||
|
self.assertEqual(dest_surface.get_flags(), expected_flags)
|
||
|
|
||
|
def test_laplacian(self):
|
||
|
""" """
|
||
|
|
||
|
SIZE = 32
|
||
|
s1 = pygame.Surface((SIZE, SIZE))
|
||
|
s2 = pygame.Surface((SIZE, SIZE))
|
||
|
s1.fill((10, 10, 70))
|
||
|
pygame.draw.line(s1, (255, 0, 0), (3, 10), (20, 20))
|
||
|
|
||
|
# a line at the last row of the image.
|
||
|
pygame.draw.line(s1, (255, 0, 0), (0, 31), (31, 31))
|
||
|
|
||
|
pygame.transform.laplacian(s1, s2)
|
||
|
|
||
|
# show_image(s1)
|
||
|
# show_image(s2)
|
||
|
|
||
|
self.assertEqual(s2.get_at((0, 0)), (0, 0, 0, 255))
|
||
|
self.assertEqual(s2.get_at((3, 10)), (255, 0, 0, 255))
|
||
|
self.assertEqual(s2.get_at((0, 31)), (255, 0, 0, 255))
|
||
|
self.assertEqual(s2.get_at((31, 31)), (255, 0, 0, 255))
|
||
|
|
||
|
# here we create the return surface.
|
||
|
s2 = pygame.transform.laplacian(s1)
|
||
|
|
||
|
self.assertEqual(s2.get_at((0, 0)), (0, 0, 0, 255))
|
||
|
self.assertEqual(s2.get_at((3, 10)), (255, 0, 0, 255))
|
||
|
self.assertEqual(s2.get_at((0, 31)), (255, 0, 0, 255))
|
||
|
self.assertEqual(s2.get_at((31, 31)), (255, 0, 0, 255))
|
||
|
|
||
|
def test_laplacian__24_big_endian(self):
|
||
|
""" """
|
||
|
pygame.display.init()
|
||
|
try:
|
||
|
surf_1 = pygame.image.load(
|
||
|
example_path(os.path.join("data", "laplacian.png"))
|
||
|
)
|
||
|
SIZE = 32
|
||
|
surf_2 = pygame.Surface((SIZE, SIZE), 0, 24)
|
||
|
# s1.fill((10, 10, 70))
|
||
|
# pygame.draw.line(s1, (255, 0, 0), (3, 10), (20, 20))
|
||
|
|
||
|
# a line at the last row of the image.
|
||
|
# pygame.draw.line(s1, (255, 0, 0), (0, 31), (31, 31))
|
||
|
|
||
|
# Also validate keyword arguments
|
||
|
pygame.transform.laplacian(surface=surf_1, dest_surface=surf_2)
|
||
|
|
||
|
# show_image(s1)
|
||
|
# show_image(s2)
|
||
|
|
||
|
self.assertEqual(surf_2.get_at((0, 0)), (0, 0, 0, 255))
|
||
|
self.assertEqual(surf_2.get_at((3, 10)), (255, 0, 0, 255))
|
||
|
self.assertEqual(surf_2.get_at((0, 31)), (255, 0, 0, 255))
|
||
|
self.assertEqual(surf_2.get_at((31, 31)), (255, 0, 0, 255))
|
||
|
|
||
|
# here we create the return surface.
|
||
|
surf_2 = pygame.transform.laplacian(surf_1)
|
||
|
|
||
|
self.assertEqual(surf_2.get_at((0, 0)), (0, 0, 0, 255))
|
||
|
self.assertEqual(surf_2.get_at((3, 10)), (255, 0, 0, 255))
|
||
|
self.assertEqual(surf_2.get_at((0, 31)), (255, 0, 0, 255))
|
||
|
self.assertEqual(surf_2.get_at((31, 31)), (255, 0, 0, 255))
|
||
|
finally:
|
||
|
pygame.display.quit()
|
||
|
|
||
|
def test_average_surfaces(self):
|
||
|
""" """
|
||
|
|
||
|
SIZE = 32
|
||
|
s1 = pygame.Surface((SIZE, SIZE))
|
||
|
s2 = pygame.Surface((SIZE, SIZE))
|
||
|
s3 = pygame.Surface((SIZE, SIZE))
|
||
|
s1.fill((10, 10, 70))
|
||
|
s2.fill((10, 20, 70))
|
||
|
s3.fill((10, 130, 10))
|
||
|
|
||
|
surfaces = [s1, s2, s3]
|
||
|
surfaces = [s1, s2]
|
||
|
sr = pygame.transform.average_surfaces(surfaces)
|
||
|
|
||
|
self.assertEqual(sr.get_at((0, 0)), (10, 15, 70, 255))
|
||
|
|
||
|
self.assertRaises(TypeError, pygame.transform.average_surfaces, 1)
|
||
|
self.assertRaises(TypeError, pygame.transform.average_surfaces, [])
|
||
|
|
||
|
self.assertRaises(TypeError, pygame.transform.average_surfaces, [1])
|
||
|
self.assertRaises(TypeError, pygame.transform.average_surfaces, [s1, 1])
|
||
|
self.assertRaises(TypeError, pygame.transform.average_surfaces, [1, s1])
|
||
|
self.assertRaises(TypeError, pygame.transform.average_surfaces, [s1, s2, 1])
|
||
|
|
||
|
self.assertRaises(
|
||
|
TypeError, pygame.transform.average_surfaces, (s for s in [s1, s2, s3])
|
||
|
)
|
||
|
|
||
|
def test_average_surfaces__24(self):
|
||
|
SIZE = 32
|
||
|
depth = 24
|
||
|
s1 = pygame.Surface((SIZE, SIZE), 0, depth)
|
||
|
s2 = pygame.Surface((SIZE, SIZE), 0, depth)
|
||
|
s3 = pygame.Surface((SIZE, SIZE), 0, depth)
|
||
|
s1.fill((10, 10, 70, 255))
|
||
|
s2.fill((10, 20, 70, 255))
|
||
|
s3.fill((10, 130, 10, 255))
|
||
|
|
||
|
surfaces = [s1, s2, s3]
|
||
|
sr = pygame.transform.average_surfaces(surfaces)
|
||
|
self.assertEqual(sr.get_masks(), s1.get_masks())
|
||
|
self.assertEqual(sr.get_flags(), s1.get_flags())
|
||
|
self.assertEqual(sr.get_losses(), s1.get_losses())
|
||
|
|
||
|
if 0:
|
||
|
print(sr, s1)
|
||
|
print(sr.get_masks(), s1.get_masks())
|
||
|
print(sr.get_flags(), s1.get_flags())
|
||
|
print(sr.get_losses(), s1.get_losses())
|
||
|
print(sr.get_shifts(), s1.get_shifts())
|
||
|
|
||
|
self.assertEqual(sr.get_at((0, 0)), (10, 53, 50, 255))
|
||
|
|
||
|
def test_average_surfaces__24_big_endian(self):
|
||
|
pygame.display.init()
|
||
|
try:
|
||
|
surf_1 = pygame.image.load(example_path(os.path.join("data", "BGR.png")))
|
||
|
|
||
|
surf_2 = surf_1.copy()
|
||
|
|
||
|
surfaces = [surf_1, surf_2]
|
||
|
self.assertEqual(surf_1.get_at((0, 0)), (255, 0, 0, 255))
|
||
|
self.assertEqual(surf_2.get_at((0, 0)), (255, 0, 0, 255))
|
||
|
|
||
|
surf_av = pygame.transform.average_surfaces(surfaces)
|
||
|
self.assertEqual(surf_av.get_masks(), surf_1.get_masks())
|
||
|
self.assertEqual(surf_av.get_flags(), surf_1.get_flags())
|
||
|
self.assertEqual(surf_av.get_losses(), surf_1.get_losses())
|
||
|
|
||
|
self.assertEqual(surf_av.get_at((0, 0)), (255, 0, 0, 255))
|
||
|
finally:
|
||
|
pygame.display.quit()
|
||
|
|
||
|
def test_average_surfaces__subclassed_surfaces(self):
|
||
|
"""Ensure average_surfaces accepts subclassed surfaces."""
|
||
|
expected_size = (23, 17)
|
||
|
expected_flags = 0
|
||
|
expected_depth = 32
|
||
|
expected_color = (50, 50, 50, 255)
|
||
|
surfaces = []
|
||
|
|
||
|
for color in ((40, 60, 40), (60, 40, 60)):
|
||
|
s = test_utils.SurfaceSubclass(
|
||
|
expected_size, expected_flags, expected_depth
|
||
|
)
|
||
|
s.fill(color)
|
||
|
surfaces.append(s)
|
||
|
|
||
|
surface = pygame.transform.average_surfaces(surfaces)
|
||
|
|
||
|
self.assertIsInstance(surface, pygame.Surface)
|
||
|
self.assertNotIsInstance(surface, test_utils.SurfaceSubclass)
|
||
|
self.assertEqual(surface.get_at((0, 0)), expected_color)
|
||
|
self.assertEqual(surface.get_bitsize(), expected_depth)
|
||
|
self.assertEqual(surface.get_size(), expected_size)
|
||
|
self.assertEqual(surface.get_flags(), expected_flags)
|
||
|
|
||
|
def test_average_surfaces__subclassed_destination_surface(self):
|
||
|
"""Ensure average_surfaces accepts a destination subclassed surface."""
|
||
|
expected_size = (13, 27)
|
||
|
expected_flags = 0
|
||
|
expected_depth = 32
|
||
|
expected_color = (15, 15, 15, 255)
|
||
|
surfaces = []
|
||
|
|
||
|
for color in ((10, 10, 20), (20, 20, 10), (30, 30, 30)):
|
||
|
s = test_utils.SurfaceSubclass(
|
||
|
expected_size, expected_flags, expected_depth
|
||
|
)
|
||
|
s.fill(color)
|
||
|
surfaces.append(s)
|
||
|
expected_dest_surface = surfaces.pop()
|
||
|
|
||
|
# Also validate keyword arguments
|
||
|
dest_surface = pygame.transform.average_surfaces(
|
||
|
surfaces=surfaces, dest_surface=expected_dest_surface
|
||
|
)
|
||
|
|
||
|
self.assertIsInstance(dest_surface, pygame.Surface)
|
||
|
self.assertIsInstance(dest_surface, test_utils.SurfaceSubclass)
|
||
|
self.assertIs(dest_surface, expected_dest_surface)
|
||
|
self.assertEqual(dest_surface.get_at((0, 0)), expected_color)
|
||
|
self.assertEqual(dest_surface.get_bitsize(), expected_depth)
|
||
|
self.assertEqual(dest_surface.get_size(), expected_size)
|
||
|
self.assertEqual(dest_surface.get_flags(), expected_flags)
|
||
|
|
||
|
def test_average_color(self):
|
||
|
""" """
|
||
|
for i in (24, 32):
|
||
|
with self.subTest(f"Testing {i}-bit surface"):
|
||
|
s = pygame.Surface((32, 32), 0, i)
|
||
|
s.fill((0, 100, 200))
|
||
|
s.fill((10, 50, 100), (0, 0, 16, 32))
|
||
|
|
||
|
self.assertEqual(pygame.transform.average_color(s), (5, 75, 150, 0))
|
||
|
|
||
|
# Also validate keyword arguments
|
||
|
avg_color = pygame.transform.average_color(
|
||
|
surface=s, rect=(16, 0, 16, 32)
|
||
|
)
|
||
|
self.assertEqual(avg_color, (0, 100, 200, 0))
|
||
|
|
||
|
def test_average_color_considering_alpha_all_pixels_opaque(self):
|
||
|
""" """
|
||
|
s = pygame.Surface((32, 32), pygame.SRCALPHA, 32)
|
||
|
s.fill((0, 100, 200, 255))
|
||
|
s.fill((10, 50, 100, 255), (0, 0, 16, 32))
|
||
|
|
||
|
self.assertEqual(
|
||
|
pygame.transform.average_color(s, consider_alpha=True), (5, 75, 150, 255)
|
||
|
)
|
||
|
|
||
|
# Also validate keyword arguments
|
||
|
avg_color = pygame.transform.average_color(
|
||
|
surface=s, rect=(16, 0, 16, 32), consider_alpha=True
|
||
|
)
|
||
|
self.assertEqual(avg_color, (0, 100, 200, 255))
|
||
|
|
||
|
def test_average_color_considering_alpha(self):
|
||
|
""" """
|
||
|
s = pygame.Surface((32, 32), pygame.SRCALPHA, 32)
|
||
|
s.fill((0, 100, 200, 255))
|
||
|
s.fill((10, 50, 100, 128), (0, 0, 16, 32))
|
||
|
|
||
|
# formula for this example of half filled square
|
||
|
# n = number of pixels, e.g. 32 * 32
|
||
|
# rgb = (n/2 * ( a_left * rgb_left) + n/2 (a_right * rgb_right) ) / (n/2 * a_left + n/2 * a_right)
|
||
|
# a = (n/2 * a_left + n/2 * a_right) / n
|
||
|
self.assertEqual(
|
||
|
pygame.transform.average_color(s, consider_alpha=True), (3, 83, 166, 191)
|
||
|
)
|
||
|
|
||
|
# Also validate keyword arguments
|
||
|
avg_color = pygame.transform.average_color(
|
||
|
surface=s, rect=(0, 0, 16, 32), consider_alpha=True
|
||
|
)
|
||
|
self.assertEqual(avg_color, (10, 50, 100, 128))
|
||
|
|
||
|
def test_rotate(self):
|
||
|
# setting colors and canvas
|
||
|
blue = (0, 0, 255, 255)
|
||
|
red = (255, 0, 0, 255)
|
||
|
black = (0, 0, 0)
|
||
|
canvas = pygame.Surface((3, 3))
|
||
|
rotation = 0
|
||
|
|
||
|
canvas.set_at((2, 0), blue)
|
||
|
canvas.set_at((0, 2), red)
|
||
|
|
||
|
self.assertEqual(canvas.get_at((0, 0)), black)
|
||
|
self.assertEqual(canvas.get_at((2, 0)), blue)
|
||
|
self.assertEqual(canvas.get_at((0, 2)), red)
|
||
|
|
||
|
for i in range(0, 4):
|
||
|
if i % 2 == 0:
|
||
|
self.assertEqual(canvas.get_at((0, 0)), black)
|
||
|
elif i == 1:
|
||
|
self.assertEqual(canvas.get_at((0, 0)), blue)
|
||
|
elif i == 3:
|
||
|
self.assertEqual(canvas.get_at((0, 0)), red)
|
||
|
|
||
|
rotation += 90
|
||
|
# Also validate keyword arguments
|
||
|
canvas = pygame.transform.rotate(surface=canvas, angle=90)
|
||
|
|
||
|
self.assertEqual(canvas.get_at((0, 0)), black)
|
||
|
|
||
|
def test_rotate_of_0_sized_surface(self):
|
||
|
# This function just tests possible Segmentation Fault
|
||
|
canvas1 = pygame.Surface((0, 1))
|
||
|
canvas2 = pygame.Surface((1, 0))
|
||
|
pygame.transform.rotate(canvas1, 42)
|
||
|
pygame.transform.rotate(canvas2, 42)
|
||
|
|
||
|
def test_rotate__lossless_at_90_degrees(self):
|
||
|
w, h = 32, 32
|
||
|
s = pygame.Surface((w, h), pygame.SRCALPHA)
|
||
|
|
||
|
gradient = list(test_utils.gradient(w, h))
|
||
|
|
||
|
for pt, color in gradient:
|
||
|
s.set_at(pt, color)
|
||
|
|
||
|
for rotation in (90, -90):
|
||
|
s = pygame.transform.rotate(s, rotation)
|
||
|
|
||
|
for pt, color in gradient:
|
||
|
self.assertTrue(s.get_at(pt) == color)
|
||
|
|
||
|
def test_scale2x(self):
|
||
|
# __doc__ (as of 2008-06-25) for pygame.transform.scale2x:
|
||
|
|
||
|
# pygame.transform.scale2x(Surface, DestSurface = None): Surface
|
||
|
# specialized image doubler
|
||
|
|
||
|
w, h = 32, 32
|
||
|
s = pygame.Surface((w, h), pygame.SRCALPHA, 32)
|
||
|
|
||
|
# s.set_at((0,0), (20, 20, 20, 255))
|
||
|
|
||
|
s1 = pygame.transform.scale2x(s)
|
||
|
# Also validate keyword arguments
|
||
|
s2 = pygame.transform.scale2x(surface=s)
|
||
|
self.assertEqual(s1.get_rect().size, (64, 64))
|
||
|
self.assertEqual(s2.get_rect().size, (64, 64))
|
||
|
|
||
|
def test_scale2xraw(self):
|
||
|
w, h = 32, 32
|
||
|
s = pygame.Surface((w, h), pygame.SRCALPHA, 32)
|
||
|
s.fill((0, 0, 0))
|
||
|
pygame.draw.circle(s, (255, 0, 0), (w // 2, h // 2), (w // 3))
|
||
|
|
||
|
s2 = pygame.transform.scale(s, (w * 2, h * 2))
|
||
|
s2_2 = pygame.transform.scale(s2, (w * 4, h * 4))
|
||
|
s4 = pygame.transform.scale(s, (w * 4, h * 4))
|
||
|
|
||
|
self.assertEqual(s2_2.get_rect().size, (128, 128))
|
||
|
|
||
|
for pt in test_utils.rect_area_pts(s2_2.get_rect()):
|
||
|
self.assertEqual(s2_2.get_at(pt), s4.get_at(pt))
|
||
|
|
||
|
def test_get_smoothscale_backend(self):
|
||
|
filter_type = pygame.transform.get_smoothscale_backend()
|
||
|
self.assertTrue(filter_type in ["GENERIC", "MMX", "SSE"])
|
||
|
# It would be nice to test if a non-generic type corresponds to an x86
|
||
|
# processor. But there is no simple test for this. platform.machine()
|
||
|
# returns process version specific information, like 'i686'.
|
||
|
|
||
|
def test_set_smoothscale_backend(self):
|
||
|
# All machines should allow 'GENERIC'.
|
||
|
original_type = pygame.transform.get_smoothscale_backend()
|
||
|
pygame.transform.set_smoothscale_backend("GENERIC")
|
||
|
filter_type = pygame.transform.get_smoothscale_backend()
|
||
|
self.assertEqual(filter_type, "GENERIC")
|
||
|
# All machines should allow returning to original value.
|
||
|
# Also check that keyword argument works.
|
||
|
pygame.transform.set_smoothscale_backend(backend=original_type)
|
||
|
|
||
|
# Something invalid.
|
||
|
def change():
|
||
|
pygame.transform.set_smoothscale_backend("mmx")
|
||
|
|
||
|
self.assertRaises(ValueError, change)
|
||
|
|
||
|
# Invalid argument keyword.
|
||
|
def change():
|
||
|
pygame.transform.set_smoothscale_backend(t="GENERIC")
|
||
|
|
||
|
self.assertRaises(TypeError, change)
|
||
|
|
||
|
# Invalid argument type.
|
||
|
def change():
|
||
|
pygame.transform.set_smoothscale_backend(1)
|
||
|
|
||
|
self.assertRaises(TypeError, change)
|
||
|
# Unsupported type, if possible.
|
||
|
if original_type != "SSE":
|
||
|
|
||
|
def change():
|
||
|
pygame.transform.set_smoothscale_backend("SSE")
|
||
|
|
||
|
self.assertRaises(ValueError, change)
|
||
|
# Should be back where we started.
|
||
|
filter_type = pygame.transform.get_smoothscale_backend()
|
||
|
self.assertEqual(filter_type, original_type)
|
||
|
|
||
|
def test_chop(self):
|
||
|
original_surface = pygame.Surface((20, 20))
|
||
|
pygame.draw.rect(original_surface, (255, 0, 0), (0, 0, 10, 10))
|
||
|
pygame.draw.rect(original_surface, (0, 255, 0), (0, 10, 10, 10))
|
||
|
pygame.draw.rect(original_surface, (0, 0, 255), (10, 0, 10, 10))
|
||
|
pygame.draw.rect(original_surface, (255, 255, 0), (10, 10, 10, 10))
|
||
|
# Test chopping the corner of image
|
||
|
rect = pygame.Rect(0, 0, 5, 15)
|
||
|
test_surface = pygame.transform.chop(original_surface, rect)
|
||
|
# Check the size of chopped image
|
||
|
self.assertEqual(test_surface.get_size(), (15, 5))
|
||
|
# Check if the colors of the chopped image are correct
|
||
|
for x in range(15):
|
||
|
for y in range(5):
|
||
|
if x < 5:
|
||
|
self.assertEqual(test_surface.get_at((x, y)), (0, 255, 0))
|
||
|
else:
|
||
|
self.assertEqual(test_surface.get_at((x, y)), (255, 255, 0))
|
||
|
# Check if the original image stayed the same
|
||
|
self.assertEqual(original_surface.get_size(), (20, 20))
|
||
|
for x in range(20):
|
||
|
for y in range(20):
|
||
|
if x < 10 and y < 10:
|
||
|
self.assertEqual(original_surface.get_at((x, y)), (255, 0, 0))
|
||
|
if x < 10 < y:
|
||
|
self.assertEqual(original_surface.get_at((x, y)), (0, 255, 0))
|
||
|
if x > 10 > y:
|
||
|
self.assertEqual(original_surface.get_at((x, y)), (0, 0, 255))
|
||
|
if x > 10 and y > 10:
|
||
|
self.assertEqual(original_surface.get_at((x, y)), (255, 255, 0))
|
||
|
# Test chopping the center of the surface:
|
||
|
rect = pygame.Rect(0, 0, 10, 10)
|
||
|
rect.center = original_surface.get_rect().center
|
||
|
# Also validate keyword arguments
|
||
|
test_surface = pygame.transform.chop(surface=original_surface, rect=rect)
|
||
|
self.assertEqual(test_surface.get_size(), (10, 10))
|
||
|
for x in range(10):
|
||
|
for y in range(10):
|
||
|
if x < 5 and y < 5:
|
||
|
self.assertEqual(test_surface.get_at((x, y)), (255, 0, 0))
|
||
|
if x < 5 < y:
|
||
|
self.assertEqual(test_surface.get_at((x, y)), (0, 255, 0))
|
||
|
if x > 5 > y:
|
||
|
self.assertEqual(test_surface.get_at((x, y)), (0, 0, 255))
|
||
|
if x > 5 and y > 5:
|
||
|
self.assertEqual(test_surface.get_at((x, y)), (255, 255, 0))
|
||
|
# Test chopping with the empty rect
|
||
|
rect = pygame.Rect(10, 10, 0, 0)
|
||
|
test_surface = pygame.transform.chop(original_surface, rect)
|
||
|
self.assertEqual(test_surface.get_size(), (20, 20))
|
||
|
# Test chopping the entire surface
|
||
|
rect = pygame.Rect(0, 0, 20, 20)
|
||
|
test_surface = pygame.transform.chop(original_surface, rect)
|
||
|
self.assertEqual(test_surface.get_size(), (0, 0))
|
||
|
# Test chopping outside of surface
|
||
|
rect = pygame.Rect(5, 15, 20, 20)
|
||
|
test_surface = pygame.transform.chop(original_surface, rect)
|
||
|
self.assertEqual(test_surface.get_size(), (5, 15))
|
||
|
rect = pygame.Rect(400, 400, 10, 10)
|
||
|
test_surface = pygame.transform.chop(original_surface, rect)
|
||
|
self.assertEqual(test_surface.get_size(), (20, 20))
|
||
|
|
||
|
def test_rotozoom(self):
|
||
|
# __doc__ (as of 2008-08-02) for pygame.transform.rotozoom:
|
||
|
|
||
|
# pygame.transform.rotozoom(Surface, angle, scale): return Surface
|
||
|
# filtered scale and rotation
|
||
|
#
|
||
|
# This is a combined scale and rotation transform. The resulting
|
||
|
# Surface will be a filtered 32-bit Surface. The scale argument is a
|
||
|
# floating point value that will be multiplied by the current
|
||
|
# resolution. The angle argument is a floating point value that
|
||
|
# represents the counterclockwise degrees to rotate. A negative
|
||
|
# rotation angle will rotate clockwise.
|
||
|
|
||
|
s = pygame.Surface((10, 0))
|
||
|
pygame.transform.scale(s, (10, 2))
|
||
|
s1 = pygame.transform.rotozoom(s, 30, 1)
|
||
|
# Also validate keyword arguments
|
||
|
s2 = pygame.transform.rotozoom(surface=s, angle=30, scale=1)
|
||
|
|
||
|
self.assertEqual(s1.get_rect(), pygame.Rect(0, 0, 0, 0))
|
||
|
self.assertEqual(s2.get_rect(), pygame.Rect(0, 0, 0, 0))
|
||
|
|
||
|
def test_smoothscale(self):
|
||
|
"""Tests the stated boundaries, sizing, and color blending of smoothscale function"""
|
||
|
# __doc__ (as of 2008-08-02) for pygame.transform.smoothscale:
|
||
|
|
||
|
# pygame.transform.smoothscale(Surface, (width, height), DestSurface =
|
||
|
# None): return Surface
|
||
|
#
|
||
|
# scale a surface to an arbitrary size smoothly
|
||
|
#
|
||
|
# Uses one of two different algorithms for scaling each dimension of
|
||
|
# the input surface as required. For shrinkage, the output pixels are
|
||
|
# area averages of the colors they cover. For expansion, a bilinear
|
||
|
# filter is used. For the amd64 and i686 architectures, optimized MMX
|
||
|
# routines are included and will run much faster than other machine
|
||
|
# types. The size is a 2 number sequence for (width, height). This
|
||
|
# function only works for 24-bit or 32-bit surfaces. An exception
|
||
|
# will be thrown if the input surface bit depth is less than 24.
|
||
|
#
|
||
|
# New in pygame 1.8
|
||
|
|
||
|
# check stated exceptions
|
||
|
def smoothscale_low_bpp():
|
||
|
starting_surface = pygame.Surface((20, 20), depth=12)
|
||
|
smoothscaled_surface = pygame.transform.smoothscale(
|
||
|
starting_surface, (10, 10)
|
||
|
)
|
||
|
|
||
|
self.assertRaises(ValueError, smoothscale_low_bpp)
|
||
|
|
||
|
def smoothscale_high_bpp():
|
||
|
starting_surface = pygame.Surface((20, 20), depth=48)
|
||
|
smoothscaled_surface = pygame.transform.smoothscale(
|
||
|
starting_surface, (10, 10)
|
||
|
)
|
||
|
|
||
|
self.assertRaises(ValueError, smoothscale_high_bpp)
|
||
|
|
||
|
def smoothscale_invalid_scale():
|
||
|
starting_surface = pygame.Surface((20, 20), depth=32)
|
||
|
smoothscaled_surface = pygame.transform.smoothscale(
|
||
|
starting_surface, (-1, -1)
|
||
|
)
|
||
|
|
||
|
self.assertRaises(ValueError, smoothscale_invalid_scale)
|
||
|
|
||
|
# Test Color Blending Scaling-Up
|
||
|
two_pixel_surface = pygame.Surface((2, 1), depth=32)
|
||
|
two_pixel_surface.fill(pygame.Color(0, 0, 0), pygame.Rect(0, 0, 1, 1))
|
||
|
two_pixel_surface.fill(pygame.Color(255, 255, 255), pygame.Rect(1, 0, 1, 1))
|
||
|
for k in [2**x for x in range(5, 8)]: # Enlarge to targets 32, 64...256
|
||
|
bigger_surface = pygame.transform.smoothscale(two_pixel_surface, (k, 1))
|
||
|
self.assertEqual(
|
||
|
bigger_surface.get_at((k // 2, 0)), pygame.Color(127, 127, 127)
|
||
|
)
|
||
|
self.assertEqual(bigger_surface.get_size(), (k, 1))
|
||
|
# Test Color Blending Scaling-Down
|
||
|
two_five_six_surf = pygame.Surface((256, 1), depth=32)
|
||
|
two_five_six_surf.fill(pygame.Color(0, 0, 0), pygame.Rect(0, 0, 128, 1))
|
||
|
two_five_six_surf.fill(pygame.Color(255, 255, 255), pygame.Rect(128, 0, 128, 1))
|
||
|
for k in range(3, 11, 2): # Shrink to targets 3, 5...11 pixels wide
|
||
|
smaller_surface = pygame.transform.smoothscale(two_five_six_surf, (k, 1))
|
||
|
self.assertEqual(
|
||
|
smaller_surface.get_at(((k // 2), 0)), pygame.Color(127, 127, 127)
|
||
|
)
|
||
|
self.assertEqual(smaller_surface.get_size(), (k, 1))
|
||
|
|
||
|
|
||
|
class TransformDisplayModuleTest(unittest.TestCase):
|
||
|
def setUp(self):
|
||
|
pygame.display.init()
|
||
|
pygame.display.set_mode((320, 200))
|
||
|
|
||
|
def tearDown(self):
|
||
|
pygame.display.quit()
|
||
|
|
||
|
def test_flip(self):
|
||
|
"""honors the set_color key on the returned surface from flip."""
|
||
|
image_loaded = pygame.image.load(example_path("data/chimp.png"))
|
||
|
|
||
|
image = pygame.Surface(image_loaded.get_size(), 0, 32)
|
||
|
image.blit(image_loaded, (0, 0))
|
||
|
|
||
|
image_converted = image_loaded.convert()
|
||
|
|
||
|
self.assertFalse(image.get_flags() & pygame.SRCALPHA)
|
||
|
self.assertFalse(image_converted.get_flags() & pygame.SRCALPHA)
|
||
|
|
||
|
surf = pygame.Surface(image.get_size(), 0, 32)
|
||
|
surf2 = pygame.Surface(image.get_size(), 0, 32)
|
||
|
|
||
|
surf.fill((255, 255, 255))
|
||
|
surf2.fill((255, 255, 255))
|
||
|
|
||
|
colorkey = image.get_at((0, 0))
|
||
|
image.set_colorkey(colorkey, RLEACCEL)
|
||
|
timage = pygame.transform.flip(image, 1, 0)
|
||
|
|
||
|
colorkey = image_converted.get_at((0, 0))
|
||
|
image_converted.set_colorkey(colorkey, RLEACCEL)
|
||
|
# Also validate keyword arguments
|
||
|
timage_converted = pygame.transform.flip(
|
||
|
surface=image_converted, flip_x=1, flip_y=0
|
||
|
)
|
||
|
|
||
|
# blit the flipped surface, and non flipped surface.
|
||
|
surf.blit(timage, (0, 0))
|
||
|
surf2.blit(image, (0, 0))
|
||
|
|
||
|
# the results should be the same.
|
||
|
self.assertEqual(surf.get_at((0, 0)), surf2.get_at((0, 0)))
|
||
|
self.assertEqual(surf2.get_at((0, 0)), (255, 255, 255, 255))
|
||
|
|
||
|
# now we test the convert() ed image also works.
|
||
|
surf.fill((255, 255, 255))
|
||
|
surf2.fill((255, 255, 255))
|
||
|
surf.blit(timage_converted, (0, 0))
|
||
|
surf2.blit(image_converted, (0, 0))
|
||
|
self.assertEqual(surf.get_at((0, 0)), surf2.get_at((0, 0)))
|
||
|
|
||
|
def test_flip_alpha(self):
|
||
|
"""returns a surface with the same properties as the input."""
|
||
|
image_loaded = pygame.image.load(example_path("data/chimp.png"))
|
||
|
|
||
|
image_alpha = pygame.Surface(image_loaded.get_size(), pygame.SRCALPHA, 32)
|
||
|
image_alpha.blit(image_loaded, (0, 0))
|
||
|
|
||
|
surf = pygame.Surface(image_loaded.get_size(), 0, 32)
|
||
|
surf2 = pygame.Surface(image_loaded.get_size(), 0, 32)
|
||
|
|
||
|
colorkey = image_alpha.get_at((0, 0))
|
||
|
image_alpha.set_colorkey(colorkey, RLEACCEL)
|
||
|
timage_alpha = pygame.transform.flip(image_alpha, 1, 0)
|
||
|
|
||
|
self.assertTrue(image_alpha.get_flags() & pygame.SRCALPHA)
|
||
|
self.assertTrue(timage_alpha.get_flags() & pygame.SRCALPHA)
|
||
|
|
||
|
# now we test the alpha image works.
|
||
|
surf.fill((255, 255, 255))
|
||
|
surf2.fill((255, 255, 255))
|
||
|
surf.blit(timage_alpha, (0, 0))
|
||
|
surf2.blit(image_alpha, (0, 0))
|
||
|
self.assertEqual(surf.get_at((0, 0)), surf2.get_at((0, 0)))
|
||
|
self.assertEqual(surf2.get_at((0, 0)), (255, 0, 0, 255))
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
unittest.main()
|