mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 01:46:18 +03:00
Merge pull request #6086 from radarhere/l_gif
This commit is contained in:
commit
d0a33addc5
BIN
Tests/images/no_palette_with_transparency.gif
Normal file
BIN
Tests/images/no_palette_with_transparency.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 B |
|
@ -59,6 +59,17 @@ def test_invalid_file():
|
|||
GifImagePlugin.GifImageFile(invalid_file)
|
||||
|
||||
|
||||
def test_l_mode_transparency():
|
||||
with Image.open("Tests/images/no_palette_with_transparency.gif") as im:
|
||||
assert im.mode == "L"
|
||||
assert im.load()[0, 0] == 0
|
||||
assert im.info["transparency"] == 255
|
||||
|
||||
im.seek(1)
|
||||
assert im.mode == "LA"
|
||||
assert im.load()[0, 0] == (0, 255)
|
||||
|
||||
|
||||
def test_optimize():
|
||||
def test_grayscale(optimize):
|
||||
im = Image.new("L", (1, 1), 0)
|
||||
|
|
|
@ -135,6 +135,10 @@ def test_trns_l(tmp_path):
|
|||
|
||||
f = str(tmp_path / "temp.png")
|
||||
|
||||
im_la = im.convert("LA")
|
||||
assert "transparency" not in im_la.info
|
||||
im_la.save(f)
|
||||
|
||||
im_rgb = im.convert("RGB")
|
||||
assert im_rgb.info["transparency"] == (128, 128, 128) # undone
|
||||
im_rgb.save(f)
|
||||
|
|
|
@ -67,6 +67,16 @@ class TestImagingPaste:
|
|||
],
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def gradient_LA(self):
|
||||
return Image.merge(
|
||||
"LA",
|
||||
[
|
||||
self.gradient_L,
|
||||
self.gradient_L.transpose(Image.Transpose.ROTATE_90),
|
||||
],
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def gradient_RGBA(self):
|
||||
return Image.merge(
|
||||
|
@ -145,6 +155,28 @@ class TestImagingPaste:
|
|||
],
|
||||
)
|
||||
|
||||
def test_image_mask_LA(self):
|
||||
for mode in ("RGBA", "RGB", "L"):
|
||||
im = Image.new(mode, (200, 200), "white")
|
||||
im2 = getattr(self, "gradient_" + mode)
|
||||
|
||||
self.assert_9points_paste(
|
||||
im,
|
||||
im2,
|
||||
self.gradient_LA,
|
||||
[
|
||||
(128, 191, 255, 191),
|
||||
(112, 207, 206, 111),
|
||||
(128, 254, 128, 1),
|
||||
(208, 208, 239, 239),
|
||||
(192, 191, 191, 191),
|
||||
(207, 207, 112, 113),
|
||||
(255, 255, 255, 255),
|
||||
(239, 207, 207, 239),
|
||||
(255, 191, 128, 191),
|
||||
],
|
||||
)
|
||||
|
||||
def test_image_mask_RGBA(self):
|
||||
for mode in ("RGBA", "RGB", "L"):
|
||||
im = Image.new(mode, (200, 200), "white")
|
||||
|
|
|
@ -167,9 +167,15 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
if self.__frame == 1:
|
||||
self.pyaccess = None
|
||||
if "transparency" in self.info:
|
||||
self.mode = "RGBA"
|
||||
self.im.putpalettealpha(self.info["transparency"], 0)
|
||||
self.im = self.im.convert("RGBA", Image.Dither.FLOYDSTEINBERG)
|
||||
if self.mode == "P":
|
||||
self.im.putpalettealpha(self.info["transparency"], 0)
|
||||
self.im = self.im.convert("RGBA", Image.Dither.FLOYDSTEINBERG)
|
||||
self.mode = "RGBA"
|
||||
else:
|
||||
self.im = self.im.convert_transparent(
|
||||
"LA", self.info["transparency"]
|
||||
)
|
||||
self.mode = "LA"
|
||||
|
||||
del self.info["transparency"]
|
||||
else:
|
||||
|
@ -368,15 +374,18 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
if self.__frame == 0:
|
||||
return
|
||||
if self._frame_transparency is not None:
|
||||
self.im.putpalettealpha(self._frame_transparency, 0)
|
||||
frame_im = self.im.convert("RGBA")
|
||||
if self.mode == "P":
|
||||
self.im.putpalettealpha(self._frame_transparency, 0)
|
||||
frame_im = self.im.convert("RGBA")
|
||||
else:
|
||||
frame_im = self.im.convert_transparent("LA", self._frame_transparency)
|
||||
else:
|
||||
frame_im = self.im.convert("RGB")
|
||||
frame_im = self._crop(frame_im, self.dispose_extent)
|
||||
|
||||
self.im = self._prev_im
|
||||
self.mode = self.im.mode
|
||||
if frame_im.mode == "RGBA":
|
||||
if frame_im.mode in ("LA", "RGBA"):
|
||||
self.im.paste(frame_im, self.dispose_extent, frame_im)
|
||||
else:
|
||||
self.im.paste(frame_im, self.dispose_extent)
|
||||
|
|
|
@ -975,7 +975,9 @@ class Image:
|
|||
delete_trns = False
|
||||
# transparency handling
|
||||
if has_transparency:
|
||||
if self.mode in ("1", "L", "I", "RGB") and mode == "RGBA":
|
||||
if (self.mode in ("1", "L", "I") and mode in ("LA", "RGBA")) or (
|
||||
self.mode == "RGB" and mode == "RGBA"
|
||||
):
|
||||
# Use transparent conversion to promote from transparent
|
||||
# color to an alpha channel.
|
||||
new_im = self._new(
|
||||
|
@ -1565,8 +1567,8 @@ class Image:
|
|||
also use color strings as supported by the ImageColor module.
|
||||
|
||||
If a mask is given, this method updates only the regions
|
||||
indicated by the mask. You can use either "1", "L" or "RGBA"
|
||||
images (in the latter case, the alpha band is used as mask).
|
||||
indicated by the mask. You can use either "1", "L", "LA", "RGBA"
|
||||
or "RGBa" images (if present, the alpha band is used as mask).
|
||||
Where the mask is 255, the given image is copied as is. Where
|
||||
the mask is 0, the current value is preserved. Intermediate
|
||||
values will mix the two images together, including their alpha
|
||||
|
@ -1614,7 +1616,7 @@ class Image:
|
|||
elif isImageType(im):
|
||||
im.load()
|
||||
if self.mode != im.mode:
|
||||
if self.mode != "RGB" or im.mode not in ("RGBA", "RGBa"):
|
||||
if self.mode != "RGB" or im.mode not in ("LA", "RGBA", "RGBa"):
|
||||
# should use an adapter for this!
|
||||
im = im.convert(self.mode)
|
||||
im = im.im
|
||||
|
|
|
@ -1634,29 +1634,15 @@ ImagingConvertTransparent(Imaging imIn, const char *mode, int r, int g, int b) {
|
|||
return (Imaging)ImagingError_ModeError();
|
||||
}
|
||||
|
||||
if (!((strcmp(imIn->mode, "RGB") == 0 || strcmp(imIn->mode, "1") == 0 ||
|
||||
strcmp(imIn->mode, "I") == 0 || strcmp(imIn->mode, "L") == 0) &&
|
||||
strcmp(mode, "RGBA") == 0))
|
||||
#ifdef notdef
|
||||
{
|
||||
return (Imaging)ImagingError_ValueError("conversion not supported");
|
||||
}
|
||||
#else
|
||||
{
|
||||
static char buf[100];
|
||||
snprintf(
|
||||
buf,
|
||||
100,
|
||||
"conversion from %.10s to %.10s not supported in convert_transparent",
|
||||
imIn->mode,
|
||||
mode);
|
||||
return (Imaging)ImagingError_ValueError(buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (strcmp(imIn->mode, "RGB") == 0) {
|
||||
if (strcmp(imIn->mode, "RGB") == 0 && strcmp(mode, "RGBA") == 0) {
|
||||
convert = rgb2rgba;
|
||||
} else {
|
||||
} else if ((strcmp(imIn->mode, "1") == 0 ||
|
||||
strcmp(imIn->mode, "I") == 0 ||
|
||||
strcmp(imIn->mode, "L") == 0
|
||||
) && (
|
||||
strcmp(mode, "RGBA") == 0 ||
|
||||
strcmp(mode, "LA") == 0
|
||||
)) {
|
||||
if (strcmp(imIn->mode, "1") == 0) {
|
||||
convert = bit2rgb;
|
||||
} else if (strcmp(imIn->mode, "I") == 0) {
|
||||
|
@ -1665,6 +1651,15 @@ ImagingConvertTransparent(Imaging imIn, const char *mode, int r, int g, int b) {
|
|||
convert = l2rgb;
|
||||
}
|
||||
g = b = r;
|
||||
} else {
|
||||
static char buf[100];
|
||||
snprintf(
|
||||
buf,
|
||||
100,
|
||||
"conversion from %.10s to %.10s not supported in convert_transparent",
|
||||
imIn->mode,
|
||||
mode);
|
||||
return (Imaging)ImagingError_ValueError(buf);
|
||||
}
|
||||
|
||||
imOut = ImagingNew2Dirty(mode, imOut, imIn);
|
||||
|
|
|
@ -295,7 +295,7 @@ ImagingPaste(
|
|||
paste_mask_L(imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
||||
ImagingSectionLeave(&cookie);
|
||||
|
||||
} else if (strcmp(imMask->mode, "RGBA") == 0) {
|
||||
} else if (strcmp(imMask->mode, "LA") == 0 || strcmp(imMask->mode, "RGBA") == 0) {
|
||||
ImagingSectionEnter(&cookie);
|
||||
paste_mask_RGBA(
|
||||
imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
||||
|
|
Loading…
Reference in New Issue
Block a user