PNG图像的Python缓冲区

时间:2012-04-17 06:20:22

标签: python binary png decode

我正在使用Indigo library进行基于网络的化学项目。简而言之,他们为它编写了一个很棒的Python界面,我正在通过CGI使用它。有几种输出格式,包括SVG和PNG。我不是Python专家,所以我对作者对缓冲区的想法感到有点困惑。以下作品:

#!python
from indigo import *
from indigo_renderer import *
from struct import *
print "Content-type: image/svg+xml"
print

indigo = Indigo()
renderer = IndigoRenderer(indigo);

mol1 = indigo.loadMolecule("ONc1cccc1");

indigo.setOption("render-output-format", "svg");
indigo.setOption("render-highlight-color-enabled", "true");

image = renderer.renderToBuffer(mol1);
output = image.tostring()
print output

也就是说,上面的代码吐出了格式正确的SVG XML,没有不需要的前导或尾随字符。 Firefox识别出内容类型并将其渲染得很好。

但是,我很难理解我应该为PNG做些什么:

我将代码更改为:

from indigo import *
from indigo_renderer import *
from struct import *

print "Content-type: image/png"
print

indigo = Indigo()
renderer = IndigoRenderer(indigo);

mol1 = indigo.loadMolecule("ONc1cccc1");

indigo.setOption("render-output-format", "png");
indigo.setOption("render-highlight-color-enabled", "true");

image = renderer.renderToBuffer(mol1);
output = image
print output

我得到了这个(这不是我期望的PNG):

array('c', '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00[ truncated by me ]')

如果我尝试使用toString()方法,我会得到一个很好的二进制blob(我没有花费任何努力试图解释它),但它仍然显然已经被打破了。我有一种感觉,这需要在被转储到客户端之前被解码(我曾经用PHP做过) - 这可能相当简单,但我找不到文档的帮助(或者我找到了什么我正在寻找,这超出了我的理解力。我只是不确定发生了什么,并希望得到一些建议。

2 个答案:

答案 0 :(得分:1)

根据您的输出,它是一个PNG文件。只需将其保存到wb模式的文件中即可。

由于您是PHP开发人员,我只会使用您在python中的所有内容:

选项一:

保存到文件并使用PHP

进行提取
...
output = image
f=open ("someFileName.png", wb)
f.write(output[1])
f.close()

然后将"someFileName.png"与PHP包装器一起使用。

选项二: 从PHP包装器调用python脚本。将图像数据作为退出代码传递给包装器。

...
output = image
import sys
sys.exit(output[1])

答案 1 :(得分:0)

(抱歉将此放在评论中以及此处)。解决问题 - Windows肯定会让这很痛苦,但现在必须这样做。不幸的是,当我开始为我的Linux VPS完成它时,代码将不得不改变,但这就是我所做的。输出是一个字符数组,tostring()按预期工作,只是转储原始内容。我需要做的就是强制输出写为二进制以防止损坏。以二进制文件写入文件是微不足道的,但写入stdout作为二进制文件是特定于平台的。请参阅:链接感谢您的帮助。我在这里找到了指导:

Win32 Binary Write 最终的代码是:

#!python
from indigo import *
from indigo_renderer import *
from array import *
import sys, cgitb, cgi

cgitb.enable()
httpArgs = cgi.FieldStorage()
print "Content-type: image/png"
print

indigo = Indigo()
renderer = IndigoRenderer(indigo)

mol1 = indigo.loadMolecule("ONc1cccc1")

indigo.setOption("render-output-format", "png")
indigo.setOption("render-highlight-color-enabled", "true")

outputStream = renderer.renderToBuffer(mol1)
if sys.platform == "win32":
   import os, msvcrt
   msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
else:
sys.exit()
sys.stdout.write(outputStream.tostring())