23

この質問はここで同様の方法で尋ねられましたが、答えは私の頭をはるかに超えていました(私はPythonとWeb開発に非常に慣れていません)ので、もっと簡単な方法があるか、別の方法で説明できることを願っています.

最初にサーバーにファイルを書き込まずに、matplotlib を使用して画像を生成し、提供しようとしています。私のコードはおそらくばかげていますが、次のようになります。

import cgi
import matplotlib.pyplot as pyplot
import cStringIO #I think I will need this but not sure how to use

...a bunch of matplotlib stuff happens....
pyplot.savefig('test.png')

print "Content-type: text/html\n"
print """<html><body>
...a bunch of text and html here...
<img src="test.png"></img>
...more text and html...
</body></html>
"""

pyplot.savefig('test.png') を実行する代わりに、cstringIO オブジェクトを作成してから、次のようにする必要があると思います。

mybuffer=cStringIO.StringIO()
pyplot.savefig(mybuffer, format="png")

しかし、私はそこからかなり迷っています。私が見たすべての例 (例: http://lost-theory.org/python/dynamicimg.html ) は、次のようなことを行います。

print "Content-type: image/png\n"

そして、それをすでに出力しているHTMLと統合する方法がわかりません。

4

6 に答える 6

20

あなたがすべき

  • 最初に cStringIO オブジェクトに書き込みます
  • 次に、HTTP ヘッダーを書き込みます
  • 次に、cStringIO の内容を stdout に書き込みます

したがって、エラーがsavefig発生した場合でも、別のヘッダーを返すこともできます。一部のエラーは早期に認識されません。たとえば、テキストの問題、画像のサイズが大きすぎるなどです。

savefig出力をどこに書き込むかを指定する必要があります。できるよ:

format = "png"
sio = cStringIO.StringIO()
pyplot.savefig(sio, format=format)
print "Content-Type: image/%s\n" % format
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) # Needed this on windows, IIS
sys.stdout.write(sio.getvalue())

画像を HTML に埋め込みたい場合:

print "Content-Type: text/html\n"
print """<html><body>
...a bunch of text and html here...
<img src="data:image/png;base64,%s"/>
...more text and html...
</body></html>""" % sio.getvalue().encode("base64").strip()
于 2013-02-12T11:03:13.123 に答える
5

私の最初の質問は次のとおりです。画像は頻繁に変更されますか? 古いものを保持しますか?それがリアルタイムのものであれば、最適化の探求は正当化されます。それ以外の場合、オンザフライで画像を生成する利点はそれほど重要ではありません。

このままのコードでは、2 つのリクエストが必要になります。

  1. すでに持っているhtmlソースを取得し、
  2. 実際の画像を取得するには

おそらく最も簡単な方法 (Web リクエストを最小限に抑える) は @Alex L のコメントです。これにより、画像が埋め込まれた HTML を構築することで、単一のリクエストでそれを行うことができます。

コードは次のようになります。

# Build your matplotlib image in a iostring here
# ......
#

# Initialise the base64 string
#
imgStr = "data:image/png;base64,"

imgStr += base64.b64encode(mybuffer)

print "Content-type: text/html\n"
print """<html><body>
# ...a bunch of text and html here...
    <img src="%s"></img>
#...more text and html...
    </body></html>
""" % imgStr

このコードはそのままでは機能しない可能性がありますが、考え方は示しています。

画像があまり頻繁に変更されない場合、または生成に時間がかかる場合、これは一般的に悪い考えであることに注意してください。これは、毎回生成されるためです

別の方法は、元の html を生成することです。それをロードすると、「test.png」のリクエストがトリガーされます。既に言及したバッファ ストリーミング ソリューションを介して、または静的ファイルから、個別に提供できます。

個人的には、別のプロセスで画像を生成し (常に画像が利用可能であることを確認してください)、非常に軽いものを使用して HTML を生成および提供するという分離ソリューションに固執します。

HTH、

于 2013-02-12T10:53:43.640 に答える
2

私があなたの質問をひどく誤解していない限り、画像の場所に cd して実行するだけです: python -m SimpleHTTPServer 8000 &

次にブラウザを開きhttp://localhost:8000/、URL バーに入力します。

于 2013-02-12T02:46:34.003 に答える