画像生成
自然言語プロンプトから画像を生成し、既存画像から背景を削除します。
AI Image Generation を使用する理由
アプリケーションにはカスタム画像が必要です。たとえば、ユーザーのプロンプトに合ったヒーローイラスト、説明に基づくアバター、eコマース商品リスト用の製品モックアップ、プロフィール写真用のきれいな切り抜きなどです。ストックライブラリの利用では一般的すぎるうえ、各モデルプロバイダーと直接統合する場合は、API key、リクエスト形式、ポーリングロジック、ストレージを個別に扱う必要があります。
Squid AI Image は、複数の画像モデルに対応する単一の backend API と、組み込みの背景削除エンドポイントを提供します。
- TypeScript
- Python
const url = await this.squid.ai().image().generate('a pirate ship at sunset, oil painting style', {
modelName: 'gpt-image-1',
size: '1024x1024',
quality: 'high',
});
url = await self.squid.ai().image().generate(
'a pirate ship at sunset, oil painting style',
{'modelName': 'gpt-image-1', 'size': '1024x1024', 'quality': 'high'},
)
概要
Squid AI Image は、3 つの画像モデルファミリーを単一の client でラップします。
- 一般用途のフォトリアルな画像とスタイライズされた画像向けの OpenAI GPT Image (
gpt-image-*) - スタイルプリセット、アスペクト比制御、背景削除向けの Stability AI Stable Diffusion Core
- 明示的な幅・高さ制御による高品質な生成向けの Black Forest Labs Flux Pro / Flux Kontext Pro
Squid backend はリクエストを認証し、アプリケーション設定から適切なプロバイダーの API key を検索して、upstream モデルを呼び出し、生成された画像への URL を返します。
AI Image を使用する場合
| ユースケース | 推奨事項 |
|---|---|
| テキストプロンプトから一度限りの画像を生成する | スタイルのニーズに合うモデルで generate() を使用 |
| アップロードした写真から背景を削除する | removeBackground() |
| AI agent 内で生成した画像を表示する | generate() を呼び出して URL を返す AI function をアタッチする |
| 生成したアセットを長期保存する | 返された画像を Squid storage にアップロードする |
仕組み
- backend service から
this.squid.ai().image().generate(prompt, options)を呼び出します - Squid がモデルとオプションを検証し、対応するプロバイダー(OpenAI、Stability、または Black Forest Labs)に呼び出しをルーティングします
- プロバイダーが画像を生成し、URL を返します
- Squid backend がその URL をコードに返します
- URL は一時的なものです。画像を保持する必要がある場合は、ダウンロードして Squid storage または独自の bucket に再アップロードしてください。
クイックスタート
前提条件
squid initで初期化された Squid backend project@squidcloud/backendpackage(TypeScript)またはsquidcloud-backendpackage(Python)- 呼び出すモデルに応じて、Squid Console で有効化された該当 AI provider(OpenAI、Stability AI、または Black Forest Labs)
ステップ 1: 呼び出しを executable でラップする
画像生成には admin access が必要なため、backend で実行する必要があります。API key を公開せずに client からトリガーできるよう、executable でラップします。
- TypeScript
- Python
import { executable, SquidService } from '@squidcloud/backend';
import { AiGenerateImageOptions } from '@squidcloud/client';
export class ImageService extends SquidService {
@executable()
async generateImage(prompt: string): Promise<string> {
this.assertIsAuthenticated();
const options: AiGenerateImageOptions = {
modelName: 'gpt-image-1',
quality: 'medium',
size: '1024x1024',
};
return this.squid.ai().image().generate(prompt, options);
}
}
from squidcloud_backend import SquidService, executable
class ImageService(SquidService):
@executable()
async def generate_image(self, prompt: str) -> str:
self.assert_is_authenticated()
options = {
'modelName': 'gpt-image-1',
'quality': 'medium',
'size': '1024x1024',
}
return await self.squid.ai().image().generate(prompt, options)
ステップ 2: backend を実行またはデプロイする
squid start
cloud にデプロイするには、backend のデプロイを参照してください。
ステップ 3: client から呼び出す
const imageUrl = await squid.executeFunction('generateImage', 'a friendly squid mascot, vector art');
document.querySelector<HTMLImageElement>('#preview')!.src = imageUrl;
認証と設定
画像メソッドには、admin access を持つ認証済み Squid client が必要です。generate() と removeBackground() はいずれも、backend または admin context 以外からの呼び出しを拒否します。
推奨されるパターンは次の 2 つです。
- 呼び出しを executable でラップする。Quick Start で示したとおりです。これは client からトリガーされる画像生成の標準パターンです。executablesを参照してください。
- trigger、scheduler、または webhook などの権限を持つ backend service から呼び出す。
プロバイダーの API key(OpenAI、Stability、Flux)は Squid Console のアプリケーション設定に保存されます。Squid は、渡した modelName に基づき、リクエスト時に適切な key を検索します。
コアコンセプト
対応モデル
AiGenerateImageOptions は modelName による discriminated union です。このフィールドによって、有効なオプションセットと呼び出されるプロバイダーが決まります。
| モデル | プロバイダー | オプション型 |
|---|---|---|
gpt-image-1, gpt-image-1-mini, gpt-image-1.5, gpt-image-2, chatgpt-image-latest | OpenAI | GptImageOptions |
stable-diffusion-core | Stability AI | StableDiffusionCoreOptions |
flux-pro-1.1 | Black Forest Labs | FluxOptions |
flux-kontext-pro | Black Forest Labs | FluxOptions |
GPT Image オプション
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
modelName | 上記の gpt-image-* モデル名のいずれか | はい | OpenAI 画像モデルを選択します |
quality | 'auto' | 'high' | 'medium' | 'low' | いいえ | 画像品質。デフォルトは 'auto' です。 |
size | '1024x1024' | '1024x1536' | '1536x1024' | 'auto' | いいえ | 出力サイズ。デフォルトは '1024x1024' です。 |
numberOfImagesToGenerate | number | いいえ | 生成する画像の数。デフォルトは 1 です。 |
Stable Diffusion Core オプション
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
modelName | 'stable-diffusion-core' | はい | Stable Diffusion Core モデルを選択します |
aspectRatio | string | いいえ | '16:9'、'1:1'、'21:9'、'2:3'、'3:2'、'4:5'、'5:4'、'9:16'、'9:21' のいずれか。デフォルトは '1:1' です。 |
negativePrompt | string | いいえ | 画像から除外する内容を指定します |
seed | number | いいえ | 再現可能な出力のために固定 seed を設定します |
stylePreset | string | いいえ | 'analog-film'、'anime'、'cinematic'、'comic-book'、'digital-art'、'enhance'、'fantasy-art'、'isometric'、'line-art'、'low-poly'、'modeling-compound'、'neon-punk'、'origami'、'photographic'、'pixel-art'、'tile-texture' のいずれか |
outputFormat | 'jpeg' | 'png' | 'webp' | いいえ | 出力画像形式。デフォルトは 'png' です。 |
Flux オプション
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
modelName | 'flux-pro-1.1' | 'flux-kontext-pro' | はい | 使用する Flux モデルを選択します |
width | number | いいえ | 32 の倍数で、256 ~ 1440 の範囲。デフォルトは 1024 です。 |
height | number | いいえ | 32 の倍数で、256 ~ 1440 の範囲。デフォルトは 768 です。 |
prompt_upsampling | boolean | いいえ | true の場合、プロバイダーはよりクリエイティブな出力のためにプロンプトを書き換えます |
seed | number | いいえ | 再現可能な出力のための整数 seed |
safety_tolerance | number | いいえ | 1(最も厳格)から 5(最も寛容)までの整数 |
戻り値
generate() は Promise<string>(TypeScript)または str(Python)を返します。文字列は生成された画像を指す URL です。URL は一時的なもので、保持期間はプロバイダーごとに異なります。
- GPT Image: Squid storage を指す signed URL。基になるファイルは 1 日間保持されます
- Stable Diffusion Core: Squid storage を指す signed URL。基になるファイルは 1 日間保持されます
- Flux: Black Forest Labs によりホストされる signed URL
画像への長期的なアクセスが必要な場合は、URL からダウンロードし、独自の Squid storage bucket に再アップロードしてください。
背景削除
removeBackground() は画像ファイルを受け取り、背景を削除した同じ画像を指す URL を返します。内部では常に Stable Diffusion を使用します(モデルは選択しません)。このメソッドを動作させるには、アプリケーションで Stability AI を有効化する必要があります。
| メソッド | TypeScript signature | Python signature |
|---|---|---|
removeBackground | (file: File) => Promise<string> | (image_data: bytes, filename: str = "image.png", content_type: str = "image/png") -> str |
コード例
スタイルプリセットを使用して Stable Diffusion で生成する
- TypeScript
- Python
import { executable, SquidService } from '@squidcloud/backend';
export class ImageService extends SquidService {
@executable()
async generateAnimePoster(subject: string): Promise<string> {
this.assertIsAuthenticated();
return this.squid.ai().image().generate(subject, {
modelName: 'stable-diffusion-core',
stylePreset: 'anime',
aspectRatio: '2:3',
outputFormat: 'png',
negativePrompt: 'low quality, blurry, watermark',
});
}
}
from squidcloud_backend import SquidService, executable
class ImageService(SquidService):
@executable()
async def generate_anime_poster(self, subject: str) -> str:
self.assert_is_authenticated()
return await self.squid.ai().image().generate(
subject,
{
'modelName': 'stable-diffusion-core',
'stylePreset': 'anime',
'aspectRatio': '2:3',
'outputFormat': 'png',
'negativePrompt': 'low quality, blurry, watermark',
},
)
特定の解像度で Flux を使用して生成する
- TypeScript
- Python
const url = await this.squid.ai().image().generate('a glass terrarium with bonsai trees', {
modelName: 'flux-pro-1.1',
width: 1024,
height: 1024,
safety_tolerance: 2,
seed: 42, // Deterministic output
});
url = await self.squid.ai().image().generate(
'a glass terrarium with bonsai trees',
{
'modelName': 'flux-pro-1.1',
'width': 1024,
'height': 1024,
'safety_tolerance': 2,
'seed': 42, # Deterministic output
},
)
生成してから結果を Squid storage に永続化する
プロバイダー URL は一時的なものです。画像を保持したい場合は、ダウンロードして Squid storage bucket に再アップロードしてください。
- TypeScript
- Python
import { executable, SquidService } from '@squidcloud/backend';
export class GalleryService extends SquidService {
@executable()
async generateAndStore(prompt: string): Promise<{ url: string }> {
this.assertIsAuthenticated();
const tempUrl = await this.squid.ai().image().generate(prompt, {
modelName: 'gpt-image-1',
size: '1024x1024',
quality: 'high',
});
// Download the image bytes from the temporary URL.
const response = await fetch(tempUrl);
if (!response.ok) {
throw new Error(`Failed to download generated image: ${response.status}`);
}
const arrayBuffer = await response.arrayBuffer();
// Upload to Squid storage so the image is available long-term.
const storage = this.squid.storage('gallery');
const fileName = `${crypto.randomUUID()}.png`;
const file = new File([arrayBuffer], fileName, { type: 'image/png' });
await storage.uploadFile('generated', file);
const { url } = await storage.getDownloadUrl(`generated/${fileName}`);
return { url };
}
}
import base64
import httpx
from squidcloud_backend import SquidService, executable
class GalleryService(SquidService):
@executable()
async def generate_and_return(self, prompt: str) -> dict:
self.assert_is_authenticated()
temp_url = await self.squid.ai().image().generate(
prompt,
{'modelName': 'gpt-image-1', 'size': '1024x1024', 'quality': 'high'},
)
# Download the image bytes from the temporary URL before it expires.
async with httpx.AsyncClient() as http:
response = await http.get(temp_url)
response.raise_for_status()
image_bytes = response.content
# Return the image inline as base64. For long-term hosting, upload from
# the TypeScript backend or your own storage layer.
return {
'base64': base64.b64encode(image_bytes).decode('ascii'),
'mimeType': 'image/png',
}
client upload から背景を削除する
- TypeScript
- Python
import { executable, SquidFile, SquidService } from '@squidcloud/backend';
export class ImageService extends SquidService {
@executable()
async stripBackground(image: SquidFile): Promise<string> {
this.assertIsAuthenticated();
if (!image.mimetype.startsWith('image/')) {
throw new Error('Only image files are accepted');
}
const file = new File([image.data], image.originalName, { type: image.mimetype });
return this.squid.ai().image().removeBackground(file);
}
}
from squidcloud_backend import SquidFile, SquidService, executable
class ImageService(SquidService):
@executable()
async def strip_background(self, image: SquidFile) -> str:
self.assert_is_authenticated()
if not image['mimetype'].startswith('image/'):
raise ValueError('Only image files are accepted')
return await self.squid.ai().image().remove_background(
image['data'],
image['originalName'],
image['mimetype'],
)
エラー処理
よくあるエラー
| エラー | 原因 | 解決策 |
|---|---|---|
UNAUTHORIZED | admin 以外の context(例: backend でラップしていない browser)から画像メソッドを呼び出した | 呼び出しを executable でラップするか、backend code から呼び出す |
Unsupported image model name | modelName が対応リストに含まれていない | gpt-image-* モデル、stable-diffusion-core、flux-pro-1.1、または flux-kontext-pro を使用する |
Invalid width: <n> (Flux) | 幅が 256 ~ 1440 の範囲の整数ではない、または 32 の倍数ではない | 最も近い有効な値に丸める |
Invalid height: <n> (Flux) | 高さが 256 ~ 1440 の範囲の整数ではない、または 32 の倍数ではない | 最も近い有効な値に丸める |
Invalid safety tolerance (Flux) | safety_tolerance が 1 ~ 5 の範囲の整数ではない | [1, 5] 内の値を使用する |
Image generation timed out (Flux) | プロバイダー job が polling window 内に完了しなかった | 再試行するか、別のモデルにフォールバックする |
Method not implemented (背景削除) | Stability 以外のプロバイダーで背景削除を試みた | removeBackground() を直接呼び出します。context にかかわらず常に Stable Diffusion を使用します。 |
MUST_PROVIDE_FILE | ファイルなしで removeBackground() を呼び出した | 空でない File(TypeScript)または bytes(Python)を渡す |
入力を早期に検証する
upstream provider の失敗を待つのではなく、executable 内で明らかに不適切な入力を拒否してください。
- TypeScript
- Python
@executable()
async safeGenerate(prompt: string): Promise<string> {
this.assertIsAuthenticated();
if (!prompt || prompt.length < 3) {
throw new Error('Prompt must be at least 3 characters');
}
if (prompt.length > 1000) {
throw new Error('Prompt must be 1000 characters or less');
}
return this.squid.ai().image().generate(prompt, {
modelName: 'gpt-image-1',
});
}
@executable()
async def safe_generate(self, prompt: str) -> str:
self.assert_is_authenticated()
if not prompt or len(prompt) < 3:
raise ValueError('Prompt must be at least 3 characters')
if len(prompt) > 1000:
raise ValueError('Prompt must be 1000 characters or less')
return await self.squid.ai().image().generate(
prompt,
{'modelName': 'gpt-image-1'},
)
ベストプラクティス
- 画像呼び出しは常に executable でラップしてください。 画像メソッドには admin access が必要なため、browser から直接呼び出すことはできません。
- ユースケースに合ったモデルを選択してください。
gpt-image-1は一般用途の画像に適した強力なデフォルトです。スタイルプリセットまたはアスペクト比制御が必要な場合は Stable Diffusion Core が最適です。Flux は明示的な幅・高さ制御と再現可能な seed を提供します。 - 重要な画像は永続化してください。 プロバイダー URL は期限切れになります。長期ホスティングにはダウンロードして Squid storage に再アップロードしてください。
- 不適切な入力を早期に拒否してください。 モデルを呼び出す前に、プロンプトの長さとファイルタイプを検証してください。
- 画像 executable に rate limiting を適用してください。 画像生成は最も高コストな AI 操作の 1 つであり、不正利用の一般的な標的です。
- プロンプト + オプションで cache してください。 同一の
seedを持つ同一プロンプトは、Flux と Stable Diffusion で同一の結果を生成します。quota を節約するため、(prompt, options)の hash で cache してください。
関連項目
- Executables - client から呼び出せるように画像呼び出しをラップする
- AI agent - AI function を通じて画像を生成できる AI agent を構築する
- Storage - 生成した画像を長期アクセス用に永続化する
- Rate and quota limiting - 画像 executable を不正利用から保護する