Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

document.add_picture ZeroDivisionError: division by zero #515

Open
luowqn opened this issue Jul 5, 2018 · 7 comments
Open

document.add_picture ZeroDivisionError: division by zero #515

luowqn opened this issue Jul 5, 2018 · 7 comments

Comments

@luowqn
Copy link

luowqn commented Jul 5, 2018

Hello,I have a question,i want to add a picture to doc
Mycode:

from docx import Document
from docx.shared import Inches

document = Document()
document.add_picture('./test.jpg',width=Inches(1.25))
document.save('demo.docx')
Error:
`C:\Users\luowq\AppData\Local\Programs\Python\Python36\python3.exe F:/学习代码/study/python/imageCompareSvr/main.py
Traceback (most recent call last):
  File "F:/学习代码/study/python/imageCompareSvr/main.py", line 28, in <module>
    document.add_picture('./test.jpg',width=Inches(1.25))
  File "C:\Users\luowq\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\document.py", line 79, in add_picture
    return run.add_picture(image_path_or_stream, width, height)
  File "C:\Users\luowq\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\text\run.py", line 62, in add_picture
    inline = self.part.new_pic_inline(image_path_or_stream, width, height)
  File "C:\Users\luowq\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\parts\document.py", line 93, in new_pic_inline
    cx, cy = image.scaled_dimensions(width, height)
  File "C:\Users\luowq\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\image\image.py", line 159, in scaled_dimensions
    scaling_factor = float(width) / float(self.width)
  File "C:\Users\luowq\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\image\image.py", line 127, in width
    return Inches(self.px_width / self.horz_dpi)
ZeroDivisionError: division by zero
@scanny
Copy link
Contributor

scanny commented Jul 5, 2018

I've shortened your code to get rid of lines that I don't believe are related. Please ensure the error still occurs with this minimal code to reproduce.

I believe you're going to find that your JPEG file is missing some important information, in particular, the horizontal DPI setting. Try using another JPEG file and seeing if the error reoccurs.

@floriaanpost
Copy link

floriaanpost commented Jul 1, 2020

In case anyone gets this error... It is "solved" by monkey patching the height and width of the Image class:

from docx.image.image import Image
from docx.shared import Inches

@property
def image_width(self):
    if (self.horz_dpi == 0):
        return Inches(self.px_width / 72)
    return Inches(self.px_width / self.horz_dpi)


@property
def image_height(self):
    if (self.vert_dpi == 0):
        return Inches(self.px_height / 72)
    return Inches(self.px_height / self.vert_dpi)


Image.width = image_width
Image.height = image_height

If don't have a clue to why it is zero in the first place, as the images (in my case) do not appear to have an header, so it should default to 72 dpi.

@Swannbm
Copy link

Swannbm commented Nov 1, 2020

I think it's a True issue because in readthedoc it says that it should default to 72 DPI.

@taiebnoe
Copy link

Thanks! I had the same issue. Jpegs with bad header. Hope this gets fixed in the main branch.

@GISallover
Copy link

So I couldn't get this monkey patch to work, so I set out to try and fix the actual bug. A bit beyond my pay grade, but I did track it down to this function in tiff.py:

` def _dpi(self, resolution_tag):
"""
Return the dpi value calculated for resolution_tag, which can be
either TIFF_TAG.X_RESOLUTION or TIFF_TAG.Y_RESOLUTION. The
calculation is based on the values of both that tag and the
TIFF_TAG.RESOLUTION_UNIT tag in this parser's |_IfdEntries| instance.
"""

    ifd_entries = self._ifd_entries
    logging.debug(resolution_tag)
    if resolution_tag not in ifd_entries:
        logging.debug("no tag")
        return 72`

That error trap simply isn't going off.. because the photos do have resolution tags. There's something else that's preventing these values from getting passed correctly, but that's why it's not defaulting.

Anyways, I did manage to get it to work simply put putting line 343 of tiff.py in a try/except block and setting a default value of 72 there. I don't even know if this is referring to resolution... but I figured it had something to do with sizing so I started there, and it worked.

Hope that gives a starting point to anyone

In case anyone gets this error... It is "solved" by monkey patching the height and width of the Image class:

from docx.image.image import Image
from docx.shared import Inches

@property
def image_width(self):
    if (self.horz_dpi == 0):
        return Inches(self.px_width / 72)
    return Inches(self.px_width / self.horz_dpi)


@property
def image_height(self):
    if (self.vert_dpi == 0):
        return Inches(self.px_height / 72)
    return Inches(self.px_height / self.vert_dpi)


Image.width = image_width
Image.height = image_height

If don't have a clue to why it is zero in the first place, as the images (in my case) do not appear to have an header, so it should default to 72 dpi.

@netaddict
Copy link

Had the same issue in 2024, the bug still exists.

@python-openxml python-openxml deleted a comment from ABIDULLAH786 Sep 27, 2024
@DayDotMe
Copy link

DayDotMe commented Nov 29, 2024

Just in case, I solved this using Pillow. It's probably a bit overkill but hey, it works.

# before:

picture_stream = BytesIO(picture_content) 
run = paragraph.add_run()
run.add_picture(picture_stream) # raises the ZeroDivisionError

# after:

picture_stream = BytesIO(picture_content)
image = Image.open(picture_stream)
clean_stream = BytesIO()
image.save(clean_stream, format=image.format)
clean_stream.seek(0)
run = paragraph.add_run()
run.add_picture(clean_stream)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants