Skip to content

Image.save() causes images created by Image.frombuffer() to stop reflecting changes in that buffer #8828

Closed
@igoras1993

Description

@igoras1993

Hi, recently messed with PIL to encounter what is probably a bug

What did you do?

import numpy as np
from PIL import Image


# Source of data for image
im_data: np.typing.NDArray = np.array([[255]], dtype=np.uint8)
assert im_data[0, 0] == 255  # OK

# Attach to buffer protocol of an array, should reflect changes in im_data
im: Image.Image = Image.frombuffer(mode="L", size=(1, 1), data=im_data)
assert im_data[0, 0] == 255  # OK
assert im.getdata()[0] == 255  # OK

im_data[:, :] = np.array([[128]], dtype=np.uint8)
assert im_data[0, 0] == 128  # OK
assert im.getdata()[0] == 128  # OK!

im.save("./test_image.bmp")
assert im_data[0, 0] == 128  # OK
assert im.getdata()[0] == 128  # OK

im_data[:, :] = np.array([[64]], dtype=np.uint8)
assert im_data[0, 0] == 64  # OK
assert im.getdata()[0] == 64  # Failed!!! It is still == 128

What did you expect to happen?

Line with last assert should pass the assertion:

...
assert im.getdata()[0] == 64   # Should pass

What actually happened?

Yes, so it seams that Image.save() messes with image buffer state. Moreover, this is actually explicitly stated that it does in source code:

# may mutate self!

#     def save(...):
#         ...
           # may mutate self!
           self._ensure_mutable()

Once one saved the image, one can no longer work with buffer and expect image working properly.

I can try to work out some patches but really I am somewhat new to the pillow and not well aware of all internal connections with things. It would be nice to have some hints on what may going on - then I can try to fix this.

What are your OS, Python and Pillow versions?

OS:

lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.5 LTS
Release:	22.04
Codename:	jammy

Python:

  • Python 3.12.9
  • Prebuilt binary from deadsnakes ppa if I remember correctly

Pillow:

poetry run python3 -m PIL --report
--------------------------------------------------------------------
Pillow 11.1.0
Python 3.12.9 (main, Feb  5 2025, 08:49:00) [GCC 11.4.0]
--------------------------------------------------------------------
Python executable is [...]/.venv/bin/python3
Environment Python files loaded from [...]/.venv
System Python files loaded from /usr
--------------------------------------------------------------------
Python Pillow modules loaded from [...]/.venv/lib/python3.12/site-packages/PIL
Binary Pillow modules loaded from [...]/.venv/lib/python3.12/site-packages/PIL
--------------------------------------------------------------------
--- PIL CORE support ok, compiled for 11.1.0
*** TKINTER support not installed
--- FREETYPE2 support ok, loaded 2.13.2
--- LITTLECMS2 support ok, loaded 2.16
--- WEBP support ok, loaded 1.5.0
--- JPEG support ok, compiled for libjpeg-turbo 3.1.0
--- OPENJPEG (JPEG2000) support ok, loaded 2.5.3
--- ZLIB (PNG/ZIP) support ok, loaded 1.2.11, compiled for zlib-ng 2.2.2
--- LIBTIFF support ok, loaded 4.6.0
--- RAQM (Bidirectional Text) support ok, loaded 0.10.1, fribidi 1.0.8, harfbuzz 10.1.0
*** LIBIMAGEQUANT (Quantization method) support not installed
--- XCB (X protocol) support ok
--------------------------------------------------------------------

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions