Se encuentra con un error compression error -2
. Sería genial si alguien pudiera proporcionar algunos consejos.
Adjunto el PDF con el problema:
5_EN.pdf
Mensaje de error:
Processing Pages: 1/28...mupdf: compression error -2
Traceback (most recent call last):
File "/Users/erikchan/Downloads/convert.py", line 10, in <module>
parse(pdf_files[i], docx_files[i])
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pdf2docx/main.py", line 31, in parse
cv.make_docx(indexes, multi_processing)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pdf2docx/converter.py", line 118, in make_docx
self._make_docx(page_indexes)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pdf2docx/converter.py", line 192, in _make_docx
self.initialize(page).parse().make_page(self.doc_docx)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pdf2docx/converter.py", line 172, in initialize
images, paths = self._paths_extractor.extract_paths(page)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pdf2docx/shape/Path.py", line 61, in extract_paths
image = largest.to_image(page) if largest.contains_curve else None
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pdf2docx/shape/Path.py", line 140, in to_image
return ImagesExtractor.clip_page(page, bbox, zoom)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pdf2docx/image/Image.py", line 60, in clip_page
return cls.to_raw_dict(image, bbox)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/pdf2docx/image/Image.py", line 50, in to_raw_dict
'image': image.getPNGData()
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/fitz/fitz.py", line 5899, in getPNGData
barray = self._getImageData(1)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/fitz/fitz.py", line 5868, in _getImageData
return _fitz.Pixmap__getImageData(self, format)
RuntimeError: compression error -2
Gracias por proporcionar este caso.
En su pdf existen muchos gráficos vectoriales, es decir, path
como una línea, una curva y su combinación. Sin embargo, esta biblioteca ignora actualmente la ruta de recorte debido a un problema técnico al extraer estas rutas de PDF. Algunas rutas están fuera de la página sin ser recortadas, lo que da como resultado este problema compression error -2
.
Además, dos números más para convertir este pdf:
El color de la ruta es incorrecto. Supongo que la causa principal es que actualmente solo se consideran Device Color Space
(Gray / RGB / CMYK), mientras que esta muestra de pdf puede seguir un espacio de color especial como Indexed CS
, DeviceN CS
.
se eliminan las imágenes superpuestas. python-docx
se aplica para escribir el docx convertido, pero python-docx
no admite elementos flotantes. Por lo tanto, las imágenes flotantes se eliminan como compromiso.
Entonces, desafortunadamente, pdf2docx
no puede convertir su pdf por ahora. Deben realizarse al menos los siguientes esfuerzos:
Gracias @dothinking por la clara explicación. Me sorprende que esta biblioteca no sea más popular de lo que es. La versión actual ya es muy buena y sé que mucha gente puede beneficiarse de ella.
Hágame saber cómo puedo ayudar a resolver cualquiera de los problemas que enumeró (necesitaré orientación). Ya sea para resolver los errores, realizar pruebas o de otra manera.
Muchas gracias @ echan00.
Algunos avances en este tema:
PyMuPDF
publicó una nueva característica sobre la ruta de extracción. Lo investigaré y espero poder resolver este problema.Después de eso, se agradece cualquier prueba o sugerencia.
Comente sobre 2020-12-31: el último PyMuPDF 1.18.5 resolvió este problema en parte, pero no perfectamente, especialmente el trazado de recorte.
Dado que la imagen en línea es compatible con python-docx
, los pasos para explorar la imagen flotante:
behind text
)resultados de la estructura xml:
<wp:inline>
nodo debajo de <w:drawing>
<wp:anchor>
nodo debajo de <w:drawing>
<wp:positionH>
y <wp:positionV>
para definir la posición fijaEntonces, la idea es crear <wp:anchor>
nodo, luego agregar subnodos:
<wp:positionH>
y <wp:positionV>
Parece que la imagen flotante con python-docx
es una solicitud común, documente aquí para compartir.
# -*- coding: utf-8 -*-
'''
Implement floating image based on python-docx.
- Text wrapping style: BEHIND TEXT <wp:anchor behindDoc="1">
- Picture position: top-left corner of PAGE `<wp:positionH relativeFrom="page">`.
Create a docx sample (Layout | Positions | More Layout Options) and explore the
source xml (Open as a zip | word | document.xml) to implement other text wrapping
styles and position modes per `CT_Anchor._anchor_xml()`.
'''
from docx.oxml import parse_xml, register_element_cls
from docx.oxml.ns import nsdecls
from docx.oxml.shape import CT_Picture
from docx.oxml.xmlchemy import BaseOxmlElement, OneAndOnlyOne
# refer to docx.oxml.shape.CT_Inline
class CT_Anchor(BaseOxmlElement):
"""
``<w:anchor>`` element, container for a floating image.
"""
extent = OneAndOnlyOne('wp:extent')
docPr = OneAndOnlyOne('wp:docPr')
graphic = OneAndOnlyOne('a:graphic')
<strong i="7">@classmethod</strong>
def new(cls, cx, cy, shape_id, pic, pos_x, pos_y):
"""
Return a new ``<wp:anchor>`` element populated with the values passed
as parameters.
"""
anchor = parse_xml(cls._anchor_xml(pos_x, pos_y))
anchor.extent.cx = cx
anchor.extent.cy = cy
anchor.docPr.id = shape_id
anchor.docPr.name = 'Picture %d' % shape_id
anchor.graphic.graphicData.uri = (
'http://schemas.openxmlformats.org/drawingml/2006/picture'
)
anchor.graphic.graphicData._insert_pic(pic)
return anchor
<strong i="8">@classmethod</strong>
def new_pic_anchor(cls, shape_id, rId, filename, cx, cy, pos_x, pos_y):
"""
Return a new `wp:anchor` element containing the `pic:pic` element
specified by the argument values.
"""
pic_id = 0 # Word doesn't seem to use this, but does not omit it
pic = CT_Picture.new(pic_id, filename, rId, cx, cy)
anchor = cls.new(cx, cy, shape_id, pic, pos_x, pos_y)
anchor.graphic.graphicData._insert_pic(pic)
return anchor
<strong i="9">@classmethod</strong>
def _anchor_xml(cls, pos_x, pos_y):
return (
'<wp:anchor distT="0" distB="0" distL="0" distR="0" simplePos="0" relativeHeight="0" \n'
' behindDoc="1" locked="0" layoutInCell="1" allowOverlap="1" \n'
' %s>\n'
' <wp:simplePos x="0" y="0"/>\n'
' <wp:positionH relativeFrom="page">\n'
' <wp:posOffset>%d</wp:posOffset>\n'
' </wp:positionH>\n'
' <wp:positionV relativeFrom="page">\n'
' <wp:posOffset>%d</wp:posOffset>\n'
' </wp:positionV>\n'
' <wp:extent cx="914400" cy="914400"/>\n'
' <wp:wrapNone/>\n'
' <wp:docPr id="666" name="unnamed"/>\n'
' <wp:cNvGraphicFramePr>\n'
' <a:graphicFrameLocks noChangeAspect="1"/>\n'
' </wp:cNvGraphicFramePr>\n'
' <a:graphic>\n'
' <a:graphicData uri="URI not set"/>\n'
' </a:graphic>\n'
'</wp:anchor>' % ( nsdecls('wp', 'a', 'pic', 'r'), int(pos_x), int(pos_y) )
)
# refer to docx.parts.story.BaseStoryPart.new_pic_inline
def new_pic_anchor(part, image_descriptor, width, height, pos_x, pos_y):
"""Return a newly-created `w:anchor` element.
The element contains the image specified by *image_descriptor* and is scaled
based on the values of *width* and *height*.
"""
rId, image = part.get_or_add_image(image_descriptor)
cx, cy = image.scaled_dimensions(width, height)
shape_id, filename = part.next_id, image.filename
return CT_Anchor.new_pic_anchor(shape_id, rId, filename, cx, cy, pos_x, pos_y)
# refer to docx.text.run.add_picture
def add_float_picture(p, image_path_or_stream, width=None, height=None, pos_x=0, pos_y=0):
"""Add float picture at fixed position `pos_x` and `pos_y` to the top-left point of page.
"""
run = p.add_run()
anchor = new_pic_anchor(run.part, image_path_or_stream, width, height, pos_x, pos_y)
run._r.add_drawing(anchor)
# refer to docx.oxml.shape.__init__.py
register_element_cls('wp:anchor', CT_Anchor)
if __name__ == '__main__':
from docx import Document
from docx.shared import Inches, Pt
document = Document()
# add a floating image
p = document.add_paragraph()
add_float_picture(p, 'test.png', width=Inches(5.0), pos_x=Pt(20), pos_y=Pt(30))
# add text
p.add_run('Hello World'*50)
document.save('output.docx')
Bien @dothinking , parece que sabes exactamente cuáles son los problemas. Tengo una variedad de archivos PDF que puedo ayudar a probar una vez que esté listo
@dothinking ¡Muchas gracias por tu código de muestra! Resuelve mi problema a la perfección !!!!
No tuve tiempo para este proyecto durante tanto tiempo. La nueva versión v0.5.0
ahora está disponible para resolver parcialmente este problema:
PyMuPDF
, pero no es tan buena para formas complicadas, por ejemplo, ruta de recorte.Con esta última versión, el pdf de muestra se puede convertir con éxito, pero aún necesita mucho trabajo para mejorar la calidad del archivo docx convertido, debido al estilo complicado / magnífico.
Vaya, esta es una gran actualización. Muchas gracias por tu arduo trabajo @dothinking
Comentario más útil
Parece que la imagen flotante con
python-docx
es una solicitud común, documente aquí para compartir.