3

我正在为基于 Web 的化学项目使用Indigo 库。长话短说,他们为它编写了一个不错的 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() 方法,我确实得到了一个不错的二进制文件(我没有花任何精力试图解释它),但它显然仍然被破坏了。我觉得这需要在转储到客户端之前进行解码(我以前用 PHP 来做)——这可能很简单,但我从文档中找不到太多帮助(或者我找到了我想要的东西)正在寻找,这超出了我的理解)。我只是不确定发生了什么,并希望得到一些建议。

4

2 回答 2

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])
于 2012-04-17T06:36:53.257 回答
0

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

Win32 二进制写入 最终代码为:

#!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())
于 2012-04-17T21:46:51.613 回答