mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-13 18:56:17 +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)
|
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_optimize():
|
||||||
def test_grayscale(optimize):
|
def test_grayscale(optimize):
|
||||||
im = Image.new("L", (1, 1), 0)
|
im = Image.new("L", (1, 1), 0)
|
||||||
|
|
|
@ -135,6 +135,10 @@ def test_trns_l(tmp_path):
|
||||||
|
|
||||||
f = str(tmp_path / "temp.png")
|
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")
|
im_rgb = im.convert("RGB")
|
||||||
assert im_rgb.info["transparency"] == (128, 128, 128) # undone
|
assert im_rgb.info["transparency"] == (128, 128, 128) # undone
|
||||||
im_rgb.save(f)
|
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
|
@cached_property
|
||||||
def gradient_RGBA(self):
|
def gradient_RGBA(self):
|
||||||
return Image.merge(
|
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):
|
def test_image_mask_RGBA(self):
|
||||||
for mode in ("RGBA", "RGB", "L"):
|
for mode in ("RGBA", "RGB", "L"):
|
||||||
im = Image.new(mode, (200, 200), "white")
|
im = Image.new(mode, (200, 200), "white")
|
||||||
|
|
|
@ -167,9 +167,15 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
if self.__frame == 1:
|
if self.__frame == 1:
|
||||||
self.pyaccess = None
|
self.pyaccess = None
|
||||||
if "transparency" in self.info:
|
if "transparency" in self.info:
|
||||||
self.mode = "RGBA"
|
if self.mode == "P":
|
||||||
self.im.putpalettealpha(self.info["transparency"], 0)
|
self.im.putpalettealpha(self.info["transparency"], 0)
|
||||||
self.im = self.im.convert("RGBA", Image.Dither.FLOYDSTEINBERG)
|
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"]
|
del self.info["transparency"]
|
||||||
else:
|
else:
|
||||||
|
@ -368,15 +374,18 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
if self.__frame == 0:
|
if self.__frame == 0:
|
||||||
return
|
return
|
||||||
if self._frame_transparency is not None:
|
if self._frame_transparency is not None:
|
||||||
self.im.putpalettealpha(self._frame_transparency, 0)
|
if self.mode == "P":
|
||||||
frame_im = self.im.convert("RGBA")
|
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:
|
else:
|
||||||
frame_im = self.im.convert("RGB")
|
frame_im = self.im.convert("RGB")
|
||||||
frame_im = self._crop(frame_im, self.dispose_extent)
|
frame_im = self._crop(frame_im, self.dispose_extent)
|
||||||
|
|
||||||
self.im = self._prev_im
|
self.im = self._prev_im
|
||||||
self.mode = self.im.mode
|
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)
|
self.im.paste(frame_im, self.dispose_extent, frame_im)
|
||||||
else:
|
else:
|
||||||
self.im.paste(frame_im, self.dispose_extent)
|
self.im.paste(frame_im, self.dispose_extent)
|
||||||
|
|
|
@ -975,7 +975,9 @@ class Image:
|
||||||
delete_trns = False
|
delete_trns = False
|
||||||
# transparency handling
|
# transparency handling
|
||||||
if has_transparency:
|
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
|
# Use transparent conversion to promote from transparent
|
||||||
# color to an alpha channel.
|
# color to an alpha channel.
|
||||||
new_im = self._new(
|
new_im = self._new(
|
||||||
|
@ -1565,8 +1567,8 @@ class Image:
|
||||||
also use color strings as supported by the ImageColor module.
|
also use color strings as supported by the ImageColor module.
|
||||||
|
|
||||||
If a mask is given, this method updates only the regions
|
If a mask is given, this method updates only the regions
|
||||||
indicated by the mask. You can use either "1", "L" or "RGBA"
|
indicated by the mask. You can use either "1", "L", "LA", "RGBA"
|
||||||
images (in the latter case, the alpha band is used as mask).
|
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
|
Where the mask is 255, the given image is copied as is. Where
|
||||||
the mask is 0, the current value is preserved. Intermediate
|
the mask is 0, the current value is preserved. Intermediate
|
||||||
values will mix the two images together, including their alpha
|
values will mix the two images together, including their alpha
|
||||||
|
@ -1614,7 +1616,7 @@ class Image:
|
||||||
elif isImageType(im):
|
elif isImageType(im):
|
||||||
im.load()
|
im.load()
|
||||||
if self.mode != im.mode:
|
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!
|
# should use an adapter for this!
|
||||||
im = im.convert(self.mode)
|
im = im.convert(self.mode)
|
||||||
im = im.im
|
im = im.im
|
||||||
|
|
|
@ -1634,29 +1634,15 @@ ImagingConvertTransparent(Imaging imIn, const char *mode, int r, int g, int b) {
|
||||||
return (Imaging)ImagingError_ModeError();
|
return (Imaging)ImagingError_ModeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!((strcmp(imIn->mode, "RGB") == 0 || strcmp(imIn->mode, "1") == 0 ||
|
if (strcmp(imIn->mode, "RGB") == 0 && strcmp(mode, "RGBA") == 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) {
|
|
||||||
convert = rgb2rgba;
|
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) {
|
if (strcmp(imIn->mode, "1") == 0) {
|
||||||
convert = bit2rgb;
|
convert = bit2rgb;
|
||||||
} else if (strcmp(imIn->mode, "I") == 0) {
|
} 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;
|
convert = l2rgb;
|
||||||
}
|
}
|
||||||
g = b = r;
|
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);
|
imOut = ImagingNew2Dirty(mode, imOut, imIn);
|
||||||
|
|
|
@ -295,7 +295,7 @@ ImagingPaste(
|
||||||
paste_mask_L(imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
paste_mask_L(imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
} else if (strcmp(imMask->mode, "RGBA") == 0) {
|
} else if (strcmp(imMask->mode, "LA") == 0 || strcmp(imMask->mode, "RGBA") == 0) {
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
paste_mask_RGBA(
|
paste_mask_RGBA(
|
||||||
imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user