Unable to convert imgkit image to PIL image

1k Views Asked by At

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

3

There are 3 best solutions below

0
On BEST ANSWER

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")
2
On

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).

0
On

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:]