@@ -2026,10 +2026,6 @@ def save(self, fp, format=None, **params):
20262026 # may mutate self!
20272027 self ._ensure_mutable ()
20282028
2029- save_all = params .pop ("save_all" , False )
2030- self .encoderinfo = params
2031- self .encoderconfig = ()
2032-
20332029 preinit ()
20342030
20352031 ext = os .path .splitext (filename )[1 ].lower ()
@@ -2044,11 +2040,20 @@ def save(self, fp, format=None, **params):
20442040
20452041 if format .upper () not in SAVE :
20462042 init ()
2047- if save_all :
2043+ if params . pop ( ' save_all' , False ) :
20482044 save_handler = SAVE_ALL [format .upper ()]
20492045 else :
20502046 save_handler = SAVE [format .upper ()]
20512047
2048+ if params .get ('convert_mode' ):
2049+ plugin = sys .modules [save_handler .__module__ ]
2050+ converted_im = self ._convert_mode (plugin , params )
2051+ if converted_im :
2052+ return converted_im .save (fp , format , ** params )
2053+
2054+ self .encoderinfo = params
2055+ self .encoderconfig = ()
2056+
20522057 if open_fp :
20532058 if params .get ("append" , False ):
20542059 fp = builtins .open (filename , "r+b" )
@@ -2064,6 +2069,37 @@ def save(self, fp, format=None, **params):
20642069 if open_fp :
20652070 fp .close ()
20662071
2072+ def _convert_mode (self , plugin , params ):
2073+ if not hasattr (plugin , '_convert_mode' ):
2074+ return
2075+ new_mode = plugin ._convert_mode (self )
2076+ if self .mode == 'LA' and new_mode == 'P' :
2077+ alpha = self .getchannel ('A' )
2078+ # Convert the image into P mode but only use 255 colors
2079+ # in the palette out of 256.
2080+ im = self .convert ('L' ) \
2081+ .convert ('P' , palette = ADAPTIVE , colors = 255 )
2082+ # Set all pixel values below 128 to 255, and the rest to 0.
2083+ mask = eval (alpha , lambda px : 255 if px < 128 else 0 )
2084+ # Paste the color of index 255 and use alpha as a mask.
2085+ im .paste (255 , mask )
2086+ # The transparency index is 255.
2087+ im .info ['transparency' ] = 255
2088+ return im
2089+
2090+ elif self .mode == 'I' :
2091+ im = self .point ([i // 256 for i in range (65536 )], 'L' )
2092+ return im .convert (new_mode ) if new_mode != 'L' else im
2093+
2094+ elif self .mode in ('RGBA' , 'LA' ) and new_mode in ('RGB' , 'L' ):
2095+ fill_color = params .get ('fill_color' , 'white' )
2096+ background = new (new_mode , self .size , fill_color )
2097+ background .paste (self , self .getchannel ('A' ))
2098+ return background
2099+
2100+ elif new_mode :
2101+ return self .convert (new_mode )
2102+
20672103 def seek (self , frame ):
20682104 """
20692105 Seeks to the given frame in this sequence file. If you seek
0 commit comments