@@ -1731,39 +1731,43 @@ def _writeImg(self, data, id, smask=None):
17311731 'Subtype' : Name ('Image' ),
17321732 'Width' : width ,
17331733 'Height' : height ,
1734- 'ColorSpace' : Name ({1 : 'DeviceGray' ,
1735- 3 : 'DeviceRGB' }[color_channels ]),
1734+ 'ColorSpace' : Name ({1 : 'DeviceGray' , 3 : 'DeviceRGB' }[color_channels ]),
17361735 'BitsPerComponent' : 8 }
17371736 if smask :
17381737 obj ['SMask' ] = smask
17391738 if mpl .rcParams ['pdf.compression' ]:
17401739 if data .shape [- 1 ] == 1 :
17411740 data = data .squeeze (axis = - 1 )
1741+ png = {'Predictor' : 10 , 'Colors' : color_channels , 'Columns' : width }
17421742 img = Image .fromarray (data )
17431743 img_colors = img .getcolors (maxcolors = 256 )
17441744 if color_channels == 3 and img_colors is not None :
1745- # Convert to indexed color if there are 256 colors or fewer
1746- # This can significantly reduce the file size
1745+ # Convert to indexed color if there are 256 colors or fewer. This can
1746+ # significantly reduce the file size.
17471747 num_colors = len (img_colors )
1748- # These constants were converted to IntEnums and deprecated in
1749- # Pillow 9.2
1750- dither = getattr (Image , 'Dither' , Image ).NONE
1751- pmode = getattr (Image , 'Palette' , Image ).ADAPTIVE
1752- img = img .convert (
1753- mode = 'P' , dither = dither , palette = pmode , colors = num_colors
1754- )
1748+ palette = np .array ([comp for _ , color in img_colors for comp in color ],
1749+ dtype = np .uint8 )
1750+ palette24 = ((palette [0 ::3 ].astype (np .uint32 ) << 16 ) |
1751+ (palette [1 ::3 ].astype (np .uint32 ) << 8 ) |
1752+ palette [2 ::3 ])
1753+ rgb24 = ((data [:, :, 0 ].astype (np .uint32 ) << 16 ) |
1754+ (data [:, :, 1 ].astype (np .uint32 ) << 8 ) |
1755+ data [:, :, 2 ])
1756+ indices = np .argsort (palette24 ).astype (np .uint8 )
1757+ rgb8 = indices [np .searchsorted (palette24 , rgb24 , sorter = indices )]
1758+ img = Image .fromarray (rgb8 , mode = 'P' )
1759+ img .putpalette (palette )
17551760 png_data , bit_depth , palette = self ._writePng (img )
17561761 if bit_depth is None or palette is None :
17571762 raise RuntimeError ("invalid PNG header" )
1758- palette = palette [:num_colors * 3 ] # Trim padding
1759- obj ['ColorSpace' ] = Verbatim (
1760- b'[/Indexed /DeviceRGB %d %s]'
1761- % (num_colors - 1 , pdfRepr (palette )))
1763+ palette = palette [:num_colors * 3 ] # Trim padding; remove for Pillow>=9
1764+ obj ['ColorSpace' ] = [Name ('Indexed' ), Name ('DeviceRGB' ),
1765+ num_colors - 1 , palette ]
17621766 obj ['BitsPerComponent' ] = bit_depth
1763- color_channels = 1
1767+ png ['Colors' ] = 1
1768+ png ['BitsPerComponent' ] = bit_depth
17641769 else :
17651770 png_data , _ , _ = self ._writePng (img )
1766- png = {'Predictor' : 10 , 'Colors' : color_channels , 'Columns' : width }
17671771 else :
17681772 png = None
17691773 self .beginStream (
0 commit comments