diff --git a/Tests/test_file_icns.py b/Tests/test_file_icns.py index 7bf7b72ec..05feedb1a 100644 --- a/Tests/test_file_icns.py +++ b/Tests/test_file_icns.py @@ -55,6 +55,19 @@ def test_save_append_images(tmp_path): assert_image_equal(reread, provided_im) +@pytest.mark.skipif(sys.platform != "darwin", reason="Requires macOS") +def test_save_fp(): + fp = io.BytesIO() + + with Image.open(TEST_FILE) as im: + im.save(fp, format="ICNS") + + with Image.open(fp) as reread: + assert reread.mode == "RGBA" + assert reread.size == (1024, 1024) + assert reread.format == "ICNS" + + def test_sizes(): # Check that we can load all of the sizes, and that the final pixel # dimensions are as expected diff --git a/src/PIL/IcnsImagePlugin.py b/src/PIL/IcnsImagePlugin.py index 9de7d8dfe..7023855ba 100644 --- a/src/PIL/IcnsImagePlugin.py +++ b/src/PIL/IcnsImagePlugin.py @@ -337,6 +337,10 @@ def _save(im, fp, filename): # iconutil -c icns -o {} {} + fp_only = not filename + if fp_only: + f, filename = tempfile.mkstemp(".icns") + os.close(f) convert_cmd = ["iconutil", "-c", "icns", "-o", filename, iconset] convert_proc = subprocess.Popen( convert_cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL @@ -349,6 +353,10 @@ def _save(im, fp, filename): if retcode: raise subprocess.CalledProcessError(retcode, convert_cmd) + if fp_only: + with open(filename, "rb") as f: + fp.write(f.read()) + Image.register_open(IcnsImageFile.format, IcnsImageFile, lambda x: x[:4] == b"icns") Image.register_extension(IcnsImageFile.format, ".icns")