画像生成
自然言語プロンプトから画像を生成し、既存画像の背景を削除します。
AI画像生成を使う理由
アプリケーションにはカスタム画像が必要です。たとえば、ユーザーのプロンプトに合うヒーローイラスト、説明に基づくアバター、eコマース掲載用のプロダクトモックアップ、またはプロフィール写真用のきれいな切り抜きなどです。ストックライブラリでは汎用的すぎますし、各モデルプロバイダに直接統合すると、APIキー、リクエスト形式、ポーリングロジック、ストレージの扱いをすべて取り回す必要があります。
Squid AI Image は、複数の画像モデルに対して単一のバックエンドAPIと、組み込みの背景削除エンドポイントを提供します。
- TypeScript
- Python
const url = await this.squid.ai().image().generate('a pirate ship at sunset, oil painting style', {
modelName: 'dall-e-3',
size: '1024x1024',
quality: 'hd',
});
url = await self.squid.ai().image().generate(
'a pirate ship at sunset, oil painting style',
{'modelName': 'dall-e-3', 'size': '1024x1024', 'quality': 'hd'},
)
概要
Squid AI Image は、3つの系統の画像モデルを単一のクライアントの背後にラップします。
- 一般用途の写実的・スタイライズ画像向けの OpenAI DALL-E 3
- スタイルプリセット、アスペクト比コントロール、背景削除向けの Stability AI Stable Diffusion Core
- 明示的な width/height 指定による高品質生成向けの Black Forest Labs Flux Pro / Flux Kontext Pro
Squid backend はリクエストを認証し、アプリケーション設定から適切なプロバイダのAPIキーを取得し、上流モデルを呼び出して、生成された画像へのURLを返します。
AI Image を使うべき場合
| ユースケース | 推奨 |
|---|---|
| テキストプロンプトから単発の画像を生成する | スタイル要件に合うモデルで generate() を使う |
| アップロードした写真から背景を除去する | removeBackground() |
| AI agent の中で生成画像を表示する | generate() を呼び出してURLを返す AI function をアタッチする |
| 生成アセットを長期保存する | 返された画像を Squid storage にアップロードする |
仕組み
- バックエンドサービスから
this.squid.ai().image().generate(prompt, options)を呼び出します - Squid がモデルとオプションを検証し、対応するプロバイダ(OpenAI / Stability / Black Forest Labs)にルーティングします
- プロバイダが画像を生成し、URLを返します
- Squid backend がそのURLをコードに返します
- URLは一時的です。画像を保持する必要がある場合はダウンロードし、Squid storage または自分のバケットに再アップロードしてください。
クイックスタート
前提条件
squid initで初期化された Squid backend プロジェクト@squidcloud/backendパッケージ(TypeScript)またはsquidcloud-backendパッケージ(Python)- 呼び出すモデルに応じて、Squid Console で該当するAIプロバイダが有効化されていること(OpenAI / Stability AI / Black Forest Labs)
ステップ1: 呼び出しを executable でラップする
画像生成には admin access が必要なため、バックエンドで実行する必要があります。APIキーを漏らさずにクライアントからトリガーできるよう、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: 'dall-e-3',
quality: 'standard',
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': 'dall-e-3',
'quality': 'standard',
'size': '1024x1024',
}
return await self.squid.ai().image().generate(prompt, options)
ステップ2: バックエンドを実行またはデプロイする
squid start
クラウドへデプロイする場合は、deploying your backend を参照してください。
ステップ3: クライアントから呼び出す
const imageUrl = await squid.executeFunction('generateImage', 'a friendly squid mascot, vector art');
document.querySelector<HTMLImageElement>('#preview')!.src = imageUrl;
認証と設定
画像メソッドは、admin access を持つ認証済みの Squid client を必要とします。generate() と removeBackground() は、バックエンドまたは admin コンテキストに由来しない呼び出しを拒否します。
推奨されるパターンは次の2つです。
- 呼び出しを executables でラップする(クイックスタートのとおり)。クライアント起点の画像生成では標準的なパターンです。executables を参照してください。
- 権限のあるバックエンドサービスから呼び出す。たとえば trigger、scheduler、または webhook などです。
プロバイダAPIキー(OpenAI / Stability / Flux)は Squid Console のアプリケーション設定に保存されます。Squid は、渡された modelName に基づいてリクエスト時に正しいキーを参照します。
コアコンセプト
対応モデル
AiGenerateImageOptions は modelName による discriminated union です。このフィールドによって、有効なオプションセットと呼び出されるプロバイダが決まります。
| Model | Provider | Options type |
|---|---|---|
dall-e-3 | OpenAI | DallEOptions |
stable-diffusion-core | Stability AI | StableDiffusionCoreOptions |
flux-pro-1.1 | Black Forest Labs | FluxOptions |
flux-kontext-pro | Black Forest Labs | FluxOptions |
DALL-E 3 オプション
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
modelName | 'dall-e-3' | Yes | DALL-E 3 モデルを選択します |
quality | 'hd' | 'standard' | No | 画像品質。デフォルトは 'standard'。 |
size | '1024x1024' | '1792x1024' | '1024x1792' | No | 出力サイズ。デフォルトは '1024x1024'。 |
numberOfImagesToGenerate | 1 | No | DALL-E 3 は1回の呼び出しで1枚のみをサポートします |
Stable Diffusion Core オプション
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
modelName | 'stable-diffusion-core' | Yes | Stable Diffusion Core モデルを選択します |
aspectRatio | string | No | '16:9', '1:1', '21:9', '2:3', '3:2', '4:5', '5:4', '9:16', '9:21' のいずれか。デフォルトは '1:1'。 |
negativePrompt | string | No | 画像から除外したいものを記述します |
seed | number | No | 再現可能な出力のために固定seedを設定します |
stylePreset | string | No | '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' | No | 出力画像フォーマット。デフォルトは 'png'。 |
Flux オプション
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
modelName | 'flux-pro-1.1' | 'flux-kontext-pro' | Yes | 使用する Flux モデルを選択します |
width | number | No | 32の倍数で、256〜1440。デフォルトは 1024。 |
height | number | No | 32の倍数で、256〜1440。デフォルトは 768。 |
prompt_upsampling | boolean | No | true の場合、プロバイダがより創造的な出力のためにプロンプトをリライトします |
seed | number | No | 再現可能な出力のための整数seed |
safety_tolerance | number | No | 1(最も厳格)〜5(最も許容)的な整数 |
戻り値
generate() は Promise<string>(TypeScript)または str(Python)を返します。文字列は生成された画像を指すURLです。URLは一時的で、寿命はプロバイダごとに異なります。
- DALL-E: OpenAI hosted URL。おおむね1時間有効
- Stable Diffusion Core: Squid storage を指す signed URL。基になるファイルは1日保持
- Flux: Black Forest Labs がホストする signed URL
画像を長期間アクセス可能にしたい場合は、URLからダウンロードして自分の Squid storage バケットに再アップロードしてください。
背景削除
removeBackground() は画像ファイルを受け取り、背景を除去した同一画像を指すURLを返します。内部では常に Stable Diffusion を使用します(モデルは選べません)。このメソッドが動作するには、アプリケーションで Stability AI が有効になっている必要があります。
| Method | 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: 'dall-e-3',
size: '1024x1024',
quality: 'hd',
});
// 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': 'dall-e-3', 'size': '1024x1024', 'quality': 'hd'},
)
# 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',
}
クライアントアップロードから背景を削除する
- 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 ではないコンテキストから画像メソッドを呼び出した(例: バックエンドでラップしていないブラウザ) | 呼び出しを executable でラップするか、バックエンドコードから呼び出す |
Unsupported image model name | modelName がサポート一覧にない | dall-e-3, stable-diffusion-core, flux-pro-1.1, flux-kontext-pro のいずれかを使用する |
Invalid width: <n> (Flux) | width が 256〜1440 の整数でない、または 32 の倍数でない | 最も近い有効値に丸める |
Invalid height: <n> (Flux) | height が 256〜1440 の整数でない、または 32 の倍数でない | 最も近い有効値に丸める |
Invalid safety tolerance (Flux) | safety_tolerance が 1〜5 の整数でない | [1, 5] の値を使う |
Image generation timed out (Flux) | ポーリングウィンドウ内にプロバイダジョブが完了しなかった | リトライする、または別モデルにフォールバックする |
Method not implemented (background removal) | Stability 以外のプロバイダで背景削除を試みた | removeBackground() を直接呼び出す。コンテキストに関係なく常に Stable Diffusion を使います。 |
MUST_PROVIDE_FILE | removeBackground() をファイルなしで呼び出した | 空でない File(TypeScript)または bytes(Python)を渡す |
入力を早期に検証する
上流プロバイダの失敗を待つよりも、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: 'dall-e-3',
});
}
@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': 'dall-e-3'},
)
ベストプラクティス
- 画像呼び出しは必ず executables でラップする。 画像メソッドには admin access が必要なため、ブラウザから直接呼び出せません。
- ユースケースに合うモデルを選ぶ。 DALL-E 3 は一般用途で強力なデフォルトです。Stable Diffusion Core はスタイルプリセットやアスペクト比コントロールが必要なときに優れます。Flux は明示的な width/height 指定と再現可能なseedを提供します。
- 重要な画像は永続化する。 プロバイダURLは失効します。Squid storage にダウンロードして再アップロードし、長期ホスティングしてください。
- 不正な入力は早期に拒否する。 モデルを呼ぶ前に、プロンプト長とファイル種別を検証します。
- 画像用 executables に rate limiting を適用する。 画像生成は最も高価なAI操作の一つで、悪用の標的になりやすいです。
- プロンプト + オプションでキャッシュする。 Flux と Stable Diffusion では、同一の
seedを使った同一プロンプトは同一結果を生成します。クォータ節約のため、(prompt, options)のハッシュでキャッシュしましょう。
関連項目
- Executables - 画像呼び出しをラップしてクライアントから呼べるようにする
- AI agent - AI function 経由で画像生成できるAI agentを構築する
- Storage - 生成画像を長期アクセスのために保存する
- Rate and quota limiting - 画像用 executables の悪用を防ぐ