はじめに

ここでは、画像や動画など、静的ファイルをPythonとbottleを用いてHTML上に表示する方法について説明します。ここでは、Fileディレクトリにあるimg01.pngという画像を表示する方法を述べます。

ダブルクォーテーション「”」はHTML側、シングルクォーテーション「’」はpython側の文字列認識です。混同しないように、落ち着いてやってください。慣れないうちはノートなどに書きながらやらないと混乱するかもしれません。なお、シングルクォーテーション3つ「”’」は、複数行の文字列を扱う、python側の記述です。


コード

# -*- coding: utf-8 -*-
from bottle import route, run, get, post, request, static_file, debug
import os

# *** 静的ファイルを扱うための設定 ***
@route('/File/<filename:path>') # <- (A)
def static(filename):
    rootpass = os.getcwd() + "/File" # <- (B)
    return static_file(filename, root=rootpass)

# トップページ
@route('/')
def TopPage():
    # (C)
    t= '''
       <head>
        <script>
           window.onload = function () {
                document.getElementById("img01").src = "File/img01.png"
           };
        </script>
       </head>
    '''

    # (D)
    t= t + '''
        <body>
            <img id = "img01">
        </body>
    '''
    return t

# サーバの起動(一番下に書くこと)
run(reloader=True, port=9999)

重要なことは、pythonに対して画像が置かれているディレクトリがどこに置いてあるかを教えてあげることです。(A)および(B)でその設定をしています。今、test.pyが起動してあるディレクトリを起点として、そこにディレクトリFileがあるとし、その中に画像ファイルimg01.pngがあるとします。ここで、(A)と(B)には、以下のルールでパス指定を行います。

  • (A)で指定するパス: test.pyがあるディレクトリを起点とし、画像ファイルがあるディレクトリを指定します。今回は、test.pyがあるディレクトリにFileというディレクトリがあり、そこに画像があるので、(A)のように記述します。
  • (B)で指定するパス: コンピュータのフルパスとして、画像ファイルがあるディレクトリを指定します。画像があるディレクトリのフルパスを知りたい場合は、ターミナルコマンドで「pwd」と打ち込めば値が返されます。ただし、それでは環境が変わると使えなくなってしまうので、少し工夫します。(B)にあるように、os.getcwd()と書くことで、test.pyが起動しているディレクトリを入手することができます。これに、画像ファイルがあるディレクトリを後ろにつなげることで、画像ファイルがあるディレクトリをフルパスで入手することができます。

これで、pythonが画像ファイルにアクセスできるようになります。次に、htmlを記述する部分に移ります。(C)を見ると、document.getElementById(“img01”).src = “File/img01.png”という記述があります。これは、idにimg01が指定されたhtmlタグのsrc要素を”File/img01.png”に書き換えよ、という意味があります。idにimg01が指定されているタグはどこか探してみると、(D)にあることがわかりまします。すなわち、(C)と(D)を組み合わせると、



となり、画像が表示されるHTMLタグが構成されることがわかります。いきなり、imgタグの中に画像ファイルを指定すればいいのに、なぜ(C)を経由しているのでしょうか。これには結構大事な理由があります。(C)をみるとwindows.onload関数があることがわかります。これは、画像ファイルなどを読み込んだ後に、onload関数の中身を実行する、という意味があります。これにより、画像ファイルがきちんとロードされた後に、画像を表示することができます。もし、(C)を経由せずに、imgタグに画像ファイルのパスを直書きした場合、画像が読み込まれる前に、画像が表示しようとしてしまい、画像が表示されない場合があります。これは、本番環境でWebページをデプロイした場合、特に顕著に発生します。必ず、(C)を経由して画像を表示させる癖をつけておきましょう。

複数の画像を並べる場合:
javascriptはセミコロンで改行を認識するので、セミコロンを忘れないように注意しましょう。画像が1枚の場合は不要です。


キャッシュ対策:
画像ファイルをユーザの入力に従って生成させるようなアプリケーションの場合、キャッシュが悪さをして画像が更新されなくなる場合があります。「aaa.png?xxx」のように、画像ファイルの後ろに無作為な文字列xxxを入れることで、この対策になります。


import time
cashtx = str(time.time()) # 現在時刻の文字列生成
t = t + ''