mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-25 17:36:18 +03:00
Merge pull request #7888 from radarhere/convert_rgb
This commit is contained in:
commit
d734c8b702
|
@ -183,6 +183,14 @@ def test_trns_RGB(tmp_path: Path) -> None:
|
||||||
assert im_l.info["transparency"] == im_l.getpixel((0, 0)) # undone
|
assert im_l.info["transparency"] == im_l.getpixel((0, 0)) # undone
|
||||||
im_l.save(f)
|
im_l.save(f)
|
||||||
|
|
||||||
|
im_la = im.convert("LA")
|
||||||
|
assert "transparency" not in im_la.info
|
||||||
|
im_la.save(f)
|
||||||
|
|
||||||
|
im_la = im.convert("La")
|
||||||
|
assert "transparency" not in im_la.info
|
||||||
|
assert im_la.getpixel((0, 0)) == (0, 0)
|
||||||
|
|
||||||
im_p = im.convert("P")
|
im_p = im.convert("P")
|
||||||
assert "transparency" in im_p.info
|
assert "transparency" in im_p.info
|
||||||
im_p.save(f)
|
im_p.save(f)
|
||||||
|
@ -191,6 +199,10 @@ def test_trns_RGB(tmp_path: Path) -> None:
|
||||||
assert "transparency" not in im_rgba.info
|
assert "transparency" not in im_rgba.info
|
||||||
im_rgba.save(f)
|
im_rgba.save(f)
|
||||||
|
|
||||||
|
im_rgba = im.convert("RGBa")
|
||||||
|
assert "transparency" not in im_rgba.info
|
||||||
|
assert im_rgba.getpixel((0, 0)) == (0, 0, 0, 0)
|
||||||
|
|
||||||
im_p = pytest.warns(UserWarning, im.convert, "P", palette=Image.Palette.ADAPTIVE)
|
im_p = pytest.warns(UserWarning, im.convert, "P", palette=Image.Palette.ADAPTIVE)
|
||||||
assert "transparency" not in im_p.info
|
assert "transparency" not in im_p.info
|
||||||
im_p.save(f)
|
im_p.save(f)
|
||||||
|
|
|
@ -978,7 +978,7 @@ class Image:
|
||||||
# transparency handling
|
# transparency handling
|
||||||
if has_transparency:
|
if has_transparency:
|
||||||
if (self.mode in ("1", "L", "I", "I;16") and mode in ("LA", "RGBA")) or (
|
if (self.mode in ("1", "L", "I", "I;16") and mode in ("LA", "RGBA")) or (
|
||||||
self.mode == "RGB" and mode == "RGBA"
|
self.mode == "RGB" and mode in ("La", "LA", "RGBa", "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.
|
||||||
|
|
|
@ -499,26 +499,27 @@ rgba2rgb_(UINT8 *out, const UINT8 *in, int xsize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Conversion of RGB + single transparent color to RGBA,
|
* Conversion of RGB + single transparent color either to
|
||||||
* where any pixel that matches the color will have the
|
* RGBA or LA, where any pixel matching the color will have the alpha channel set to 0, or
|
||||||
* alpha channel set to 0
|
* RGBa or La, where any pixel matching the color will have all channels set to 0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rgbT2rgba(UINT8 *out, int xsize, int r, int g, int b) {
|
rgbT2a(UINT8 *out, UINT8 *in, int xsize, int r, int g, int b, int premultiplied) {
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
UINT32 trns = ((r & 0xff) << 24) | ((g & 0xff) << 16) | ((b & 0xff) << 8) | 0xff;
|
UINT32 trns = ((r & 0xff) << 24) | ((g & 0xff) << 16) | ((b & 0xff) << 8) | 0xff;
|
||||||
UINT32 repl = trns & 0xffffff00;
|
UINT32 repl = premultiplied ? 0 : (trns & 0xffffff00);
|
||||||
#else
|
#else
|
||||||
UINT32 trns = (0xffU << 24) | ((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xff);
|
UINT32 trns = (0xffU << 24) | ((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xff);
|
||||||
UINT32 repl = trns & 0x00ffffff;
|
UINT32 repl = premultiplied ? 0 : (trns & 0x00ffffff);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < xsize; i++, out += sizeof(trns)) {
|
UINT8 *ref = in != NULL ? in : out;
|
||||||
|
for (i = 0; i < xsize; i++, ref += sizeof(trns), out += sizeof(trns)) {
|
||||||
UINT32 v;
|
UINT32 v;
|
||||||
memcpy(&v, out, sizeof(v));
|
memcpy(&v, ref, sizeof(v));
|
||||||
if (v == trns) {
|
if (v == trns) {
|
||||||
memcpy(out, &repl, sizeof(repl));
|
memcpy(out, &repl, sizeof(repl));
|
||||||
}
|
}
|
||||||
|
@ -941,12 +942,14 @@ static struct {
|
||||||
{"RGB", "1", rgb2bit},
|
{"RGB", "1", rgb2bit},
|
||||||
{"RGB", "L", rgb2l},
|
{"RGB", "L", rgb2l},
|
||||||
{"RGB", "LA", rgb2la},
|
{"RGB", "LA", rgb2la},
|
||||||
|
{"RGB", "La", rgb2la},
|
||||||
{"RGB", "I", rgb2i},
|
{"RGB", "I", rgb2i},
|
||||||
{"RGB", "F", rgb2f},
|
{"RGB", "F", rgb2f},
|
||||||
{"RGB", "BGR;15", rgb2bgr15},
|
{"RGB", "BGR;15", rgb2bgr15},
|
||||||
{"RGB", "BGR;16", rgb2bgr16},
|
{"RGB", "BGR;16", rgb2bgr16},
|
||||||
{"RGB", "BGR;24", rgb2bgr24},
|
{"RGB", "BGR;24", rgb2bgr24},
|
||||||
{"RGB", "RGBA", rgb2rgba},
|
{"RGB", "RGBA", rgb2rgba},
|
||||||
|
{"RGB", "RGBa", rgb2rgba},
|
||||||
{"RGB", "RGBX", rgb2rgba},
|
{"RGB", "RGBX", rgb2rgba},
|
||||||
{"RGB", "CMYK", rgb2cmyk},
|
{"RGB", "CMYK", rgb2cmyk},
|
||||||
{"RGB", "YCbCr", ImagingConvertRGB2YCbCr},
|
{"RGB", "YCbCr", ImagingConvertRGB2YCbCr},
|
||||||
|
@ -1681,14 +1684,27 @@ ImagingConvertTransparent(Imaging imIn, const char *mode, int r, int g, int b) {
|
||||||
ImagingSectionCookie cookie;
|
ImagingSectionCookie cookie;
|
||||||
ImagingShuffler convert;
|
ImagingShuffler convert;
|
||||||
Imaging imOut = NULL;
|
Imaging imOut = NULL;
|
||||||
|
int premultiplied = 0;
|
||||||
|
// If the transparency matches pixels in the source image, not the converted image
|
||||||
|
UINT8 *source;
|
||||||
|
int source_transparency = 0;
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
if (!imIn) {
|
if (!imIn) {
|
||||||
return (Imaging)ImagingError_ModeError();
|
return (Imaging)ImagingError_ModeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(imIn->mode, "RGB") == 0 && strcmp(mode, "RGBA") == 0) {
|
if (strcmp(imIn->mode, "RGB") == 0 && (strcmp(mode, "RGBA") == 0 || strcmp(mode, "RGBa") == 0)) {
|
||||||
convert = rgb2rgba;
|
convert = rgb2rgba;
|
||||||
|
if (strcmp(mode, "RGBa") == 0) {
|
||||||
|
premultiplied = 1;
|
||||||
|
}
|
||||||
|
} else if (strcmp(imIn->mode, "RGB") == 0 && (strcmp(mode, "LA") == 0 || strcmp(mode, "La") == 0)) {
|
||||||
|
convert = rgb2la;
|
||||||
|
source_transparency = 1;
|
||||||
|
if (strcmp(mode, "La") == 0) {
|
||||||
|
premultiplied = 1;
|
||||||
|
}
|
||||||
} else if ((strcmp(imIn->mode, "1") == 0 ||
|
} else if ((strcmp(imIn->mode, "1") == 0 ||
|
||||||
strcmp(imIn->mode, "I") == 0 ||
|
strcmp(imIn->mode, "I") == 0 ||
|
||||||
strcmp(imIn->mode, "I;16") == 0 ||
|
strcmp(imIn->mode, "I;16") == 0 ||
|
||||||
|
@ -1726,7 +1742,9 @@ ImagingConvertTransparent(Imaging imIn, const char *mode, int r, int g, int b) {
|
||||||
ImagingSectionEnter(&cookie);
|
ImagingSectionEnter(&cookie);
|
||||||
for (y = 0; y < imIn->ysize; y++) {
|
for (y = 0; y < imIn->ysize; y++) {
|
||||||
(*convert)((UINT8 *)imOut->image[y], (UINT8 *)imIn->image[y], imIn->xsize);
|
(*convert)((UINT8 *)imOut->image[y], (UINT8 *)imIn->image[y], imIn->xsize);
|
||||||
rgbT2rgba((UINT8 *)imOut->image[y], imIn->xsize, r, g, b);
|
|
||||||
|
source = source_transparency ? (UINT8 *)imIn->image[y] : NULL;
|
||||||
|
rgbT2a((UINT8 *)imOut->image[y], source, imIn->xsize, r, g, b, premultiplied);
|
||||||
}
|
}
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user