@@ -2115,10 +2115,6 @@ def save(self, fp, format=None, **params):
21152115 # may mutate self!
21162116 self ._ensure_mutable ()
21172117
2118- save_all = params .pop ("save_all" , False )
2119- self .encoderinfo = params
2120- self .encoderconfig = ()
2121-
21222118 preinit ()
21232119
21242120 ext = os .path .splitext (filename )[1 ].lower ()
@@ -2133,11 +2129,20 @@ def save(self, fp, format=None, **params):
21332129
21342130 if format .upper () not in SAVE :
21352131 init ()
2136- if save_all :
2132+ if params . pop ( ' save_all' , False ) :
21372133 save_handler = SAVE_ALL [format .upper ()]
21382134 else :
21392135 save_handler = SAVE [format .upper ()]
21402136
2137+ if params .get ('convert_mode' ):
2138+ plugin = sys .modules [save_handler .__module__ ]
2139+ converted_im = self ._convert_mode (plugin , params )
2140+ if converted_im :
2141+ return converted_im .save (fp , format , ** params )
2142+
2143+ self .encoderinfo = params
2144+ self .encoderconfig = ()
2145+
21412146 if open_fp :
21422147 if params .get ("append" , False ):
21432148 # Open also for reading ("+"), because TIFF save_all
@@ -2153,6 +2158,37 @@ def save(self, fp, format=None, **params):
21532158 if open_fp :
21542159 fp .close ()
21552160
2161+ def _convert_mode (self , plugin , params ):
2162+ if not hasattr (plugin , '_convert_mode' ):
2163+ return
2164+ new_mode = plugin ._convert_mode (self )
2165+ if self .mode == 'LA' and new_mode == 'P' :
2166+ alpha = self .getchannel ('A' )
2167+ # Convert the image into P mode but only use 255 colors
2168+ # in the palette out of 256.
2169+ im = self .convert ('L' ) \
2170+ .convert ('P' , palette = ADAPTIVE , colors = 255 )
2171+ # Set all pixel values below 128 to 255, and the rest to 0.
2172+ mask = eval (alpha , lambda px : 255 if px < 128 else 0 )
2173+ # Paste the color of index 255 and use alpha as a mask.
2174+ im .paste (255 , mask )
2175+ # The transparency index is 255.
2176+ im .info ['transparency' ] = 255
2177+ return im
2178+
2179+ elif self .mode == 'I' :
2180+ im = self .point ([i // 256 for i in range (65536 )], 'L' )
2181+ return im .convert (new_mode ) if new_mode != 'L' else im
2182+
2183+ elif self .mode in ('RGBA' , 'LA' ) and new_mode in ('RGB' , 'L' ):
2184+ fill_color = params .get ('fill_color' , 'white' )
2185+ background = new (new_mode , self .size , fill_color )
2186+ background .paste (self , self .getchannel ('A' ))
2187+ return background
2188+
2189+ elif new_mode :
2190+ return self .convert (new_mode )
2191+
21562192 def seek (self , frame ):
21572193 """
21582194 Seeks to the given frame in this sequence file. If you seek
0 commit comments