From fb8134618ece9fef92c4a652e78ef1f22f634578 Mon Sep 17 00:00:00 2001 From: Andrew Coffey <49015102+oddbookworm@users.noreply.github.com> Date: Wed, 26 Jul 2023 22:46:14 -0500 Subject: [PATCH 01/10] added pygame.transform.pixelate --- buildconfig/stubs/pygame/transform.pyi | 5 ++ docs/reST/ref/transform.rst | 15 ++++ src_c/doc/transform_doc.h | 1 + src_c/transform.c | 112 +++++++++++++++++++++++++ 4 files changed, 133 insertions(+) diff --git a/buildconfig/stubs/pygame/transform.pyi b/buildconfig/stubs/pygame/transform.pyi index 9a462dfb0a..6bb1eeac4c 100644 --- a/buildconfig/stubs/pygame/transform.pyi +++ b/buildconfig/stubs/pygame/transform.pyi @@ -35,6 +35,11 @@ def set_smoothscale_backend(backend: str) -> None: ... def chop(surface: Surface, rect: RectValue) -> Surface: ... def laplacian(surface: Surface, dest_surface: Optional[Surface] = None) -> Surface: ... def invert(surface: Surface, dest_surface: Optional[Surface] = None) -> Surface: ... +def pixelate( + surface: Surface, + pixel_size: int, + dest_surface: Optional[Surface] = None +) -> Surface: ... def average_surfaces( surfaces: Sequence[Surface], dest_surface: Optional[Surface] = None, diff --git a/docs/reST/ref/transform.rst b/docs/reST/ref/transform.rst index 9823f42bf1..6223bd2bcb 100644 --- a/docs/reST/ref/transform.rst +++ b/docs/reST/ref/transform.rst @@ -336,6 +336,21 @@ Instead, always begin with the original image and scale to the desired size.) .. ## pygame.transform.grayscale ## +.. function:: pixelate + + | :sl:`pixelate a surface` + | :sg:`pixelate(surface, pixel_size, dest_surface=None) -> Surface` + + Returns a pixelated version of the original surface. + + ``pixel_size`` is an integer describing how large you want the pixels in the final pixelated image to be. + An optional destination surface can be passed which is faster than creating a new Surface. This destination + surface must have the same dimensions (width, height) and smae depth as the source surface. + + .. versionadded:: 2.3.1 + + .. ## pygame.transform.pixelate ## + .. function:: threshold | :sl:`finds which, and how many pixels in a surface are within a threshold of a 'search_color' or a 'search_surf'.` diff --git a/src_c/doc/transform_doc.h b/src_c/doc/transform_doc.h index 04effd9d92..f4fbc4d261 100644 --- a/src_c/doc/transform_doc.h +++ b/src_c/doc/transform_doc.h @@ -18,4 +18,5 @@ #define DOC_TRANSFORM_AVERAGECOLOR "average_color(surface, rect=None, consider_alpha=False) -> Color\nfinds the average color of a surface" #define DOC_TRANSFORM_INVERT "invert(surface, dest_surface=None) -> Surface\ninverts the RGB elements of a surface" #define DOC_TRANSFORM_GRAYSCALE "grayscale(surface, dest_surface=None) -> Surface\ngrayscale a surface" +#define DOC_TRANSFORM_PIXELATE "pixelate(surface, pixel_size, dest_surface=None) -> Surface\npixelate a surface" #define DOC_TRANSFORM_THRESHOLD "threshold(dest_surface, surface, search_color, threshold=(0,0,0,0), set_color=(0,0,0,0), set_behavior=1, search_surf=None, inverse_set=False) -> num_threshold_pixels\nfinds which, and how many pixels in a surface are within a threshold of a 'search_color' or a 'search_surf'." diff --git a/src_c/transform.c b/src_c/transform.c index be3bc07af8..acd5f610d2 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -3354,6 +3354,116 @@ surf_invert(PyObject *self, PyObject *args, PyObject *kwargs) return (PyObject *)pgSurface_New(newsurf); } +SDL_Surface * +pixelate(pgSurfaceObject *srcobj, pgSurfaceObject *dstobj, int pixel_size) +{ + SDL_Surface *src = pgSurface_AsSurface(srcobj); + SDL_Surface *newsurf; + + if (!dstobj) { + newsurf = newsurf_fromsurf(src, srcobj->surf->w, srcobj->surf->h); + if (!newsurf) + return NULL; + } + else { + newsurf = pgSurface_AsSurface(dstobj); + } + + if (newsurf->w != src->w || newsurf->h != src->h) { + return (SDL_Surface *)(RAISE( + PyExc_ValueError, + "Destination surface must be the same size as source surface.")); + } + + if (src->format->BytesPerPixel != newsurf->format->BytesPerPixel) { + return (SDL_Surface *)(RAISE( + PyExc_ValueError, + "Source and destination surfaces need the same format.")); + } + + int x, y; + for (y = 0; y < src->h; y += pixel_size) { + for (x = 0; x < src->w; x += pixel_size) { + unsigned char r, g, b, a; // current + Uint64 ra, ga, ba, aa; // averages + Uint64 size; + Uint32 color, average; + Uint8 *pix; + int width = min(pixel_size, src->w - x); + int height = min(pixel_size, src->h - y); + + ra = 0; + ga = 0; + ba = 0; + aa = 0; + for (int w = 0; w < width; w++) { + for (int h = 0; h < height; h++) { + SURF_GET_AT(color, src, x + w, y + h, (Uint8 *)src->pixels, + src->format, pix); + SDL_GetRGBA(color, src->format, &r, &g, &b, &a); + ra += r; + ga += g; + ba += b; + aa += a; + } + } + size = width * height; + ra /= size; + ga /= size; + ba /= size; + aa /= size; + + average = SDL_MapRGBA(newsurf->format, ra, ga, ba, aa); + + printf("%u\n", average); + for (int w = 0; w < width; w++) { + for (int h = 0; h < height; h++) { + SURF_SET_AT(average, newsurf, x + w, y + h, + (Uint8 *)newsurf->pixels, newsurf->format, + pix); + } + } + } + } + + SDL_UnlockSurface(newsurf); + + return newsurf; +} + +/* + * anticipated API: pygame.transform.pixelate(surface, pixel_size, dest_surface + * = None) + */ +static PyObject * +surf_pixelate(PyObject *self, PyObject *args, PyObject *kwargs) +{ + pgSurfaceObject *src; + pgSurfaceObject *dst = NULL; + int pixel_size; + SDL_Surface *new_surf; + + static char *kwds[] = {"surface", "pixel_size", "dest_surface", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!i|O!", kwds, + &pgSurface_Type, &src, &pixel_size, + &pgSurface_Type, &dst)) { + return NULL; + } + + new_surf = pixelate(src, dst, pixel_size); + + if (!new_surf) { + return NULL; + } + + if (dst) { + Py_INCREF(dst); + return (PyObject *)dst; + } + return (PyObject *)pgSurface_New(new_surf); +} + static PyMethodDef _transform_methods[] = { {"scale", (PyCFunction)surf_scale, METH_VARARGS | METH_KEYWORDS, DOC_TRANSFORM_SCALE}, @@ -3393,6 +3503,8 @@ static PyMethodDef _transform_methods[] = { DOC_TRANSFORM_INVERT}, {"grayscale", (PyCFunction)surf_grayscale, METH_VARARGS | METH_KEYWORDS, DOC_TRANSFORM_GRAYSCALE}, + {"pixelate", (PyCFunction)surf_pixelate, METH_VARARGS | METH_KEYWORDS, + DOC_TRANSFORM_PIXELATE}, {NULL, NULL, 0, NULL}}; MODINIT_DEFINE(transform) From 09904863f83875a1e8b59ba88701bd08ea0372ab Mon Sep 17 00:00:00 2001 From: Andrew Coffey <49015102+oddbookworm@users.noreply.github.com> Date: Wed, 26 Jul 2023 22:53:14 -0500 Subject: [PATCH 02/10] replaced min call with ternary operations --- src_c/transform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src_c/transform.c b/src_c/transform.c index acd5f610d2..3af16bb620 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -3389,8 +3389,8 @@ pixelate(pgSurfaceObject *srcobj, pgSurfaceObject *dstobj, int pixel_size) Uint64 size; Uint32 color, average; Uint8 *pix; - int width = min(pixel_size, src->w - x); - int height = min(pixel_size, src->h - y); + int width = (pixel_size > (src->w - x)) ? src->w - x : pixel_size; + int height = (pixel_size > (src->h - y)) ? src->h - y : pixel_size; ra = 0; ga = 0; From d62452e9f907faa76fb22c4ff42e11993550839a Mon Sep 17 00:00:00 2001 From: Andrew Coffey <49015102+oddbookworm@users.noreply.github.com> Date: Thu, 27 Jul 2023 21:54:10 -0500 Subject: [PATCH 03/10] addressed compiler warnings about conversion to Uint8 and possible slight speedup --- src_c/transform.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src_c/transform.c b/src_c/transform.c index 3af16bb620..292e846365 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -3385,8 +3385,8 @@ pixelate(pgSurfaceObject *srcobj, pgSurfaceObject *dstobj, int pixel_size) for (y = 0; y < src->h; y += pixel_size) { for (x = 0; x < src->w; x += pixel_size) { unsigned char r, g, b, a; // current - Uint64 ra, ga, ba, aa; // averages - Uint64 size; + Uint32 ra, ga, ba, aa; // averages + Uint16 size; Uint32 color, average; Uint8 *pix; int width = (pixel_size > (src->w - x)) ? src->w - x : pixel_size; @@ -3408,14 +3408,11 @@ pixelate(pgSurfaceObject *srcobj, pgSurfaceObject *dstobj, int pixel_size) } } size = width * height; - ra /= size; - ga /= size; - ba /= size; - aa /= size; - average = SDL_MapRGBA(newsurf->format, ra, ga, ba, aa); + average = SDL_MapRGBA(newsurf->format, (Uint8)(ra / size), + (Uint8)(ga / size), (Uint8)(ba / size), + (Uint8)(aa / size)); - printf("%u\n", average); for (int w = 0; w < width; w++) { for (int h = 0; h < height; h++) { SURF_SET_AT(average, newsurf, x + w, y + h, From cc87855adb28315350c46b030cba0fe44059e095 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Sat, 7 Oct 2023 10:50:57 +0100 Subject: [PATCH 04/10] version added change --- docs/reST/ref/transform.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reST/ref/transform.rst b/docs/reST/ref/transform.rst index 6223bd2bcb..871a24f6e8 100644 --- a/docs/reST/ref/transform.rst +++ b/docs/reST/ref/transform.rst @@ -347,7 +347,7 @@ Instead, always begin with the original image and scale to the desired size.) An optional destination surface can be passed which is faster than creating a new Surface. This destination surface must have the same dimensions (width, height) and smae depth as the source surface. - .. versionadded:: 2.3.1 + .. versionadded:: 2.4.0 .. ## pygame.transform.pixelate ## From b544b7c4b446dd4281682f2e730021930cdd22a2 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Sat, 7 Oct 2023 10:54:27 +0100 Subject: [PATCH 05/10] Add pixel size test --- src_c/transform.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src_c/transform.c b/src_c/transform.c index 292e846365..dbfc45fd32 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -3369,6 +3369,12 @@ pixelate(pgSurfaceObject *srcobj, pgSurfaceObject *dstobj, int pixel_size) newsurf = pgSurface_AsSurface(dstobj); } + if (pixel_size < 1) { + return (SDL_Surface *)(RAISE( + PyExc_ValueError, + "pixel_size must be greater than 0.")); + } + if (newsurf->w != src->w || newsurf->h != src->h) { return (SDL_Surface *)(RAISE( PyExc_ValueError, From 26d398bac0f4a2ac918813c0ee58cdc0d324b0d3 Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Sat, 7 Oct 2023 10:57:13 +0100 Subject: [PATCH 06/10] Add pixel_size test --- src_c/transform.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src_c/transform.c b/src_c/transform.c index dbfc45fd32..e1f491ba24 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -3370,9 +3370,8 @@ pixelate(pgSurfaceObject *srcobj, pgSurfaceObject *dstobj, int pixel_size) } if (pixel_size < 1) { - return (SDL_Surface *)(RAISE( - PyExc_ValueError, - "pixel_size must be greater than 0.")); + return (SDL_Surface *)(RAISE(PyExc_ValueError, + "pixel_size must be greater than 0.")); } if (newsurf->w != src->w || newsurf->h != src->h) { From 88df72474969bb8416175782530bd957309d1f5e Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Sat, 7 Oct 2023 11:00:07 +0100 Subject: [PATCH 07/10] Add pixel_size test --- src_c/transform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_c/transform.c b/src_c/transform.c index e1f491ba24..cfaf7ba4c5 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -3373,7 +3373,7 @@ pixelate(pgSurfaceObject *srcobj, pgSurfaceObject *dstobj, int pixel_size) return (SDL_Surface *)(RAISE(PyExc_ValueError, "pixel_size must be greater than 0.")); } - + if (newsurf->w != src->w || newsurf->h != src->h) { return (SDL_Surface *)(RAISE( PyExc_ValueError, From ee170f86688551b568df2cf57228b76d5159119c Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Sun, 17 Dec 2023 22:12:28 -0600 Subject: [PATCH 08/10] rewrote transform.pixelate and wrote tests --- docs/reST/ref/transform.rst | 2 +- src_c/transform.c | 113 +++++++++--------------------------- test/transform_test.py | 31 ++++++++++ 3 files changed, 60 insertions(+), 86 deletions(-) diff --git a/docs/reST/ref/transform.rst b/docs/reST/ref/transform.rst index 77edfe1d34..e16cf2124f 100644 --- a/docs/reST/ref/transform.rst +++ b/docs/reST/ref/transform.rst @@ -352,7 +352,7 @@ Instead, always begin with the original image and scale to the desired size.) ``pixel_size`` is an integer describing how large you want the pixels in the final pixelated image to be. An optional destination surface can be passed which is faster than creating a new Surface. This destination - surface must have the same dimensions (width, height) and smae depth as the source surface. + surface must have the same dimensions (width, height) and same format as the source surface. .. versionadded:: 2.4.0 diff --git a/src_c/transform.c b/src_c/transform.c index 97965f354b..ce7a77e7f6 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -32,6 +32,7 @@ #include #include +#include #include "simd_shared.h" #include "simd_transform.h" @@ -3447,89 +3448,6 @@ surf_invert(PyObject *self, PyObject *args, PyObject *kwargs) return (PyObject *)pgSurface_New(newsurf); } -SDL_Surface * -pixelate(pgSurfaceObject *srcobj, pgSurfaceObject *dstobj, int pixel_size) -{ - SDL_Surface *src = pgSurface_AsSurface(srcobj); - SDL_Surface *newsurf; - - if (!dstobj) { - newsurf = newsurf_fromsurf(src, srcobj->surf->w, srcobj->surf->h); - if (!newsurf) - return NULL; - } - else { - newsurf = pgSurface_AsSurface(dstobj); - } - - if (pixel_size < 1) { - return (SDL_Surface *)(RAISE(PyExc_ValueError, - "pixel_size must be greater than 0.")); - } - - if (newsurf->w != src->w || newsurf->h != src->h) { - return (SDL_Surface *)(RAISE( - PyExc_ValueError, - "Destination surface must be the same size as source surface.")); - } - - if (src->format->BytesPerPixel != newsurf->format->BytesPerPixel) { - return (SDL_Surface *)(RAISE( - PyExc_ValueError, - "Source and destination surfaces need the same format.")); - } - - int x, y; - for (y = 0; y < src->h; y += pixel_size) { - for (x = 0; x < src->w; x += pixel_size) { - unsigned char r, g, b, a; // current - Uint32 ra, ga, ba, aa; // averages - Uint16 size; - Uint32 color, average; - Uint8 *pix; - int width = (pixel_size > (src->w - x)) ? src->w - x : pixel_size; - int height = (pixel_size > (src->h - y)) ? src->h - y : pixel_size; - - ra = 0; - ga = 0; - ba = 0; - aa = 0; - for (int w = 0; w < width; w++) { - for (int h = 0; h < height; h++) { - SURF_GET_AT(color, src, x + w, y + h, (Uint8 *)src->pixels, - src->format, pix); - SDL_GetRGBA(color, src->format, &r, &g, &b, &a); - ra += r; - ga += g; - ba += b; - aa += a; - } - } - size = width * height; - - average = SDL_MapRGBA(newsurf->format, (Uint8)(ra / size), - (Uint8)(ga / size), (Uint8)(ba / size), - (Uint8)(aa / size)); - - for (int w = 0; w < width; w++) { - for (int h = 0; h < height; h++) { - SURF_SET_AT(average, newsurf, x + w, y + h, - (Uint8 *)newsurf->pixels, newsurf->format, - pix); - } - } - } - } - - SDL_UnlockSurface(newsurf); - - return newsurf; -} - -/* - * anticipated API: pygame.transform.pixelate(surface, pixel_size, dest_surface - * = None) - */ static PyObject * surf_pixelate(PyObject *self, PyObject *args, PyObject *kwargs) { @@ -3537,6 +3455,7 @@ surf_pixelate(PyObject *self, PyObject *args, PyObject *kwargs) pgSurfaceObject *dst = NULL; int pixel_size; SDL_Surface *new_surf; + pgSurfaceObject *intermediate; static char *kwds[] = {"surface", "pixel_size", "dest_surface", NULL}; @@ -3546,12 +3465,36 @@ surf_pixelate(PyObject *self, PyObject *args, PyObject *kwargs) return NULL; } - new_surf = pixelate(src, dst, pixel_size); + double testWidth = round((double)src->surf->w / pixel_size); + double testHeight = round((double)src->surf->h / pixel_size); - if (!new_surf) { + if (testWidth > INT_MAX || testWidth <= 0) + { + PyErr_SetString(PyExc_OverflowError, "Cannot scale width outside the range [0, INT_MAX]"); return NULL; } + if (testHeight > INT_MAX || testHeight <= 0) + { + PyErr_SetString(PyExc_OverflowError, "Cannot scale height outside the range [0, INT_MAX]"); + return NULL; + } + + int width = (int)testWidth; + int height = (int)testHeight; + + SDL_Surface* temp = scale_to(src, NULL, width, height); + intermediate = pgSurface_New(temp); + if (intermediate == NULL) + { + return NULL; /* Exception already set in scale_to */ + } + new_surf = scale_to(intermediate, dst, src->surf->w, src->surf->h); + if (new_surf == NULL) + { + return NULL; /* Exception already set in scale_to */ + } + if (dst) { Py_INCREF(dst); return (PyObject *)dst; diff --git a/test/transform_test.py b/test/transform_test.py index f9f4bb4900..5235373dba 100644 --- a/test/transform_test.py +++ b/test/transform_test.py @@ -9,6 +9,16 @@ import pygame.transform from pygame.locals import * +def surfaces_have_same_pixels(surf1, surf2): + if surf1.get_size() != surf2.get_size(): + return False + + for row in range(surf1.get_height()): + for col in range(surf1.get_width()): + if surf1.get_at((col, row)) != surf2.get_at((col, row)): + return False + + return True def show_image(s, images=[]): # pygame.display.init() @@ -1466,7 +1476,28 @@ def smoothscale_invalid_scale(): smaller_surface.get_at(((k // 2), 0)), pygame.Color(127, 127, 127) ) self.assertEqual(smaller_surface.get_size(), (k, 1)) + + def test_pixelate(self): + """Test pygame.transform.pixelate""" + # test that pixelating the original with a pixel_size of 1 yields the original back + data_fname = example_path("data") + path = os.path.join(data_fname, "alien3.png") + image = pygame.image.load(path) # Get an indexed surface. + + no_change = pygame.transform.pixelate(image, 1) + + self.assertTrue(surfaces_have_same_pixels(image, no_change)) + + # test that pixelating a square image with a pixel_size equal to the side length + # yields a surface of a single color, which is the average of the surf + square = pygame.transform.scale(image, (50, 50)) + square_pixelated = pygame.transform.pixelate(square, 50) + square_resized = pygame.transform.scale( + pygame.transform.scale(square, (1, 1)), + square.get_size() + ) + self.assertTrue(surfaces_have_same_pixels(square_pixelated, square_resized)) class TransformDisplayModuleTest(unittest.TestCase): def setUp(self): From a0245938bb2849990114af1ab0b88639bfc82a22 Mon Sep 17 00:00:00 2001 From: Andrew Coffey Date: Sun, 17 Dec 2023 22:14:06 -0600 Subject: [PATCH 09/10] formatting --- src_c/transform.c | 20 +++++++++----------- test/transform_test.py | 14 ++++++++------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src_c/transform.c b/src_c/transform.c index ce7a77e7f6..aec560ef2b 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -3468,30 +3468,28 @@ surf_pixelate(PyObject *self, PyObject *args, PyObject *kwargs) double testWidth = round((double)src->surf->w / pixel_size); double testHeight = round((double)src->surf->h / pixel_size); - if (testWidth > INT_MAX || testWidth <= 0) - { - PyErr_SetString(PyExc_OverflowError, "Cannot scale width outside the range [0, INT_MAX]"); + if (testWidth > INT_MAX || testWidth <= 0) { + PyErr_SetString(PyExc_OverflowError, + "Cannot scale width outside the range [0, INT_MAX]"); return NULL; } - if (testHeight > INT_MAX || testHeight <= 0) - { - PyErr_SetString(PyExc_OverflowError, "Cannot scale height outside the range [0, INT_MAX]"); + if (testHeight > INT_MAX || testHeight <= 0) { + PyErr_SetString(PyExc_OverflowError, + "Cannot scale height outside the range [0, INT_MAX]"); return NULL; } int width = (int)testWidth; int height = (int)testHeight; - SDL_Surface* temp = scale_to(src, NULL, width, height); + SDL_Surface *temp = scale_to(src, NULL, width, height); intermediate = pgSurface_New(temp); - if (intermediate == NULL) - { + if (intermediate == NULL) { return NULL; /* Exception already set in scale_to */ } new_surf = scale_to(intermediate, dst, src->surf->w, src->surf->h); - if (new_surf == NULL) - { + if (new_surf == NULL) { return NULL; /* Exception already set in scale_to */ } diff --git a/test/transform_test.py b/test/transform_test.py index 5235373dba..2acfedcf47 100644 --- a/test/transform_test.py +++ b/test/transform_test.py @@ -9,17 +9,19 @@ import pygame.transform from pygame.locals import * + def surfaces_have_same_pixels(surf1, surf2): if surf1.get_size() != surf2.get_size(): return False - + for row in range(surf1.get_height()): for col in range(surf1.get_width()): if surf1.get_at((col, row)) != surf2.get_at((col, row)): return False - + return True + def show_image(s, images=[]): # pygame.display.init() size = s.get_rect()[2:] @@ -1476,7 +1478,7 @@ def smoothscale_invalid_scale(): smaller_surface.get_at(((k // 2), 0)), pygame.Color(127, 127, 127) ) self.assertEqual(smaller_surface.get_size(), (k, 1)) - + def test_pixelate(self): """Test pygame.transform.pixelate""" # test that pixelating the original with a pixel_size of 1 yields the original back @@ -1487,18 +1489,18 @@ def test_pixelate(self): no_change = pygame.transform.pixelate(image, 1) self.assertTrue(surfaces_have_same_pixels(image, no_change)) - + # test that pixelating a square image with a pixel_size equal to the side length # yields a surface of a single color, which is the average of the surf square = pygame.transform.scale(image, (50, 50)) square_pixelated = pygame.transform.pixelate(square, 50) square_resized = pygame.transform.scale( - pygame.transform.scale(square, (1, 1)), - square.get_size() + pygame.transform.scale(square, (1, 1)), square.get_size() ) self.assertTrue(surfaces_have_same_pixels(square_pixelated, square_resized)) + class TransformDisplayModuleTest(unittest.TestCase): def setUp(self): pygame.display.init() From 4c94ea59e6f12a4d5b5773f33b682e9f7bfcbdfc Mon Sep 17 00:00:00 2001 From: Dan Lawrence Date: Sat, 5 Oct 2024 16:59:27 +0100 Subject: [PATCH 10/10] fix documentation formatting --- docs/reST/ref/transform.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reST/ref/transform.rst b/docs/reST/ref/transform.rst index 7f82b2a8e5..6e11cdca34 100644 --- a/docs/reST/ref/transform.rst +++ b/docs/reST/ref/transform.rst @@ -351,7 +351,7 @@ Instead, always begin with the original image and scale to the desired size.) .. ## pygame.transform.grayscale ## .. function:: pixelate - + | :sl:`pixelate a surface` | :sg:`pixelate(surface, pixel_size, dest_surface=None) -> Surface`