Flux1.1 Pro のAPIを叩いて画像を生成する

**「すぐに見つかる・その場で作れる」AI生成フリー素材サイト [pixalia（ピクサリア）](https://pixalia.me)** を個人開発しているtoggyです。

pixaliaでは画像の生成にStable DffusionとFlux1.1 のAPIを利用しています。この記事ではphp/LaravelからFlux1.1 ProのAPIを叩いて画像を生成する実装を紹介します。

# Flux1.1 Proとは
![](https://storage.googleapis.com/zenn-user-upload/3d84a1d3205f-20250124.webp)

Flux1.1 Proとは「[Black Forest Labs](https://blackforestlabs.ai/)」が提供する画像生成系のAIモデルです。画像生成のAIエンジンはStable Diffusionが有名ですが、元々Stable Diffusionを開発していたチームが独立して独自に開発した画像生成エンジンになります。
**FluxはStable Diffusionよりも精度が良いとされ、実際に使ってみた体感としても生成AIが苦手とする5本指の描画やスポーツをしている人の描画はStable Diffusionよりも安定して生成されると感じます。**
今回はそんなFluxの中でもFlux1.1 ProのAPIを叩いてみます。

# プラットフォームを決める
Flux1.1 ProのAPIは最近までその開発元のBlack Forest Labsが直接提供していませんでした（※最近になり直接APIを提供するようになりました 2025年1月25日現在）。
そのため、Flux1.1 ProをAPIで利用できるプラットフォームは複数あり以下のうちどれを利用するかを決める必要があります。

- [Black Forest Labs](https://docs.bfl.ml/)（公式）
- [Fal.ai](https://fal.ai/models/fal-ai/flux-pro/v1.1/api#type-Image)
- [Replicate](https://replicate.com/black-forest-labs/flux-1.1-pro/api)

Black Forest LabsはFlux1.1 Proを提供する公式なのですが **「まだβ版のため変更する可能性があるよ」との注意書きもある** ため、今回はFal.aiを利用することにします。

ということで、Fal.aiにアカウントを作りましょう。Fal.aiにはFluxを中心とする様々なAPIが提供されていますが、その中からFlux1.1 ProのAPIを叩いて画像を生成したいと思います。

# APIの仕様と実装
Fal.aiのflux-pro v1.1のAPI仕様を確認していきましょう。 https://fal.ai/models/fal-ai/flux-pro/v1.1

こちらのAPI仕様をみるとnode.js/Pythonなどの言語別に実装方法が分かれていますが、php/Laravelは用意されていませんのでHTTP(cURL)の仕様に従って実装していきます。

## 生成フロー
APIの実装は以下のフローに従います
**1. 画像生成を実行する**
**2. 画像生成ステータスを確認で完了を確認する**
**3. 生成された画像を取得する**

なお、すべてのリクエストのヘッダにはfal.aiで発行されるアクセスキーが必要になりますので、あらかじめ用意しておきます。

## 1.画像生成実行のリクエストで実行を開始する（キューに入れる）
`https://queue.fal.run/fal-ai/flux-pro/v1.1` に対して以下のパラメータ（json)をPOSTすることで画像の生成を開始することができます。
|キー名|説明|値の例|
|:-|:-|:-|
|prompt(必須)|生成プロンプト（いわゆる呪文）をセットします|`Extreme close-up of a girl with smile `|
|image_size|画像サイズを`square_hd`, `square` , `portrait_4_3` , `portrait_16_9` , `landscape_4_3` , `landscape_16_9` のいずれかで指定または `{width:1280, height:720}` のカスタム指定。| `square`<br>デフォルト値は `landscape_4_3` |
|seed|シード値、同じプロンプトで全く同じ画像を生成する際は固定値にする|123などの数値。<br>デフォルト値は指定なし（=ランダムな数値とみなす）|
|sync_mode|画像生成完了を待ってレスポンスを得る場合は `true` [^1]|true/false<br>デフォルト値はfalse|
|num_images|一度の生成で生成する画像数|4など<br>デフォルト値は1|
|enable_safety_checker|公序良俗に反するいわゆるNSFW画像をチェックするかを指定します [^2]|trueまたはfalse<br>デフォルト値はtrue|
|safety_tolerance|生成画像の安全許容レベルを1-6で指定します。1が最も厳しく6が最も緩いです [^2]|1-6の数値。<br>デフォルト値は2|
|output_format|画像のファイル形式を指定|`jpeg` または `png` <br>デフォルト値は `jpeg`|

なお、他の生成AI画像エンジンにはありがちな *ネガティブプロンプトはflux1.1 proにはありません*（指定せずとも十分な精度の画像が生成されます）。

php/Laravelでの実装例は以下になります。
```php
use GuzzleHttp\Client;

//config('app.fal_ai_api_key')はAPIキーをセットする
$client = new Client([
            'headers' => [
                'Authorization' => 'Key ' . config('app.fal_ai_api_key'),
                'Content-Type' => 'application/json'
            ],
        ]);
$response = $this->client->post(
    'https://queue.fal.run/fal-ai/flux-pro/v1.1',
    [
        'json' => [
            'prompt' => 'Extreme close-up of a girl with smile ',
            'image_size' => 'landscape_16_9',
            'num_images' => 1,
            'enable_safety_checker' => false,
            'safety_tolerance' => '6',
        ]
    ]
);
```

この実装で画像の生成が開始されます。

## 2.画像生成ステータスをチェックする
1.で実行したAPIは画像生成を開始する・画像生成をタスクのキューにいれるAPIのため、**生成が完了したことを確認後に生成された画像を取得する必要があります。**
そこで次に画像生成のステータスを確認するためのAPIを叩きます。ステータスをfetchするAPIのURLは https://queue.fal.run/fal-ai/flux-pro/v1.1/requests/{request_id}/status ですが、このURLは先ほどの画像生成APIのレスポンスに `status_url` のキーでrequest_idが入った形で返ってくるのでそれを利用します。

```php
//生成実行APIでのレスポンスをjson化して、ステータス確認APIのURLを取得
$responseContent = $response->getBody()->getContents();
$json = json_decode($responseContent);
//そのままステータスをfetchする
$response = $client->get($json->status_url);
$responseContent = $response->getBody()->getContents();
$json = json_decode($responseContent);

echo($json->status)
//'IN_QUEUE' or 'IN_PROGRESS' or 'COMPLETE'

//(生成が完了した画像のURL)
echo($json->response_url)
//https://queue.fal.run/fal-ai/flux-pro/v1.1/requests/{request_id}
```
ステータスは**生成待ち（'IN_QUEUE'）／生成中（'IN_PROGRESS'）／生成完了（'COMPLETE'）があり、`COMPLETE` が返ってくるようであれば生成完了が確認できます**。画像1枚であれば1分かからず完了しますので、数秒毎にポーリングするなど工夫しましょう。

## 3.生成された画像を取得する
2.でステータスが完了になった状態であれば、ステータス確認APIのレスポンスにあるurl `response_url` で生成が完了した画像の情報が取得できます。 `response_url` で取得できるのは生成した画像の情報であって画像データそのものでは無いことに注意しましょう。画像情報とは具体的に以下が格納されています。
```json
{
  "images": [
    {
      "url": "url_to_base64_img",
      "content_type": "image/jpeg"
    }
  ],
  "prompt": ""
}
```
imagesは1.で指定した生成枚数分の配列となります。今回は1枚の指定だったため以下のような実装としました。
```php
//2.の実装で返ってきたステータス確認APIのレスポンスをjson_decodeした変数$responseJsonから
//生成画像情報を取得する
$response = $this->client->get($responseJson->response_url);
$responseContent = $response->getBody()->getContents();
$json = json_decode($responseContent);
//1枚のみの生成のためimage[0]からbase64の画像データを取得する
$image = file_get_contents($json->images[0]->url);
```

base64の文字列として取得した `$image` を画像として表示するなり保存するなりすればOKですね。

これでflux1.1proをAPI経由で叩いて生成AIで画像を作成できました。

# 終わりに（宣伝）
現在もっとも精度が高いと言われている画像生成エンジンのうちのひとつのflux1.1 proをAPI経由で利用しました。画像生成AIといえどもAPIが提供されているので実装の難易度としては他のAPIとほとんど変わりませんね。

私はこのflux1.1 proを利用した個人開発ですべてが生成AIフリー素材のストックフォトサイト [pixalia](https://pixalia.me) を運営しています。さらに無料のユーザー登録で画像生成も無料でできるのでぜひ利用してみてくださいね。




[^1]: sync_modeをtrueにしても期待した動作にならない場合があったため、記事中では常にfalseを指定した動きとして扱っています
[^2]: enable_safety_checker, safety_toleranceの規制を最大に緩めてもNSFW画像は生成不可能のようです