@@ -833,7 +833,7 @@ def load(self):
833
833
palette_length = self .im .putpalette (mode , arr )
834
834
self .palette .dirty = 0
835
835
self .palette .rawmode = None
836
- if "transparency" in self .info :
836
+ if "transparency" in self .info and mode in ( "RGBA" , "LA" , "PA" ) :
837
837
if isinstance (self .info ["transparency" ], int ):
838
838
self .im .putpalettealpha (self .info ["transparency" ], 0 )
839
839
else :
@@ -977,21 +977,28 @@ def convert_transparency(m, v):
977
977
if self .mode == "P" :
978
978
trns_im .putpalette (self .palette )
979
979
if isinstance (t , tuple ):
980
+ err = "Couldn't allocate a palette color for transparency"
980
981
try :
981
- t = trns_im .palette .getcolor (t )
982
- except Exception as e :
983
- raise ValueError (
984
- "Couldn't allocate a palette color for transparency"
985
- ) from e
986
- trns_im .putpixel ((0 , 0 ), t )
987
-
988
- if mode in ("L" , "RGB" ):
989
- trns_im = trns_im .convert (mode )
982
+ t = trns_im .palette .getcolor (t , self )
983
+ except ValueError as e :
984
+ if str (e ) == "cannot allocate more than 256 colors" :
985
+ # If all 256 colors are in use,
986
+ # then there is no need for transparency
987
+ t = None
988
+ else :
989
+ raise ValueError (err ) from e
990
+ if t is None :
991
+ trns = None
990
992
else :
991
- # can't just retrieve the palette number, got to do it
992
- # after quantization.
993
- trns_im = trns_im .convert ("RGB" )
994
- trns = trns_im .getpixel ((0 , 0 ))
993
+ trns_im .putpixel ((0 , 0 ), t )
994
+
995
+ if mode in ("L" , "RGB" ):
996
+ trns_im = trns_im .convert (mode )
997
+ else :
998
+ # can't just retrieve the palette number, got to do it
999
+ # after quantization.
1000
+ trns_im = trns_im .convert ("RGB" )
1001
+ trns = trns_im .getpixel ((0 , 0 ))
995
1002
996
1003
elif self .mode == "P" and mode == "RGBA" :
997
1004
t = self .info ["transparency" ]
@@ -1009,14 +1016,14 @@ def convert_transparency(m, v):
1009
1016
new = self ._new (im )
1010
1017
from . import ImagePalette
1011
1018
1012
- new .palette = ImagePalette .raw ("RGB" , new .im .getpalette ("RGB" ))
1019
+ new .palette = ImagePalette .ImagePalette ("RGB" , new .im .getpalette ("RGB" ))
1013
1020
if delete_trns :
1014
1021
# This could possibly happen if we requantize to fewer colors.
1015
1022
# The transparency would be totally off in that case.
1016
1023
del new .info ["transparency" ]
1017
1024
if trns is not None :
1018
1025
try :
1019
- new .info ["transparency" ] = new .palette .getcolor (trns )
1026
+ new .info ["transparency" ] = new .palette .getcolor (trns , new )
1020
1027
except Exception :
1021
1028
# if we can't make a transparent color, don't leave the old
1022
1029
# transparency hanging around to mess us up.
@@ -1039,16 +1046,25 @@ def convert_transparency(m, v):
1039
1046
raise ValueError ("illegal conversion" ) from e
1040
1047
1041
1048
new_im = self ._new (im )
1049
+ if mode == "P" and palette != ADAPTIVE :
1050
+ from . import ImagePalette
1051
+
1052
+ new_im .palette = ImagePalette .ImagePalette ("RGB" , list (range (256 )) * 3 )
1042
1053
if delete_trns :
1043
1054
# crash fail if we leave a bytes transparency in an rgb/l mode.
1044
1055
del new_im .info ["transparency" ]
1045
1056
if trns is not None :
1046
1057
if new_im .mode == "P" :
1047
1058
try :
1048
- new_im .info ["transparency" ] = new_im .palette .getcolor (trns )
1049
- except Exception :
1059
+ new_im .info ["transparency" ] = new_im .palette .getcolor (trns , new_im )
1060
+ except ValueError as e :
1050
1061
del new_im .info ["transparency" ]
1051
- warnings .warn ("Couldn't allocate palette entry for transparency" )
1062
+ if str (e ) != "cannot allocate more than 256 colors" :
1063
+ # If all 256 colors are in use,
1064
+ # then there is no need for transparency
1065
+ warnings .warn (
1066
+ "Couldn't allocate palette entry for transparency"
1067
+ )
1052
1068
else :
1053
1069
new_im .info ["transparency" ] = trns
1054
1070
return new_im
@@ -1732,7 +1748,7 @@ def putpalette(self, data, rawmode="RGB"):
1732
1748
Attaches a palette to this image. The image must be a "P", "PA", "L"
1733
1749
or "LA" image.
1734
1750
1735
- The palette sequence must contain either 768 integer values, or 1024
1751
+ The palette sequence must contain at most 768 integer values, or 1024
1736
1752
integer values if alpha is included. Each group of values represents
1737
1753
the red, green, blue (and alpha if included) values for the
1738
1754
corresponding pixel index. Instead of an integer sequence, you can use
@@ -1745,7 +1761,6 @@ def putpalette(self, data, rawmode="RGB"):
1745
1761
1746
1762
if self .mode not in ("L" , "LA" , "P" , "PA" ):
1747
1763
raise ValueError ("illegal image mode" )
1748
- self .load ()
1749
1764
if isinstance (data , ImagePalette .ImagePalette ):
1750
1765
palette = ImagePalette .raw (data .rawmode , data .palette )
1751
1766
else :
@@ -1792,7 +1807,7 @@ def putpixel(self, xy, value):
1792
1807
and len (value ) in [3 , 4 ]
1793
1808
):
1794
1809
# RGB or RGBA value for a P image
1795
- value = self .palette .getcolor (value )
1810
+ value = self .palette .getcolor (value , self )
1796
1811
return self .im .putpixel (xy , value )
1797
1812
1798
1813
def remap_palette (self , dest_map , source_palette = None ):
@@ -1813,6 +1828,7 @@ def remap_palette(self, dest_map, source_palette=None):
1813
1828
1814
1829
if source_palette is None :
1815
1830
if self .mode == "P" :
1831
+ self .load ()
1816
1832
real_source_palette = self .im .getpalette ("RGB" )[:768 ]
1817
1833
else : # L-mode
1818
1834
real_source_palette = bytearray (i // 3 for i in range (768 ))
@@ -1850,23 +1866,19 @@ def remap_palette(self, dest_map, source_palette=None):
1850
1866
m_im = self .copy ()
1851
1867
m_im .mode = "P"
1852
1868
1853
- m_im .palette = ImagePalette .ImagePalette (
1854
- "RGB" , palette = mapping_palette * 3 , size = 768
1855
- )
1869
+ m_im .palette = ImagePalette .ImagePalette ("RGB" , palette = mapping_palette * 3 )
1856
1870
# possibly set palette dirty, then
1857
1871
# m_im.putpalette(mapping_palette, 'L') # converts to 'P'
1858
1872
# or just force it.
1859
1873
# UNDONE -- this is part of the general issue with palettes
1860
- m_im .im .putpalette (* m_im .palette .getdata ())
1874
+ m_im .im .putpalette ("RGB;L" , m_im .palette .tobytes ())
1861
1875
1862
1876
m_im = m_im .convert ("L" )
1863
1877
1864
1878
# Internally, we require 768 bytes for a palette.
1865
1879
new_palette_bytes = palette_bytes + (768 - len (palette_bytes )) * b"\x00 "
1866
1880
m_im .putpalette (new_palette_bytes )
1867
- m_im .palette = ImagePalette .ImagePalette (
1868
- "RGB" , palette = palette_bytes , size = len (palette_bytes )
1869
- )
1881
+ m_im .palette = ImagePalette .ImagePalette ("RGB" , palette = palette_bytes )
1870
1882
1871
1883
return m_im
1872
1884
0 commit comments