Added RGBA saving

This commit is contained in:
Andrew Murray 2021-05-17 20:48:31 +10:00
parent 143e08c92c
commit 6449cdc1a3
2 changed files with 21 additions and 10 deletions

View File

@ -251,10 +251,18 @@ def test_save_unsupported_mode(tmp_path):
im.save(out) im.save(out)
def test_save(tmp_path): @pytest.mark.parametrize(
("mode", "test_file"),
[
("RGB", "Tests/images/hopper.png"),
("RGBA", "Tests/images/pil123rgba.png"),
],
)
def test_save(mode, test_file, tmp_path):
out = str(tmp_path / "temp.dds") out = str(tmp_path / "temp.dds")
im = hopper() with Image.open(test_file) as im:
im.save(out) assert im.mode == mode
im.save(out)
with Image.open(out) as reloaded: with Image.open(out) as reloaded:
assert_image_equal(im, reloaded) assert_image_equal(im, reloaded)

View File

@ -203,7 +203,7 @@ class DdsImageFile(ImageFile.ImageFile):
def _save(im, fp, filename): def _save(im, fp, filename):
if im.mode != "RGB": if im.mode not in ("RGB", "RGBA"):
raise OSError(f"cannot write mode {im.mode} as DDS") raise OSError(f"cannot write mode {im.mode} as DDS")
fp.write( fp.write(
@ -214,24 +214,27 @@ def _save(im, fp, filename):
) # flags ) # flags
+ o32(im.height) + o32(im.height)
+ o32(im.width) + o32(im.width)
+ o32((im.width * 24 + 7) // 8) # pitch + o32((im.width * (32 if im.mode == "RGBA" else 24) + 7) // 8) # pitch
+ o32(0) # depth + o32(0) # depth
+ o32(0) # mipmaps + o32(0) # mipmaps
+ o32(0) * 11 # reserved + o32(0) * 11 # reserved
+ o32(32) # pfsize + o32(32) # pfsize
+ o32(DDPF_RGB) # pfflags + o32(DDS_RGBA if im.mode == "RGBA" else DDPF_RGB) # pfflags
+ o32(0) # fourcc + o32(0) # fourcc
+ o32(24) # bitcount + o32(32 if im.mode == "RGBA" else 24) # bitcount
+ o32(0xFF0000) # rbitmask + o32(0xFF0000) # rbitmask
+ o32(0xFF00) # gbitmask + o32(0xFF00) # gbitmask
+ o32(0xFF) # bbitmask + o32(0xFF) # bbitmask
+ o32(0) # abitmask + o32(0xFF000000 if im.mode == "RGBA" else 0) # abitmask
+ o32(DDSCAPS_TEXTURE) # dwCaps + o32(DDSCAPS_TEXTURE) # dwCaps
+ o32(0) # dwCaps2 + o32(0) # dwCaps2
+ o32(0) # dwCaps3 + o32(0) # dwCaps3
+ o32(0) # dwCaps4 + o32(0) # dwCaps4
+ o32(0) # dwReserved2 + o32(0) # dwReserved2
) )
if im.mode == "RGBA":
r, g, b, a = im.split()
im = Image.merge("RGBA", (a, r, g, b))
ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (im.mode[::-1], 0, 1))]) ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (im.mode[::-1], 0, 1))])