diff --git a/scripts/pdf2html.py b/scripts/pdf2html.py index d6871dc..08c9c66 100644 --- a/scripts/pdf2html.py +++ b/scripts/pdf2html.py @@ -45,6 +45,26 @@ SOFT_HYPHEN = "\u00ad" OCR = False +def _image_png(raw): + """Байты картинки блока -> настоящий PNG. + + b["ext"] врёт: на «Запускаем Ansible» 3-го изд. блоки с ext="png" и + colorspace=4 на деле — CMYK JPEG (magic FFD8, подтверждено `file`), и + PNG-инструменты (pngquant) отказываются их декодировать с именем .png. + Вместо доверия заявленному формату декодируем через Pixmap (MuPDF сам + распознаёт реальный формат по данным) и всегда отдаём RGB PNG — тогда + имя файла (.png) не расходится с содержимым и CMYK не ловит инверсию + цвета в читалках, которые не ждут Adobe-JPEG с четырьмя каналами. + """ + try: + pix = pymupdf.Pixmap(raw) + if pix.colorspace is not None and pix.colorspace.n not in (1, 3): + pix = pymupdf.Pixmap(pymupdf.csRGB, pix) + return pix.tobytes("png") + except Exception: + return raw # не смогли декодировать — пишем как есть, лучше так, чем ничего + + def style(font, flags=0): """Полужирный и курсив: сначала флаги, затем имя — имена бывают пустыми.""" f = font.lower() @@ -330,7 +350,7 @@ for pno, page in enumerate(doc): continue # подложка отсканированной полосы: текст берём из OCR-слоя img_n += 1 name = "img%02d.png" % img_n - (IMGDIR / name).write_bytes(b["image"]) + (IMGDIR / name).write_bytes(_image_png(b["image"])) if open_para: parts.append(open_para) open_para = None