PythonとHTMLで作る簡単な画像アップロード画面

# はじめに
こんにちは！今回は、PythonとHTMLを使って、画像をアップロードできる簡単な掲示板を作成する方法をご紹介します。Flaskを使用して、サーバーサイドの処理を行い、HTMLテンプレートを使ってフロントエンドを作成します。

# 必要なライブラリのインストール
まずは、Flaskをインストールします。

```sh
pip install flask
```

ディレクトリ構造の準備
以下のディレクトリ構造を準備します。

```lua
/your_project_directory
|-- app.py
|-- templates
|   |-- upload.html
|-- uploads
```
※uploadsディレクトリは、アップロードされた画像を保存する場所です。手動で作成してください。

# Flaskアプリケーションのセットアップ
次に、Flaskアプリケーションをセットアップします。以下がapp.pyのコードです。

```python
from flask import Flask, request, redirect, url_for, render_template, send_from_directory
import os
from werkzeug.utils import secure_filename

app = Flask(__name__)

# アップロード先のディレクトリ
UPLOAD_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'uploads')
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# 許可するファイルの拡張子
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        # ファイルがリクエストに存在するか確認
        if 'file' not in request.files:
            return redirect(request.url)
        file = request.files['file']
        # ファイル名が空かチェック
        if file.filename == '':
            return redirect(request.url)
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return redirect(url_for('uploaded_file', filename=filename))
    return render_template('upload.html')

@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

if __name__ == '__main__':
    # アップロード先のディレクトリが存在するか確認し、存在しない場合は作成する
    if not os.path.exists(app.config['UPLOAD_FOLDER']):
        os.makedirs(app.config['UPLOAD_FOLDER'])
    app.run(debug=True)
```

### コードの説明
##### 1.ライブラリのインポート:
```python
from flask import Flask, request, redirect, url_for, render_template, send_from_directory
import os
from werkzeug.utils import secure_filename
```
Flask、OSモジュール、およびWerkzeugのsecure_filename関数をインポートします。

##### 2.Flaskアプリケーションの作成:

```python
app = Flask(__name__)
```
Flaskアプリケーションのインスタンスを作成します。

###### 3.アップロード先のディレクトリ設定:
```python
UPLOAD_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'uploads')
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
```
アップロード先のディレクトリを絶対パスで指定し、Flaskの設定に追加します。

##### 4.許可するファイルの拡張子を設定:
```python
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
```
許可するファイルの拡張子をセットします。

##### 5.ファイルの拡張子チェック関数:
```python
def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
```
ファイル名に許可された拡張子が含まれているかを確認します。

###### 6.ルートエンドポイントの作成:
```python
@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            return redirect(request.url)
        file = request.files['file']
        if file.filename == '':
            return redirect(request.url)
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return redirect(url_for('uploaded_file', filename=filename))
    return render_template('upload.html')
```
ファイルのアップロードフォームを表示し、アップロードされたファイルを保存します。

###### 7.アップロードされたファイルを表示するエンドポイント:
```python
@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
```
保存されたファイルを表示するためのエンドポイントを作成します。

###### 8.アプリケーションの実行:
```python
if __name__ == '__main__':
    if not os.path.exists(app.config['UPLOAD_FOLDER']):
        os.makedirs(app.config['UPLOAD_FOLDER'])
    app.run(debug=True)
```

アプリケーションをデバッグモードで実行し、アップロード先のディレクトリが存在しない場合は作成します。

# HTMLテンプレートの作成
次に、HTMLテンプレートを作成します。templatesフォルダ内にupload.htmlという名前で以下の内容を保存します。

```html:upload.html
<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>画像アップロード掲示板</title>
</head>
<body>
    <h1>画像をアップロードする</h1>
    <form method="post" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" value="アップロード">
    </form>
</body>
</html>
```

# アプリケーションの実行
以下のコマンドを実行して、アプリケーションを起動します。
```sh
python app.py
```

ブラウザで
http://localhost:5000/
にアクセスし、画像をアップロードすることで、アップロードされた画像が表示されることを確認できます。

![スクリーンショット 2024-07-25 17.47.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75802/3e77c1d4-f12e-fbdc-ff87-7cf0415f8a6b.png)


# おわりに
今回の記事では、PythonとHTMLを使用して簡単な画像アップロード掲示板を作成する方法を紹介しました。Flaskの基本的な使い方や、ファイルアップロードの処理について学ぶことができました。この基本的なサンプルから機能を拡張して、さらに高度な画像掲示板を作成することが可能です。ぜひ挑戦してみてください！