1

I'm using reportlab to generate PDF documents from a python API. The documents include pictures (previously taken with a camera or mobile device) loaded with :

from reportlab.platypus import Image
img = Image(path)
story.append(img)

Problem : some images are not displayed with the right orientation (some EXIF data is probably lost or ignored at some point).

I encountered a similar problem with PIL once, and the solution I chose was to use Wand instead of PIL or Pillow, but it appears ReportLab only uses PIL to handle images with Python...

I found this code snippet from another question but I'm not sure how to edit reportlab to include it, or if it's a good way to go.

I'm surprised I didn't find anything on this subject, I can't be the only one wanting to include pictures in a reportlab-generated PDF...

Here is a picture with the original image opened in Preview on the left and the PDF on the right: 1

Thanks for any help, I've been struggling with that for hours now...

Community
  • 1
  • 1
Kyrill
  • 227
  • 1
  • 11

2 Answers2

1

I actually had the same problem with pyCairo.

I have a bunch of JPEG images, some of them are directly put in the PDF document, some other are manipulated with pyCairo before being inserted into the PDF.

When inserting a JPEG image into a reportlab PDF document, or when converting an image from JPEG to PNG to work with pyCairo (pyCairo doesn't work with JPEG as far as I know), the orientation of the image stored in the EXIF gets lost.

Here's what I ended up doing :

from reportlab.platypus import Image
from wand.image import Image as WandImage

def AddAPictureToDocument():

     with WandImage(filename=path) as wimg:
          WandConvertToPNG(wimg,pngDestinationPath)

     img = Image(pngDestinationPath)
     story.append(img)

def WandConvertToPNG(img, savepath):

    exif = {}
    exif.update((k[5:], v) for k, v in img.metadata.items()
                if k.startswith('exif:'))

    orientation = exif['Orientation']

    with img.convert('png') as converted:
        if   int(orientation) == 3 :
            converted.rotate(180)
        elif int(orientation) == 6 :
            converted.rotate(90)
        elif int(orientation) == 8 :
            converted.rotate(270)

    converted.save(filename=savepath)

But it can be pretty slow, especially with pyCairo, since I need to:

1) Convert from JPEG to PNG,

2) Rotate the image to its correct orientation

3) Use pyCairo to draw things on the image

4) Save the pyCairo manipulated image to a PNG

5) Convert the PNG to a JPEG to compress the image

Was it naive of me to assume that image librairies such as PIL or Wand would handle the orientation of the image after a JPEG->PNG conversion ?

Anyways, I'm still looking for a better solution.

Kyrill
  • 227
  • 1
  • 11
0

Try to use included Image class methods such as FLIP_TOP_BOTTOM and FLIP_LEFT_RIGHT. Here is the code, which I used in the same situation with reportlab.

from PIL import Image


def flip_image(image_path):
    img = Image.open(image_path)
    out = img.transpose(Image.FLIP_TOP_BOTTOM)
    
    out.save(img)

    return image_path
Vitaly Sem
  • 11
  • 2