[無料で] デスクトップ壁紙をAI自動生成する [Windows]

## 概要

定期的に16:9画像を生成してデスクトップ壁紙にするPythonスクリプトを書いてみた。

天気や時間を取得してプロンプトに含めてみた。

![半日ほど動かしてみた結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274492/ae1f0225-8bda-5c45-998a-7a28d124c1a5.png)
半日ほど動かしてみた結果
時間や天気が反映されているのがわかる（この日は曇りときどき雨だった）

## 環境の準備

### Python

stable-diffusion-webuiの要件をみて、必要なバージョンを確認する。
（2023-09-10時点では3.10.6でした。）

https://github.com/AUTOMATIC1111/stable-diffusion-webui#automatic-installation-on-windows

https://www.python.org/downloads/release/python-3106/

:::note info
インストール時に、環境変数PATHを登録するようにでますが、別のバージョンのPythonを使っている人はここでPATHしなくもいいです。
よくわからない人は、PATH登録しておきましょう。
:::

#### この記事で使うモジュール

- pip
- schedule
- requests

### stable-diffusion-webui

#### ダウンロード

こちらからZipをダウンロード or gitでクローンする

https://github.com/AUTOMATIC1111/stable-diffusion-webui/releases

or

```download webui.bat
git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
```

#### インストール

Zipを展開 or Gitをクローンしてできた `stable-diffusion-webui` フォルダの中の、`webui-user.bat`を起動すると、初回起動時に自動で必要なライブラリなどがインストールされます。

:::note warn
さっきPATH環境変数を登録しなかった人は、起動前に`webui-user.bat`の中身の`set PYTHON=`の後に、該当のPython.exeの絶対パスを記入して保存してください。
しなくても動きますが、たまに良く稀にバグります。
:::

#### よくある不具合

`no module named 'tqdm.auto'`と表示された場合は、手動でtqdmをインストールする必要があります。
webuiは、venvを使った仮想環境で動いているので、仮想環境を立ち上げてインストール作業をしていきます。
```tqdm install.bat
cd stable-diffusion-webui/venv/Scripts
call activate.bat
: ここで表記が (venv) に変わる
python -m pip install tqdm
```

### OpenWeatherMapのアカウント作成

https://openweathermap.org/

無料アカウント登録

https://dev.classmethod.jp/articles/openweather_-pyowm/

メール認証後に届くメールにAPI Keyが書いてあるので、見返せるようにしておいてください。

[![価格表](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274492/f8ec8a87-4acc-2bd9-4c68-a3b46665653f.png)](https://openweathermap.org/price)

無料の範囲はこの通り
`Current Weather` で、現在の天気情報が取得できます。
`Geocoding API` で、地名から経緯度を取得して使います。

### ご家庭にある普通のゲーミングPC

よく家の隅に転がっていますよね。
これで実質0円です。

目安: RTX2060 with maxQ の環境で、1280×720画像が1〜3分で1枚生成できます。

## 開発

### stable-diffusion-webuiをAPIモードで立ち上げる

https://zenn.dev/myonie/articles/84952069d8d1ef

stable-diffusion-webui\webui-user.bat を編集用に開き、COMMANDLINE_ARGSを設定します

``` webui-user.bat
: ~~~
set COMMANDLINE_ARGS=--xformers --no-half-vae --no-download-sd-model --skip-version-check --listen --nowebui
: ~~~
```

`--no-half-vae`
エラーが少なくなり、生成速度が少し上がります

`--xformers`
NVIDIA製GPU専用。生成速度が上がります

`--no-download-sd-model`
標準のSD-Model(Checkpoint)をダウンロードしません
civit.ai などからCheckpointを手動でダウンロードしましょう
ダウンロード先は `stable-diffusion-webui\models\stable-diffusion`

`--skip-version-check`
バージョンチェックをスルーします
立ち上げ速度向上

`--listen --nowebui`
これをつけないとAPIが使えないです

### ブラウザからアクセスしてみる

さっき編集した`webui-user.bat`を実行します

この表示が出たらAPIサーバの立ち上げ完了
```
INFO:     Started server process [3896]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:7861 (Press CTRL+C to quit)
```

ブラウザからドキュメントを閲覧できます
[http://localhost:7861/docs](http://localhost:7861/docs)

GETリクエストはブラウザからも閲覧可能
[http://localhost:7861/sdapi/v1/sd-models](http://localhost:7861/sdapi/v1/sd-models)

### pythonからアクセスしてみる

https://max999blog.com/python-requests-get-post-json-data/

requestsモジュールを使ってアクセスしてみます

```python
req = requests.get('http://localhost:7861/sdapi/v1/sd-models', headers={'Content-Type': 'application/json'})
res_json = req.json()
```
headersで、jsonが返ってくることを明示します。

### 画像生成 → 画像取得

https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/API

text2imageで画像生成するときのエンドポイントはこちら
[http://localhost:7861/sdapi/v1/txt2img](http://localhost:7861/sdapi/v1/txt2img)
※POSTリクエストなので、ブラウザからはアクセスできません

画像をを生成する最小構成はこんな感じ
```python
data = { ..ここにデータを書いていく.. }
req = request.Request('http://localhost:7861/sdapi/v1/txt2img', json.dumps(data).encode(), {'Content-Type': 'application/json'})
res = request.urlopen(req)
body = json.loads(res.read())
```

前後しますが、dataの最小構成はこんな感じ
```python
data = {
    "prompt": "プロンプト",
    "negative_prompt": "ネガティブ プロンプト",
    "sampler_name": "Eular a", # サンプラー
    "batch_size": 1, # 生成する数
    "steps": 20, # 生成に要するステップ数
    "cfg_scale": 7, # プロンプトの適用度合い
    "width": 512, # 生成する画像のサイズ
    "height": 512,
    "eta": 0,
    "refiner_checkpoint": "SD-Model",
    "send_images": True, # レスポンスに含めるかどうか
    "save_images": True, # 保存するかどうか
}
```
save_images: Trueの場合の保存先は、`stable-diffusion-webui\outputs\txt2img-images\{今日の日付}\`


### Windowsの壁紙を更新する

https://qiita.com/lobmto/items/6d3649e6c00b98553ca2

### scheduleモジュールで定期的に動かす

https://di-acc2.com/programming/python/4574/

ここまでで、一旦、定期的に画像生成して壁紙が更新されるプログラムは完成です。

### 時間を取得してプロンプトに追加する

### 天気を取得してプロンプトに追加する(OpenWeatherMap)

## Additional

### Loraを使う

### SD-Modelをランダムにする

### モデルによってサンプラーとステップ数を変える

### プロンプトをランダムにする

### 時間を数字から言葉に変換する

### 気温/風速も数字から言葉に変換する

## Future

### アップスケーラーを使う

### 複数枚生成して自動で評価する

### 複数PCで共有する

### コンスタンスなコンテンツとして配信して収益化する（笑）

## まとめ

#### 何を生成するか分からないAI生成画像をPCの壁紙になんてしないほうがいい

プロンプトは90%くらいしか信用できない。