ぶべ
画像生成SKILLを置いておくと何かと便利
2026年04月06日
見出しはありません
要約を生成中...
Claude Codeには「カスタムスキル」という機能があり、自分だけのコマンドを追加できます。この記事では、/generate-image と打つだけでGoogle Gemini APIによるAI画像生成ができるスキルの作り方を解説します。
コード全文を載せているので、丸ごとコピーしてClaude Codeに「このSKILL作って」と渡せばそのまま動きます。
テキストプロンプトからAI画像を生成
アスペクト比(1:1, 16:9, 9:16 等)や解像度(512〜4K)を指定可能
日本語で指示しても、スキルが自動的に英語プロンプトに変換して高品質な画像を生成
ブログ記事の図解、サムネイル、概念図など幅広い用途に対応
スキルは以下の2ファイルで構成されます。
~/.claude/skills/generate-image/
├── SKILL.md # スキル定義ファイル
└── scripts/
└── generate-image.mjs # 画像生成スクリプト~/.claude/skills/ 配下にフォルダを作り、SKILL.md を置くとClaude Codeがスキルとして自動認識します。
~/.claude/.env に GEMINI_API_KEY=your-api-key を設定(Google AI Studio で取得)
スキル定義ファイルです。Claude Codeに「いつ・どうやってこのスキルを使うか」を教えます。
---
name: generate-image
description: This skill should be used when the user asks to "generate an image", "create an image", "draw", "illustrate", "画像を生成", "画像を作って", "イラストを描いて", or any request involving image creation or generation. Uses Google Gemini API for image generation.
version: 1.0.0
---
# 画像生成スキル
Google Gemini APIを使って画像を生成する。
## このスキルが適用される場面
- 画像の生成・作成・描画のリクエスト
- コンセプトのビジュアル化
- ロゴ、アイコン、ビジュアル素材の作成
- 画像ファイルの出力が必要なあらゆるリクエスト
## 前提条件
- `~/.claude/.env` に `GEMINI_API_KEY` が設定されていること(環境変数でも可)
- Node.js (v18+) が利用可能であること
## 画像生成の方法
Bashツールで `~/.claude/skills/generate-image/scripts/generate-image.mjs` を実行する:
```bash
node ~/.claude/skills/generate-image/scripts/generate-image.mjs "<プロンプト>" [--aspect <比率>] [--size <解像度>] [--output <パス>] [--model <モデル>]
```
### パラメータ
| パラメータ | デフォルト | 選択肢 | 説明 |
|-----------|---------|---------|-------------|
| prompt | (必須) | 任意のテキスト | 画像の説明 |
| --aspect | 1:1 | 1:1, 16:9, 9:16, 4:3, 3:4 | アスペクト比 |
| --size | 1K | 512, 1K, 2K, 4K | 解像度 |
| --output | 自動生成 | ファイルパス | 出力先パス |
| --model | gemini-3-pro-image-preview | 下記参照 | Geminiモデル |
### 利用可能なモデル
- `gemini-3-pro-image-preview` — 高品質
- `gemini-3.1-flash-image-preview` — 最新のflashモデル
## ワークフロー
1. ユーザーのリクエストを解釈し、画像生成に効果的な英語プロンプトを作成する(必要に応じて翻訳)
2. 用途に応じて適切なアスペクト比とサイズを選択する
3. Bashツールで生成スクリプトを実行する
4. 生成後、Readツールで生成された画像をユーザーに表示する
5. APIキーが未設定の場合は、`GEMINI_API_KEY` または `GOOGLE_API_KEY` の設定を案内する
## 守ること
- 文字を入れる場合、指示がない限りは日本語で入れる。
## より良いプロンプトのコツ
- 具体的で詳細な説明を書く
- スタイル情報を含める(例: "watercolor", "photorealistic", "flat design")
- 構図の詳細を指定する(例: "close-up", "wide angle", "bird's eye view")
- ユーザーのプロンプトが日本語の場合、英語に翻訳して内容を補強するdescription フィールドに書いたキーワード("画像を生成", "generate an image" 等)にマッチすると、Claude Codeが自動的にこのスキルを呼び出します。
実際にGemini APIを叩いて画像を生成するNode.jsスクリプト。
#!/usr/bin/env node
// Gemini API Image Generation Script
// Usage: node generate-image.mjs <prompt> [options]
// Options: --aspect <ratio> --size <resolution> --output <path> --model <model>
import { readFileSync } from "fs";
import { resolve, dirname } from "path";
import { fileURLToPath } from "url";
// .envファイルから環境変数を読み込む
const __dirname = dirname(fileURLToPath(import.meta.url));
const envPath = resolve(__dirname, "..", "..", "..", ".env");
try {
const envContent = readFileSync(envPath, "utf-8");
for (const line of envContent.split("\n")) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith("#")) continue;
const idx = trimmed.indexOf("=");
if (idx === -1) continue;
const key = trimmed.slice(0, idx).trim();
const value = trimmed.slice(idx + 1).trim();
if (!process.env[key]) {
process.env[key] = value;
}
}
} catch {}
const args = process.argv.slice(2);
function parseArgs(args) {
const options = {
prompt: "",
aspect: "1:1",
size: "1K",
output: "",
model: "gemini-3-pro-image-preview",
};
const positional = [];
for (let i = 0; i < args.length; i++) {
if (args[i] === "--aspect" && args[i + 1]) {
options.aspect = args[++i];
} else if (args[i] === "--size" && args[i + 1]) {
options.size = args[++i];
} else if (args[i] === "--output" && args[i + 1]) {
options.output = args[++i];
} else if (args[i] === "--model" && args[i + 1]) {
options.model = args[++i];
} else {
positional.push(args[i]);
}
}
options.prompt = positional.join(" ");
return options;
}
const options = parseArgs(args);
if (!options.prompt) {
console.error("Error: prompt is required");
console.error(
'Usage: node generate-image.mjs "your prompt" [--aspect 16:9] [--size 1K] [--output path.png] [--model model-name]'
);
process.exit(1);
}
const apiKey = process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY;
if (!apiKey) {
console.error(
"Error: GEMINI_API_KEY or GOOGLE_API_KEY environment variable is required"
);
process.exit(1);
}
const url = `https://generativelanguage.googleapis.com/v1beta/models/${options.model}:generateContent?key=${apiKey}`;
const body = {
contents: [
{
parts: [{ text: options.prompt }],
},
],
generationConfig: {
responseModalities: ["TEXT", "IMAGE"],
imageConfig: {
aspectRatio: options.aspect,
imageSize: options.size,
},
},
};
async function main() {
console.log(`Generating image with model: ${options.model}`);
console.log(`Prompt: ${options.prompt}`);
console.log(`Aspect ratio: ${options.aspect}, Size: ${options.size}`);
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (!response.ok) {
const error = await response.text();
console.error(`API Error (${response.status}): ${error}`);
process.exit(1);
}
const data = await response.json();
if (!data.candidates || !data.candidates[0]?.content?.parts) {
console.error("No content in response:", JSON.stringify(data, null, 2));
process.exit(1);
}
const { default: fs } = await import("fs");
const { default: path } = await import("path");
let imageCount = 0;
let textResponse = "";
for (const part of data.candidates[0].content.parts) {
if (part.inlineData) {
imageCount++;
const outputPath =
options.output ||
path.join(
process.cwd(),
`generated-image-${Date.now()}-${imageCount}.png`
);
const buffer = Buffer.from(part.inlineData.data, "base64");
fs.writeFileSync(outputPath, buffer);
console.log(`Image saved: ${outputPath}`);
}
if (part.text) {
textResponse += part.text;
}
}
if (textResponse) {
console.log(`\nText response: ${textResponse}`);
}
if (imageCount === 0) {
console.error("No images were generated in the response.");
process.exit(1);
}
console.log(`\nDone! Generated ${imageCount} image(s).`);
}
main().catch((err) => {
console.error("Error:", err.message);
process.exit(1);
});この記事のテキストを丸ごとコピーして、Claude Codeに「画像生成SKILLつくって」と渡せばOKです。
Vibely MCPと組み合わせて、「図解画像を入れながら記事書いて」と言えば適宜画像生成SKILLを呼び出しながら記事を書いてくれる
ブログ記事のOGPサムネイル画像を自動生成
プレゼン資料用の概念図・フロー図を作成
App Store用のスクリーンショット画像の作成
SKILL.mdの「ワークフロー」セクションに「英語に翻訳してプロンプトを作成する」と書いておくことで、日本語で指示しても高品質な画像が生成されます。スキル定義でClaude Codeの振る舞いをコントロールできるのがカスタムスキルの強みです。
要約
コメント
まだコメントはありません。