Implement PNG palettization

This commit is contained in:
James R. Barlow
2018-04-16 11:18:52 -07:00
parent f755fb76ee
commit 0e6b8042b0
2 changed files with 30 additions and 4 deletions
+8
View File
@@ -27,6 +27,7 @@ import logging
import warnings
from tempfile import TemporaryFile
from ctypes.util import find_library
from binascii import unhexlify
from .lib._leptonica import ffi
from functools import lru_cache
from enum import Enum
@@ -517,6 +518,13 @@ class CompressedData:
return getattr(self._compdata, name)
raise AttributeError(name)
def get_palette(self):
buf = ffi.buffer(self._compdata.cmapdatahex,
self._compdata.ncolors * 7 + 3)
hex_str = bytes(buf).decode('ascii')
hex_str = hex_str[1:-1].replace(' ', '')
return unhexlify(hex_str)
@staticmethod
def _destroy(compdata):
pp = ffi.new('L_COMP_DATA **', compdata)
+22 -4
View File
@@ -1171,15 +1171,33 @@ def optimize_pdf(
if compdata.predictor > 0:
predictor = pikepdf.Dictionary({'/Predictor': compdata.predictor})
im_obj.write(
compdata.read(), pikepdf.Name('/FlateDecode'), predictor
)
im_obj.BitsPerComponent = compdata.bps
im_obj.Width = compdata.w
im_obj.Height = compdata.h
if compdata.ncolors > 0:
palette_stream = pikepdf.Stream(pike, compdata.get_palette())
palette = [pikepdf.Name('/Indexed'), pikepdf.Name('/DeviceRGB'),
compdata.ncolors - 1, palette_stream]
#cs = pike.make_indirect(palette)
cs = palette
else:
if compdata.spp == 1:
cs = pikepdf.Name('/DeviceGray')
elif compdata.spp == 3:
cs = pikepdf.Name('/DeviceRGB')
elif compdata.spp == 4:
cs = pikepdf.Name('/DeviceCMYK')
im_obj.ColorSpace = cs
im_obj.write(compdata.read(), pikepdf.Name('/FlateDecode'), predictor)
pike.save(output_file, preserve_pdfa=True)
input_size = Path(input_file).stat().st_size
output_size = Path(output_file).stat().st_size
improvement = 100.0 * ((input_size/output_size) - 1)
improvement = input_size / output_size
log.info("Optimize reduced size by {:.1f}".format(improvement))