0

I have a program that generates pictures and either saves them to a file or prints out the raw image data in standard output. I am using Python subprocess module to call the external program, catch its stdout data and create a Python image object from the data. I keep getting "Cannot identify image file" error, though. I am new to this part of Python. Can you please help if you know how to achieve this? Here is my code:

p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
raw = p.stdout.read()
buff = StringIO.StringIO()
buff.write(raw)
buff.seek(0)
im = Image.open(buff)
im.show()
pkout
  • 6,430
  • 2
  • 45
  • 55

1 Answers1

3

The code looks fine to me. Try adding the lines...

assert len(raw) >= 4
assert raw.startswith('\x89PNG')

...directly after the line...

raw = p.stdout.read()

...just to ensure you're getting even vaguely valid data back.

Update

Try this...

from subprocess import check_output
from cStringIO import StringIO
from PIL import Image

raw = check_output(cmd)
buff = StringIO(raw)
im = Image.open(buff)
im.show()

Update #2

Problem is there's a bug in qrcode.exe whereby, when it's writing to stdout, it tries to convert UNIX line endings to DOS line endings.

Looks like the bug may have gotten fixed in a later version. Try: https://code.google.com/p/qrencode-win32/downloads/detail?name=qrcodegui_setup-3.3.1b.exe&can=1&q=qrencode-win32

Aya
  • 39,884
  • 6
  • 55
  • 55
  • Ok. I did that. No error on those assertions. I put a printed out the raw output to the console if it helps spot something. It's this (truncated): ëPNG → IHDR ô ô☺ ó₧▬╕ ☻ IDATHë▌û┴═Σ ♀à↔qαûi ë6╕╤R╥@2i`hë←m ╤@╕σ►┼√╚ƒ╒Ä┤↨|²Qä&▀H æ♠ ½|N▲á\ε\‼^%,Ü┼¥C╠CΣÜh▬▓9frτDê*fïcÄ%░┌ñ♀yP&ƒ↨G≤Wn=♀·═╔<╧?M╗X[◄☼♫┬ßδ.{╪NfH σú╧┼ùÅ – pkout Apr 12 '13 at 16:26
  • How about if you dump the entire raw var to a file, with something like `open('test.png', 'wb').write(raw)`, and then open it with an image viewer? – Aya Apr 12 '13 at 16:30
  • That actually works. I tried that already, so I am sure that the file that is produced by the external file is correct. I am just trying to avoid the step of saving the file to a hard drive first and then loading it to save it. I need to do this 30 times a seconds, so it would be nice to do this all in memory. ;) – pkout Apr 12 '13 at 16:34
  • The only other thing I can think of is that your installation of PIL doesn't include a PNG decoder for some reason, although I'm not sure how to check - does it also fail if you do `im = Image.open('test.png')` on the image you just saved? – Aya Apr 12 '13 at 16:37
  • When I do that, it works fine - no error. Strange. I guess I will resort to saving the image to a file first and then load it again. It can be done 30 times a second. It's just ugly engineering. Thanks for helping, though! – pkout Apr 12 '13 at 16:43
  • That's pretty strange. Lemme check something else. – Aya Apr 12 '13 at 16:45
  • I tried your updated code and gives the same output error as before. Did you try this yourself with something that generates PNGs? I mean, is this working for you? Thanks! – pkout Apr 12 '13 at 17:26
  • Well, I just tested it with `cmd = ['cat', 'test.png']` and it's fine. What exactly is the command you're running, and does it only output a single image, or multiple images? – Aya Apr 12 '13 at 17:35
  • I am using the qrcode.exe executable that you can find in this zip file to generate QR codes: https://code.google.com/p/qrencode-win32/downloads/detail?name=qrcode-win32-3.1.1.zip&can=1&q= There is also a bat file containing a sample of how to call the command. You can pass it to the check_output() function's cmd parameter like this: cmd = ['qrcode.exe', '-o', '-', 'text to encode']. This generates a PNG and sends it to standard output. At least that's the way I understand it from the help. – pkout Apr 12 '13 at 18:01
  • Aaah, it's working now. That was it! Thanks a million times! I wish I could give you more than one point. I will give you some for the intermediate answers for your tenacity! :) – pkout Apr 12 '13 at 18:54