簡単にテキスト入力から画像生成：PythonとStable Diffusionを使ったAI画像作成ガイド

# 簡単にテキスト入力から画像生成：PythonとStable Diffusionを使ったAI画像作成ガイド

AI技術の進展により画像生成はますます注目を集め、
且つ簡単に利用する事が可能になりました。
本記事では、PythonとStable Diffusionを利用してテキスト入力から画像生成する方法を紹介します。
（ライブラリを利用するためのアカウント作成無し、少ないコード量、コピペ完結）

## 目次
1. はじめに
2. 環境設定手順
   - ディレクトリ作成
   - ディレクトリに移動
   - demo.py作成
   - requirements.txt作成
   - 仮想環境作成
   - 仮想環境を立ち上げ
   - ライブラリのインストール
3. コードの解説
   - 引数の解析
   - 入力の検証
   - プロンプトの翻訳
   - 画像生成の処理
   - 全体の流れ
4. 実行例
5. まとめ

## 1. はじめに
Stable Diffusionは、テキストから画像を生成するための画像生成AIライブラリです。
ユーザーが入力したテキスト（日本語 or 英語）を元に画像を生成します。

## 2. 環境設定手順
プログラムを実行するための環境を設定する手順は以下の通りです。

### (2-1) ディレクトリ作成
まず、作業用のディレクトリを作成します。
```bash
$ mkdir demo-stable-diffusion
```

### (2-2) ディレクトリに移動
作成したディレクトリに移動します。
```bash
$ cd demo-stable-diffusion
```

### (2-3) ファイル作成
プログラム用のPythonファイルを作成します。
```bash
$ touch demo.py
```
demo.pyは下記の内容で作成して下さい（コード説明を後述しています）
```python
import argparse
from diffusers import DiffusionPipeline
from googletrans import Translator


def parse_arguments() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description='Stable Diffusionを使用して画像を生成します')
    parser.add_argument('--height', type=int, default=256, help='生成される画像の高さ（8で割り切れる必要があります')
    parser.add_argument('--width', type=int, default=256, help='生成される画像の幅（8で割り切れる必要があります')
    parser.add_argument('--output_file', type=str, default='demo.png', help='生成された画像の出力ファイル名')
    return parser.parse_args()


def validate_dimensions(height: int, width: int) -> None:
    # height と width が8で割り切れるかチェック
    if height % 8 != 0 or width % 8 != 0:
        raise ValueError(f"height と width は8で割り切れる値にしてください。現在の値は高さ: {height}, 幅: {width}です。")


def translate_prompt(prompt: str) -> str:
    # Google翻訳サービスを利用して日本語から英語に翻訳
    translator = Translator()
    try:
        translated = translator.translate(prompt, src='ja', dest='en')
        return translated.text
    except Exception as e:
        raise RuntimeError(f"翻訳中にエラーが発生しました: {e}")


def generate_image(prompt: str, height: int, width: int, output_file: str) -> None:
    # DiffusionPipeline クラスを使用して事前学習済みモデルを読み込む
    pipe = DiffusionPipeline.from_pretrained("digiplay/LusterMix_v1.5_safetensors")
    # 指定されたプロンプトと画像の高さ・幅を使用して画像を生成
    image = pipe(prompt, height=height, width=width).images[0]
    image.save(output_file)


if __name__ == "__main__":
    args = parse_arguments()
    validate_dimensions(args.height, args.width)

    user_input_prompt = input("Enter text for image generation: ")
    translated_prompt = translate_prompt(user_input_prompt)
    generate_image(translated_prompt, args.height, args.width, args.output_file)

```

### (2-4)requirements.txtの作成
必要なライブラリを記述したrequirements.txtファイルを作成します。
以下の内容を作成して下さい。
```bash
certifi==2024.8.30
charset-normalizer==3.3.2
diffusers==0.30.3
filelock==3.16.1
fsspec==2024.9.0
huggingface-hub==0.25.0
idna>=2.5,<4
importlib_metadata==8.5.0
Jinja2==3.1.4
MarkupSafe==2.1.5
mpmath==1.3.0
networkx==3.3
numpy==1.26.4
packaging==24.1
pillow==10.4.0
PyYAML==6.0.2
regex==2024.9.11
requests==2.32.3
safetensors==0.4.5
sympy==1.13.2
tokenizers==0.19.1
torch==2.2.2
tqdm==4.66.5
transformers==4.44.2
typing_extensions==4.12.2
urllib3==2.2.3
zipp==3.20.2
googletrans==4.0.0-rc1
accelerate==0.34.2
```

### (2-5) 仮想環境作成
仮想環境を作成します。
```bash
$ python3 -m venv venv
```

### (2-6) 仮想環境を立ち上げ
作成した仮想環境をアクティベートします。
```bash
$ source ./venv/bin/activate
```

### (2-7) ライブラリのインストール
requirements.txtに基づいて必要なライブラリをインストールします。
```bash
$ pip install -r requirements.txt
```
これらの手順を順に実行することで、Stable Diffusionを使って画像を生成するプログラムをスムーズにセットアップできます。

## 3. コードの解説

### (3-1) 引数の解析
最初に、コマンドライン引数を解析する`parse_arguments`関数を定義します。
画像の高さ、幅、出力ファイル名を指定できるようにしています。
```python
import argparse

def parse_arguments() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description='Stable Diffusionを使用して画像を生成します')
    parser.add_argument('--height', type=int, default=256, help='生成される画像の高さ（8で割り切れる必要があります')
    parser.add_argument('--width', type=int, default=256, help='生成される画像の幅（8で割り切れる必要があります')
    parser.add_argument('--output_file', type=str, default='demo.png', help='生成された画像の出力ファイル名')
    return parser.parse_args()
```

### (3-2) 入力の検証
画像の高さと幅が8で割り切れるかを確認する`validate_dimensions`関数を定義します。Stable Diffusionでは、画像の高さと幅が8の倍数である必要があります。
```python
def validate_dimensions(height: int, width: int) -> None:
    if height % 8 != 0 or width % 8 != 0:
        raise ValueError(f"height と width は8で割り切れる値にしてください。現在の値は高さ: {height}, 幅: {width}です。")
```

### (3-3) テキストの翻訳
日本語で入力された場合は、Google翻訳サービスで英語に翻訳します。
```python
from googletrans import Translator

def translate_prompt(prompt: str) -> str:
    translator = Translator()
    try:
        translated = translator.translate(prompt, src='ja', dest='en')
        return translated.text
    except Exception as e:
        raise RuntimeError(f"翻訳中にエラーが発生しました: {e}")
```

### (3-4) 画像生成の処理
`generate_image`関数で実際に画像を生成します。`DiffusionPipeline`を使って事前学習済みのStable Diffusionモデルを読み込み、指定されたプロンプトと画像サイズに基づいて画像を生成します。

今回は`digiplay/LusterMix_v1.5_safetensors`というアニメ調モデルを利用していますが
[Hugging Face](https://huggingface.co/models)から様々なモデルを利用する事が可能です。
簡単にカスタマイズできるので色々なスタイルを試してみると面白いかもしれません。

```python
from diffusers import DiffusionPipeline

def generate_image(prompt: str, height: int, width: int, output_file: str) -> None:
    pipe = DiffusionPipeline.from_pretrained("digiplay/LusterMix_v1.5_safetensors")
    image = pipe(prompt, height=height, width=width).images[0]
    image.save(output_file)
```

### (3-5) 全体の流れ
メイン部分では、引数の解析とプロンプトの入力、翻訳、そして画像生成が行われます。
```python
if __name__ == "__main__":
    args = parse_arguments()
    validate_dimensions(args.height, args.width)

    user_input_prompt = input("Enter text for image generation: ")
    translated_prompt = translate_prompt(user_input_prompt)
    generate_image(translated_prompt, args.height, args.width, args.output_file)
```

## 4. 実行例
このプログラムを実行する際は、下記のようなコマンドになります。
引数でサイズや出力ファイル名を指定できます。
サイズが大きくなるに比例して実行時間がかかるため小さいサイズ推奨
```bash
$ python3 demo.py # デフォルトサイズ（256 × 256）でdemo.png作成
$ python3 demo.py --height 80 --width 80 --output_file test.png # 80 × 80でtest.png作成
```

生成したい画像の内容を英語または日本語で入力します（日本語の場合は翻訳されます）
```
Enter text for image generation: Dolphins are watching the beautiful night view
```
下の画像は`Dolphins are watching the beautiful night view（訳：イルカたちが美しい夜景を眺めています）`と入力して生成された画像例です。
![demo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894167/828827d7-1ab5-4e1f-a809-2c1027c47156.png)

## 5. まとめ
本記事では、PythonとStable Diffusionを活用して画像を生成する方法について解説しました。Stable Diffusionはアカウント作成も無く少ないコード量でAI画像生成が可能なため、初心者の方でも簡単に試せるライブラリではないかと思います。

AIによる画像生成の楽しさを体験する一助となれば幸いです。
ありがとうございました。