Skip to content

Stop using Pillow's deprecated getdata() in tile maps - #2927

Merged
pvcraven merged 1 commit into
developmentfrom
fix/pillow-getdata
Oct 6, 2026
Merged

pvcraven merged 1 commit into
developmentfrom
fix/pillow-getdata

Conversation

@pvcraven

@pvcraven pvcraven commented Oct 6, 2026

Copy link
Copy Markdown
Member

Summary

Removes Arcade's only use of Pillow's deprecated Image.getdata(), which Pillow 14 removes (October 2027). Pillow 12.2 already warns:

DeprecationWarning: Image.Image.getdata is deprecated and will be removed in Pillow 14 (2027-10-15). Use get_flattened_data instead.

It was in TileMap, applying an image layer's transparentcolor: it read every pixel into a Python list, replaced the matching ones, and wrote them all back with putdata().

The fix

Arcade supports pillow>=11.3.0, which doesn't have the suggested get_flattened_data(), so I used Pillow operations instead. The new helper _make_color_transparent():

  • builds a mask of the pixels whose red, green and blue all match the color (Image.point to mode "1" per band, then ImageChops.logical_and);
  • pastes transparent white through the mask.

These calls are much older than Pillow 11.3. As before, the alpha of the matching pixels doesn't matter, and the image is changed in place.

Same result, faster: I compared old and new on three images: the JPEG background used by the image-layer test map, a PNG sprite sheet, and a tile. I tried each with its most common color, white, and a color that never appears. The output is byte-for-byte identical in every case. Times:

Image Old New
abstract_1.jpg, 1024×600 76 ms 3.6 ms
grassMid.png, 128×128 1.6 ms 0.15 ms
number_sheet.png, 48×32 0.2 ms 0.09 ms

The two imports only the old loop used (Sequence, RGBA255) are removed.

Tests

No test covered this code, so I added:

  • tests/fixtures/tilemaps/image_layer_transparent.json: an image layer showing number_sheet.png with "transparentcolor": "#ffffff".
  • test_image_layer_transparent_color: the loaded layer's white pixels (1375 of them) become (255, 255, 255, 0), and every other pixel is unchanged.
  • test_make_color_transparent: a 4-pixel image covering a match, a match with partial alpha, a color with one band off by one, and a color that doesn't match.

With warnings turned into errors, loading the new map raises the DeprecationWarning on development and loads cleanly with this PR.

Full suite: 1573 passed, no warnings, plus the 3 render tests that fail only on my machine. #2926 fixes those, and this branch doesn't include it yet. mypy has no new errors, and ruff is clean.

The changelog has an entry under Unreleased → Misc Changes.

🤖 Generated with Claude Code

An image layer's transparent color was applied by reading every pixel
with Image.getdata(), which Pillow 14 removes (it warns now), and
writing them back with putdata(). Arcade still supports Pillow 11.3,
which doesn't have the suggested get_flattened_data(), so use Pillow
operations instead: a mask of the pixels matching the color in all
three bands, and a paste of transparent white through it.

The result is byte for byte the same as before, and it's faster: a
1024x600 image went from 76 ms to 4 ms. Adds a test map with a
transparent color, since no test covered this.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pvcraven
pvcraven merged commit 58a3279 into development Oct 6, 2026
7 checks passed
@pvcraven
pvcraven deleted the fix/pillow-getdata branch October 6, 2026 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant