0

I am trying to convert an imgkit image into a PIL image to modify it. imgkit successfully converted the html to image when I tried to use a file. When I use BytesIO and try to convert to a PIL image, im getting an error.

Here is my code:

img = imgkit.from_string(template.render(a=elements, r=range(len(elements))), False, config=config)
bytesImg = BytesIO(img)
bytesImg.seek(0)
image = Image.open(bytesImg) #error here

PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x102082680>

I already saw this and this. Am I incorrectly converting the imgkit image to bytes or is there some other error?

Using Pillow 8.1 Python 3.9 and imgkit 1.0.2

Ceres
  • 2,498
  • 1
  • 10
  • 28
  • 1
    What are the first 20 bytes of `bytesImg` please? – Mark Setchell Jan 28 '21 at 08:37
  • @MarkSetchell . I used a print(bytesImg.read()) and got b'%PDF-1.4\n1 0 obj\n<<\n'. if that is what you are asking for – Ceres Jan 28 '21 at 08:43
  • 1
    That looks like a PDF which PIL can only write, not read https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html Can you force ImgKit to generate a JPEG? – Mark Setchell Jan 28 '21 at 08:53
  • Yeah, it worked. I messed up the config variable and it converted it to a pdf instead of image. – Ceres Jan 28 '21 at 09:07

3 Answers3

1

Am I incorrectly converting the imgkit image to bytes or is there some other error?

I would start from checking if your bytes represents image understand by your Pillow. Built-in module imghdr should suffice if you are excepting one of format known by it (see table in docs). Usage in this case:

import imghdr

...

print(imghdr.what(None, h=img))

If it does identify format then check if it is supported by your Pillow, else you would need to manually check file signature (few starting bytes).

Ceres
  • 2,498
  • 1
  • 10
  • 28
Daweo
  • 31,313
  • 3
  • 12
  • 25
  • I tried imghdr.what(None, h=img) and got 'jpeg'. – Ceres Jan 28 '21 at 08:57
  • Yeah, you were right. my config variable was messed up and converted to pdf in my main code. it didn't show up in testing. Thanks – Ceres Jan 28 '21 at 09:06
0

imgkit was converting the html to pdf because the config variable was messed up.

use

which wkhtmltoimage

to find path to wkhtmltoimage and set

config = imgkit.config(wkhtmltoimage="path found")
Ceres
  • 2,498
  • 1
  • 10
  • 28
0

For different version of python/Pillow/imgkit (in my case they were 3.6.9/8.4.0/1.2.3) experienced similar problem.

PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x102082680>

Check with

print(imghdr.what(None, h=img))

showed None

When printing first bytes, turned out that there was additional output from imgkit/wkhtmltoimage

b'libpng warning: iCCP: known incorrect sRGB profile\nlibpng warning: iCCP: known incorrect sRGB profile\n\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00d\x00d\x00\x00\xff

the workaround was to trim first bytes containing warning information ('quiet' option didn't resolve the issue).

img = imgkit.from_string(content, False, options={"xvfb": "", "quiet": ""})

img = img[102:]