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

Exporting image to a variable can include internal warnings from miscellanous components, producing an invalid output. #29

Open
fake-name opened this issue Nov 11, 2018 · 3 comments

Comments

@fake-name
Copy link

fake-name commented Nov 11, 2018

Basically, I'm using the code as following:

	options = {
		"xvfb"   : "",
		'format' : 'png',
	}

	img = imgkit.from_string(rendered_html, False, options=options)
	print("Image generated")

	with open("test.png", "wb") as fp:
		fp.write(img)

	buf = io.BytesIO(img)
	im = Image.open(buf)
	im.save("figure.png")

	buf.close()

PIL fails to open the bytes array with OSError: cannot identify image file <_io.BytesIO object at 0x7fde9c07d888>. Saving the image, Irfanview can open the file, but other viewers report it as invalid.

Opening the image in a hex editor yields:

00000000:  6c69 6270 6e67 2077 6172 6e69 6e67 3a20 6943 4350 3a20 6b6e  :libpng warning: iCCP: kn
00000018:  6f77 6e20 696e 636f 7272 6563 7420 7352 4742 2070 726f 6669  :own incorrect sRGB profi
00000030:  6c65 0a6c 6962 706e 6720 7761 726e 696e 673a 2069 4343 503a  :le.libpng warning: iCCP:
00000048:  206b 6e6f 776e 2069 6e63 6f72 7265 6374 2073 5247 4220 7072  : known incorrect sRGB pr
00000060:  6f66 696c 650a 4c6f 6164 696e 6720 7061 6765 2028 312f 3229  :ofile.Loading page (1/2)
00000078:  0a5b 3e20 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020  :.[>                     
00000090:  2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020  :                        
000000a8:  2020 2020 2020 2020 2020 2020 2020 5d20 3025 0d5b 3d3d 3d3d  :              ] 0%.[====
000000c0:  3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  :========================
000000d8:  3d3d 3e20 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020  :==>                     
000000f0:  2020 2020 2020 2020 5d20 3530 250d 5b3d 3d3d 3d3d 3d3d 3d3d  :        ] 50%.[=========
00000108:  3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  :========================
00000120:  3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  :========================
00000138:  3d3d 3d5d 2031 3030 250d 5265 6e64 6572 696e 6720 2832 2f32  :===] 100%.Rendering (2/2
00000150:  2920 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020  :)                       
00000168:  2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020  :                        
00000180:  2020 2020 200a 5b3e 2020 2020 2020 2020 2020 2020 2020 2020  :     .[>                
00000198:  2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020  :                        
000001b0:  2020 2020 2020 2020 2020 2020 2020 2020 2020 205d 2030 250d  :                   ] 0%.
000001c8:  5b3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3e20 2020 2020 2020  :[===============>       
000001e0:  2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020  :                        
000001f8:  2020 2020 2020 2020 2020 2020 205d 2032 3525 0d89 504e 470d  :             ] 25%..PNG.
00000210:  0a1a 0a00 0000 0d49 4844 5200 0004 0000 0000 c508 0600 0000  :.......IHDR.............
00000228:  ca77 8097 0000 0009 7048 5973 0000 0f61 0000 0f61 01a8 3fa7  :.w......pHYs...a...a..?.
00000240:  6900 0020 0049 4441 5478 0100 0880 f77f 01ff ffff ff00 0000  :i.. .IDATx..............
00000258:  0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000  :........................
00000270:  0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000  :........................
00000288:  0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000  :........................
000002a0:  0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000  :........................

So there's some output stuff at the beginning of the file (line breaks added manually):

libpng warning: iCCP: known incorrect sRGB profile.
libpng warning: iCCP: known incorrect sRGB profile.
Loading page (1/2).
[>                                                           ] 0%.
[==============================>                             ] 50%.
[============================================================]100%.
Rendering (2/2).
[>                                                           ] 0%.
[===============>                                            ] 25%.
.PNG

It looks like the stdout of something internal (wkhtmltopdf?) is getting captured into the "image" output, somehow.

@fake-name
Copy link
Author

A really, really horrible workaround hack (that only works for .png files) is the following:

	# PNG File header
	header = bytes((137, 80, 78, 71, 13, 10, 26, 10))
	img = img[img.index(header):]

Basically, it truncates everything before the png start-of-file header.

@sorter
Copy link

sorter commented Jun 2, 2020

A fix for this would be nice.

@eparikh
Copy link

eparikh commented Jul 17, 2023

I don't have the same exact issue, but similar. I don't even get anything saved to the variable. The raised error prevents that When I use imgkit.from_url with path=False, I get some OSError. This doesn't happen when I provide a path.

I drilled down and inspected the module code to find that IMGKit.to_img is raising an error from stderr text from wkhtmltoimage. Below are the updates I made to IMGKit.to_img that I'm using by mocking the original function. I know it's hacky and doesn't solve the root cause, but it works for my purposes. Maybe I'll look further into it once I finish this project I'm working on. This is what the relevant part of my patch of to_img looks like...and now I have it working 100%.

  • Note: I also had to reimport subprocess and sys at the beginning of the updated function.
        # 1. commented this out
        # if "Error" in stderr:
        #    raise OSError("wkhtmltoimage reported an error:\n" + stderr)

        if exit_code != 0:
            xvfb_error = ""
            if "QXcbConnection" in stderr:
                xvfb_error = 'You need to install xvfb(sudo apt-get install xvfb, ' \
                             'yum install xorg-x11-server-Xvfb, etc), ' \
                             'then add option: {"xvfb": ""}.'
                raise OSError(  # 2. tabbed this raise over since we'd reach here as well...
                    "wkhtmltoimage exited with non-zero code {0}. error:\n{1}\n\n{2}".format(
                        exit_code, stderr, xvfb_error
                    )
                )

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

No branches or pull requests

3 participants