2013-02-12 3 views
18

この質問は同じようにして質問されましたhereしかし答えは私の頭の上にありました(私はpythonとウェブ開発に新しいスーパーです)。より単純な方法でも、異なった方法で説明することもできます。Pythonを使用してmatplotlibイメージを動的にウェブに配信する

私は、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でそれを統合する方法を得ることはありません。

+0

すると、その後でimageout.py' 'から、あなたが出力ブロブを、 HTMLは画像ソースをpyスクリプトに設定できますか? PHPでは、あなたはそれらの行に沿って何かをするでしょう。 – ninMonkey

+1

をチェックアウトhttp://stackoverflow.com/questions/1207190/embedding-base64-images –

答えて

18

あなたがcStringIOオブジェクトへ

  • 最初の書き込み
  • 次いでstdoutにcStringIOの内容を書き込むHTTPヘッダ次いで
  • を書き込むべき

したがって、savefigのエラーが発生した場合でも、何か他のものを返すことができます。別のヘッダー。テキストのいくつかの問題、大きすぎる画像の寸法など、いくつかのエラーは早期に認識されません。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() 
+0

完璧に動作します、ありがとう! –

+0

あなたは大歓迎です... –

2

私はひどく、あなたの質問にmiscomprehendすべてを行う必要があるイメージの場所にCDで、実行しない限ります:python -m SimpleHTTPServer 8000 &

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

+1

私が探しているものではありませんが、あなたはわかりやすくするために言い直してくれました。 –

5

私の最初の質問です:イメージが頻繁に変更されますか?あなたは古いものを保持したいですか?それがリアルタイムのものなら、最適化のためのあなたの探求は正当化されます。そうしないと、オンザフライで画像を生成することによるメリットはそれほど重要ではありません。

それは2つの要求が必要になり立っているように、コード:おそらく最も簡単な方法(維持実際の画像

を取得するには、HTMLのあなたが既に持っているソースと

  • を取得するために

    1. を最小限のWebリクエスト)は@Alex Lのコメントです。イメージを埋め込んだHTMLを構築することで、1回のリクエストでそれを行うことができます。

      あなたのコードは次のようなものになるだろう:

      # 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 
      

      このコードはおそらく、箱から出して動作しますが、考え方を示していません。

      は毎回になるため、イメージが実際にあまり頻繁に変更されない、または生成に時間がかかる場合は、一般的に好ましくありません。

      もう1つの方法は、オリジナルのhtmlを生成することです。読み込むと、 "test.png"のリクエストがトリガーされます。すでに言及しているバッファーストリーミングソリューション、または静的ファイルを使用して、個別にサービスすることができます。

      個人的には、別のプロセスでイメージを生成し(常にイメージが利用可能であることを確認してください)、非常に軽いものを使用してHTMLを生成して配信します。

      HTH、

  • 6

    を上記の答えは少し古くなっている - ここでの生のバイトを取得するのpython3 +に私のためにどのような作品です図形データ他の回答で述べたように

    import matplotlib.pyplot as plt 
    from io import BytesIO 
    fig = plt.figure() 
    plt.plot(range(10)) 
    figdata = BytesIO() 
    fig.savefig(figdata, format='png') 
    

    あなたは今、「画像/ PNG」から「のContent-Type」ヘッダを設定し、バイトを記述する必要があります。

    ウェブサーバーとして使用している内容によってはコードが異なる場合があります。私は私のウェブサーバとしてトルネードを使用し、それを行うためのコードは次のとおりです。

    self.set_header('Content-Type', 'image/png') 
    self.write(figdata.getvalue()) 
    
    +0

    バッファの正しい内容の長さを取得できません。私がajax経由でイメージをダウンロードするとき、私は 'sys.getsizeof(figdata)'と 'figdata .__ sizeof __()'を試して、常にERR_CONTENT_LENGTH_MISMATCHエラーを受け取ります。私はコンテンツの長さを一切指定しなかった。 – TomTom101

    +1

    @ TomTom101 - あなたのHTTPサーバーにはどのようなライブラリを使用していますか?おそらく 'len(figdata.getvalue())'(実際のデータストリームではなく、BytesIOオブジェクトのサイズを取得していました) –

    +0

    nginx、Gunicorn、Falconを使用しています。私はあなたの提案を試してみます – TomTom101

    1

    何のpython3で私の作品は次のとおりです。

    buf = io.BytesIO() 
    plt.savefig(buf, format='png') 
    image_base64 = base64.b64encode(buf.getvalue()).decode('utf-8').replace('\n', '') 
    buf.close() 
    
    関連する問題