はじめに:この「完璧な仕様書」の秘密を明かします
まずはこちらをご覧ください。私が開発したWindowsアプリ『Stamp Factory』の仕様書の一部です。
記事の最後ですべて公開してます。
# Stamp Factory - アプリケーション仕様書 (v2.2.3)
## 1. 概要
Google Gemini APIを利用して、LINEスタンプ(背景透過、白フチ付き)を生成するWindows向けデスクトップアプリケーション。
## 1.5 技術スタック
- フロントエンド: React 18.3.1 + Tailwind CSS
- フレームワーク: Electron 28.2.0 + Vite
- バックエンド処理: Python 3.10+ (rembg, Pillow)
- キャンバス編集: Fabric.js 6.9.0
- AIモデル: Gemini 3.0 Pro / 2.5 Flash
## 3.3 セキュリティ
- APIキー管理: Electron safeStorageによる暗号化保存
- コマンドインジェクション対策: 独自のサニタイズ処理実装
「ReactにElectron、それにPythonの環境構築……? さらにはセキュリティ対策まで?」
「こんな本格的な設計、プロのエンジニアじゃないと無理でしょ」
もしあなたがそう思い、ブラウザの「戻る」ボタンに指をかけたなら、ちょっと待ってください。この続きは間違いなく、あなたのためのものです。

実は、私はプログラミングスキルが一切ありません。
コードは1行も書けませんし、このアプリを作る前は「Electron」が何なのかさえ知りませんでした。
そして、最大のネタばらしをします。
冒頭の立派な仕様書。これは、アプリを作り始める前に私が書いたものではありません。
アプリが完成した後に、AI(Cursor)に「今作ったこのアプリの仕様をまとめて」と投げて、数秒で書かせたものなのです。
「Hello World」で止まっていた時計を動かす
私たち非エンジニアには、共通の「痛み」があります。
「プログラミングで自分のアイデアを形にしたい」と思い立ち、ProgateやUdemyで学習を始める。変数の概念を学び、『Hello World』を表示させて喜ぶ。
……でも、そこから先へ進めないのです。
「で、ここからどうやって『自分の作りたいアプリ』になるの?」
環境構築のエラーでつまずき、ライブラリの依存関係で心を折られ、結局「自分には才能がない」とPCを閉じる。私もかつてはそうでした。
しかし、2025年の今、その壁は完全に消滅しました。
私が今回実践したのは、「チャット駆動開発(Chat-driven Development)」という、まったく新しいアプローチです。
- 「こんな感じの画面が欲しい」と日本語で伝える
- AIがとりあえず動くものを作る
- 「ここを直して」「機能を追加して」と対話で修正する
- 完成したカオスなコードを、最後にAIが解析して「仕様書」として清書する
つまり、「作る」が先、「説明」は後なのです。
AIイラスト呪文作成アプリ「Prompt Palette」を作った話
この記事の前日譚。プログラミングスキル一切なしでWebツールを作り、Windowsアプリ化した最初の挑戦記録です。
通常なら「即死レベル」の技術的難易度
今回開発した『Stamp Factory』は、正直に言って、初心者が手を出していいレベルの技術構成ではありません。
- Google Gemini 3.0: 最新AIとのAPI連携
- Python (rembg): 裏側で高度な画像処理を実行
- Fabric.js: HTML5 Canvasを操作して「縦書き」を実現
- Electron: これらを束ねてWindowsアプリ化
特に「Electron(JavaScript)」と「Python」を一つのアプリ内で連携させ、exeファイルとして配布可能な形にする作業は、熟練のエンジニアでも「環境構築の地獄」と呼ぶほど面倒な工程です。通常なら、この連携部分だけで数日は溶けるでしょう。
しかし、私には優秀な相棒であるAIエディタ「Cursor」がいました。
私がやったのは、彼らに「監督」として指示を出すことだけ。
「Pythonが動かないエラーが出たよ」と画面を貼り付ければ、AIが「ああ、パスが通っていませんね。このコードに書き換えてください」と即座に修正案を出してくれます。
その結果、知識ゼロの私が、わずか数日で以下のようなツールを完成させることができました。
この記事は、知識ゼロの人間が、AIという「最強の部下」を使って開発者へと変貌するまでの、生々しいドキュメンタリーです。
1. 成果物『Stamp Factory』の全貌 – ここまで自動化できる
「知識ゼロで作った」と言うと、多くの人はこう想像するかもしれません。
「どうせ、黒い画面(コマンドプロンプト)に文字を打ち込んだら画像が出てくるだけの、簡易的なスクリプトでしょ?」と。
いいえ、違います。
私がCursorとGeminiで作り上げた『Stamp Factory』は、「今日からこのまま販売できるレベル」のGUI(グラフィカル・ユーザー・インターフェース)を持つ、完全なWindowsデスクトップアプリです。
まずは、このアプリが実現した「3つの自動化」を見てください。これら全ての機能が、私がコードを1行も書かずに、ただ日本語で「こういう機能が欲しい」とお願いしただけで実装されたものです。
① プロンプト不要の「高品質画像生成」
LINEスタンプを作る上で最大の壁は、「40個もネタが思いつかない」ことと「プロンプト(呪文)が難しい」ことです。
Stable Diffusionなどの画像生成AIを使ったことがある方なら分かると思いますが、「白背景で」「キャラクターを固定して」「指を破綻させずに」……これらの呪文を調整するだけで、スタンプを作る前に日が暮れてしまいます。
AI画像生成で思い通りのイラストを作るコツ
1girl, SD characterなど、基本的な呪文の組み立て方はこちらで解説しています。
このアプリでは、裏側でGoogleの最新AIモデル「Gemini 3.0 Nano Banana Pro」が動いています。
なぜ、流行りの画像生成AIではなくGeminiを選んだのか?
理由は、「日本語の指示への圧倒的な理解力」と「コストパフォーマンス」です。
Geminiは、ユーザーの曖昧な日本語を解釈する能力に長けています。ユーザーは複雑な呪文を唱える必要はありません。
- キャラ設定: 「パーカーを着た眠そうな少女、ピンク髪、デフォルメ」
- 動作: 「おはよう」「OK」「既読スルー」
この2つを入力するだけで、アプリ内部で勝手に「LINEスタンプ風の画風、白背景、高品質、アニメスタイル、主線はくっきりと……」といった補正プロンプトを付与してGeminiに投げます。
さらに、「毎回動作を考えるのが面倒くさい」という私のズボラな悩みを解決するために、「ガチャ機能」も実装しました。
ボタン一つで、「ピザを食べて寝落ちする」「虚無の顔でパソコンを叩く」「布団から出たくないと駄々をこねる」といった、自分では絶対思いつかないようなシチュエーションをAIが勝手に考え、勝手に画像を生成し続けます。
私はコーヒーを飲んで、画面に次々と現れる可愛いスタンプを眺めているだけです。
② 「rembg」による背景透過と白フチの自動化
ここが最大の技術的ハイライトであり、私が最もこだわった部分です。
AIで画像を生成しても、そのままではLINEスタンプには使えません。背景が四角く残ってしまうからです。
通常、ここからが「地獄」の始まりです。
- Photoshopを開く
- 画像を読み込む
- 「被写体を選択」で切り抜く(髪の毛の隙間とかが面倒!)
- 白いフチをつける
- リサイズして保存する
これを40回繰り返す。考えただけで副業を辞めたくなります。
そこで私はCursorにこう指示しました。
「Pythonの『rembg』というライブラリを使って、生成された瞬間に背景を透明にして。あと、スタンプっぽく周りに白いフチをつけて」
その結果、以下のフローが全自動化されました。
- 画像が生成される
- 裏でPythonが起動し、わずか数秒で背景を削除
- 画像処理ライブラリ(Pillow)が、キャラの輪郭に沿って3pxの白いフチを描画
- LINE規定のサイズ(370×320px)にリサイズ
コラム:実はものすごい「Python内包」の技術
エンジニアの方なら、ここで「おっ」と思ったかもしれません。
Web技術であるElectron(JavaScript)の中で、Pythonを動かす。しかも、ユーザーにPythonをインストールさせるのではなく、アプリの中にPython環境を丸ごと詰め込んで(exe化して)配布する。
これは、プロのエンジニアでも「環境構築が面倒くさい」「パスが通らない」と嫌がる、かなり難易度の高い実装です。
しかし、Cursorは文句一つ言わず、pyinstallerを使ったビルド設定まで完璧に書き上げてくれました。私がやったのは、出来上がったexeファイルをクリックしただけです。
③ 「40個の壁」を超えるスロット管理システム
LINEスタンプの販売には、最低でも8個、最大で40個の画像セットが必要です。
以前の私は、生成した画像をフォルダに保存し、「image_01.png」「image_02_new.png」……と名前をつけ、どれが採用でどれがボツか分からなくなるという惨状を繰り返していました。
そこで、「ドラッグ&ドロップで管理できる専用画面」を作らせました。
- 01〜40番のスロット: 空いている場所に生成画像を放り込むだけ
- メイン画像・タブ画像: 専用の枠を用意
- 入れ替え機能: マウス操作だけで順番を入れ替え
まるでパズルを埋めるようにスタンプ作りが進みます。これも「Reactで作るなら、ドラッグ&ドロップのライブラリ(dnd-kit等)入れたらいいよ」とAIが提案してくれ、実装コードを書いてくれました。
2. 開発の裏側:Cursor × Geminiへの「指示出し」具体例
「すごいのは分かった。でも、実際どうやって作るの?」
「英語で黒い画面にコマンドを打つ必要があるんじゃないの?」
ここからは、私が実際に『Stamp Factory』を開発した時の画面と、入力した「日本語の指示(プロンプト)」をそのまま公開します。
結論から言います。
2025年の開発において、最も強力なプログラミング言語はPythonでもJavaScriptでもありません。「日本語」です。
魔法のショートカット「Ctrl + I」で世界が変わる
これまでのAIコーディング(ChatGPTなど)には、致命的な弱点がありました。
「コードを書いて」と頼むと、AIは画面上にコードを表示してくれます。しかし、それをコピーして、自分のファイルの「正しい場所」に貼り付けるのは、あくまで「人間」の仕事でした。
「どのファイルの何行目に貼り付けるの?」
「貼り付けたら、インポートの記述が足りなくてエラーになった!」
初心者はここで死にます。私も何度も死にました。
しかし、AIエディタ「Cursor」の革新的な機能「Composer(コンポーザー)」は違います。
キーボードの Ctrl + I(MacならCmd + I)を押すと、画面中央に小さな入力バーが現れます。
Cursorの設定を自宅と職場で同期する方法
Cursorを本格的に使いこなすなら設定同期は必須。GitHubを使った簡単な方法を紹介しています。
ここに要望を書き込むと、何が起きるか。
AIが勝手にファイルを開き、勝手にコードを書き換え始めます。

画面上のコードが、まるで生き物のように流れていきます。
削除される古いコードは「赤色」で、新しく追加されるコードは「緑色」でハイライト表示(Diff表示)され、ものすごいスピードで書き換わっていく。
私たちは、その様子を腕組みして眺め、最後に表示される「Accept(承認)」ボタンを押すだけ。
「そうそう、そういうこと」と頷いてボタンを押す。
まさに、「プログラミング(作業)」ではなく「ディレクション(指示出し)」です。
実録①:最初の1行目「土台を作って」
何もない真っ白な画面。ここからどうやってアプリを作るのか?
私が最初に入力したのは、こんな単純な日本語でした。
プロンプト:
「ElectronとReactを使って、左側に設定パネル、右側に画像プレビューが表示される、モダンな黒基調のアプリの雛形を作ってください。スタイリングにはTailwind CSSを使って。」
たったこれだけです。
Composerは即座に動き出し、「package.jsonを作成」「App.jsxを作成」……と複数のファイルを同時に生成し、わずか3分後には、「実行するにはこのボタンを押してね」という状態に。
言われた通りに実行すると、画面にはすでに「左にパネル、右にプレビュー」のレイアウトが出来上がっていました。
実録②:曖昧な指示でも通じる「文脈(コンテキスト)理解」
開発が進むと、修正したい箇所が出てきます。
ここでCursorの恐ろしい能力「コンテキスト(文脈)理解」が火を噴きます。
例えば、右側のプレビュー画面の背景を「チェック柄(透過表現)」にしたいと思いました。
しかし、私はそのプレビュー画面のコードが「どのファイルの」「どのクラス名」で書かれているか知りません(AIが勝手に作ったので)。
普通のエンジニアならファイルを探すところですが、私はこう指示しました。
プロンプト:
「右側のプレビュー画面の背景を、Photoshopみたいな白とグレーの市松模様にして。」
Cursorはプロジェクト全体をインデックス化しており、「ああ、ユーザーが言っている『右側のプレビュー』とは PreviewPanel.jsx のことだな」と瞬時に理解します。
さらに、PreviewPanel.jsx を修正するだけでなく、「市松模様のスタイル定義が必要だから index.css にもクラスを追加しておこう」と、関連する別ファイルまで同時に書き換えてくれたのです。
「アレをいい感じにして」
まるで熟年夫婦のような阿吽の呼吸が、AIとの間で成立するのです。
実録③:複雑なロジックを実装する「ガチャ機能」
見た目だけでなく、プログラムの「中身(ロジック)」も日本語で作れます。
『Stamp Factory』の目玉機能である「ガチャ(ランダム生成)」の実装例を見てみましょう。
私はこのように、かなり具体的かつ「わがまま」な指示を出しました。
プロンプト:
「『ガチャを回す』というボタンを追加して。
押されたら、LINEスタンプにありそうな面白いシチュエーションをランダムで選んで、プロンプト入力欄に自動入力して、そのまま生成を開始してほしい。
シチュエーションは、ちょっとシュールで笑えるやつを10個くらい考えて配列に入れておいて。」
これに対するCursorの仕事ぶりには、思わず笑ってしまいました。
AIが生成したコード(配列)の一部がこちらです。
// AIが勝手に考えたスタンプのネタ
const randomPrompts = [
"ピザを食べて寝落ちする少女",
"虚無の顔でキーボードを叩く",
"布団から絶対に出ないと固い決意",
"壁のシミを見つめて現実逃避",
"給料日直後の王族のような振る舞い",
// ...他5つ
];
「給料日直後の王族」なんて、私の語彙力にはありませんでした(笑)。
Cursorはこの配列を作るだけでなく、
- 画面に「ガチャ」ボタンを配置し(UI)
- ボタンが押されたら配列からランダムに1つ選び(ロジック)
- それを入力欄にセットして生成関数をキックする(連携)
ここまでの一連の流れを、一度の指示ですべて完結させました。
「やりたいこと(What)」さえ伝えれば、「どうやるか(How)」はAIが全部知っている。 これが現代の開発スタイルです。
3. 激闘の記録:AIが苦手な「縦書き」と「角丸」をどう実装させたか
ここまで読んだあなたは、「なんだ、AIに頼めば何でも一瞬で終わるのか」と思ったかもしれません。
正直に言います。そんなに甘くはありませんでした。
S3でお話しした「ガチャ機能」や「レイアウト作成」は、世界共通のWeb標準技術です。しかし、開発が終盤に差し掛かった時、私は「日本独自の仕様」という巨大な壁にぶち当たりました。
それが、「日本語の縦書き」です。
LINEスタンプにおいて、縦書きのセリフは欠かせません。「ありがとう」を縦に添えるだけで、和風の情緒が出たり、インパクトが増したりします。
私は軽い気持ちでCursorにこう頼みました。
プロンプト:
「テキスト編集機能に『縦書きモード』を追加して。」
これが、1週間にわたる泥沼の戦いの始まりでした。
DXF解析アプリ開発でも起きた「幾何学」のバグ
図形処理はAIの苦手分野? CADファイル解析アプリを作った際も同様の苦労がありました。
コラム:なぜ「縦書き」はこんなに難しいのか?
エンジニアでない方のために、少しだけ技術的な背景を説明させてください。
普段私たちが目にするWebサイト(HTML/CSS)なら、writing-mode: vertical-rl; という呪文を一つ書けば、ブラウザが勝手に文字を縦に並べてくれます。
しかし、今回私が使っているのは「Canvas(キャンバス)」という技術です。これはWebページ上にお絵かきボードを置くようなもので、「文字」を「文字」として扱わず、「図形」として描画します。
海外製のライブラリ(Fabric.js)にとって、文字とは「左から右に並ぶもの」であり、「上から下に並ぶ」なんて概念は存在しなかったのです。
地獄の光景:串刺しになった「ー」と、暴れる「。」
Cursorは自信満々に「実装しました!」とコードを書き換えました。
しかし、プレビュー画面を見て私は絶句しました。
- 文字が「横倒し」になっている(首を90度曲げないと読めない)
- 「ー(長音)」が横棒のまま縦に並ぶ(まるで串団子)
- 句読点「。」が文字のど真ん中に表示される
ここからのAIとのやり取りは、まさに「コント(喜劇)」でした。
- 私:「文字が横に寝てるよ! 起き上がらせて!」
- AI:「分かりました。文字全体を回転(rotate)させます」
- → 結果:文章全体が斜めに45度回転しただけ。
- 私:「違う、一文字ずつ正しく並べて!」
- AI:「では、改行コードを入れて一文字ずつ改行します」
- → 結果:「ー(長音)」が横棒のまま縦に並ぶ(串団子状態)。
「あちらを立てればこちらが立たず」
AIは英語圏のデータで学習しているため、「日本語の縦書きの美しさ」や「約物(記号)の正しい向き」という概念を肌感覚として持っていなかったのです。
突破口は「画像を見せる」ことだった
テキストでいくら説明しても伝わらない。
私が知識ゼロの素人だから、正しい技術用語(グリフ、ベースライン、レンダリング…)で指示できないせいもあるでしょう。
そこで私は作戦を変えました。
「エラー画面のスクリーンショット」を撮り、Cursorのチャット欄にペーストしたのです。
プロンプト(画像付き):
「今の状態がこれ(画像A)。これじゃダメ。
私が作りたいのは、こういう状態(画像B:ネットで拾った正しい縦書きの画像)。
違いを見て、どう修正すべきか考えて。」
すると、AIの反応が劇的に変わりました。
AI:「画像を確認しました。なるほど、Fabric.jsの標準機能では文字ごとの細かい回転制御ができていませんね。『一文字ずつ個別のオブジェクトとして描画し、それを計算で縦に並べる独自関数』を書きましょう」
「独自関数を書く」。
これは、既存のライブラリの機能を使うのを諦め、ゼロからロジックを作るという提案でした。
AIが吐き出したコードの一部がこれです。
// AIが生成した「縦書き描画ロジック」の一部
text.split('').forEach((char, index) => {
let angle = 0;
// 長音や括弧など、縦書き時に回転が必要な文字を判定
if (['ー', '〜', '(', ')'].includes(char)) {
angle = 90;
}
// Y座標を計算して一文字ずつ配置
const charObj = new fabric.Text(char, {
top: startY + (index * lineHeight), // 行送りの計算
left: startX,
angle: angle,
// ...省略
});
canvas.add(charObj);
});
一文字ずつ分解し、特定の記号が来た時だけ角度を変え、座標を計算して配置していく……。
こんなロジック、知識ゼロの私が書けるはずがありません。
しかし、恐る恐る実行ボタンを押すと、画面には綺麗に整列した「ありがとう」の文字が。長音も縦になり、句読点も適切な位置に収まっています。
「勝った……!」
言葉で伝わらなければ、絵で見せる。これは人間相手の仕事と同じでした。
こだわりの「角丸背景」と「数学」の壁
縦書きをクリアした後、もう一つこだわったのが「文字の背景」です。
文字の後ろに色付きの座布団(背景)を敷きたい。しかも、ただの四角ではなく、可愛らしく「角丸」にしたい。
これも「文字数」によって「高さ」が変わるため、数学的な計算が必要でした。
プロンプト:
「文字数に合わせて背景の高さが変わるようにして。あと、iPhoneのアプリアイコンくらい(radius 16pxくらい)丸くして。」
Cursorは、瞬時に以下のような計算式をコードに落とし込みました。
// AIによる背景サイズの動的計算
const bgHeight = (charArray.length * fontSize * lineHeight) + (padding * 2);
const background = new fabric.Rect({
width: bgWidth,
height: bgHeight,
rx: 16, ry: 16 // 角丸設定
});
私が「なんか変」「もっとこうして」と感覚的に注文をつけるだけで、AIはその裏にある幾何学的な計算をすべて肩代わりしてくれました。
4. 「機能追加」の極意:マーケティング機能とセキュリティの実装
アプリが動き、縦書きも綺麗に表示された。
これでもう完成……と言いたいところですが、私はまだ満足していませんでした。
なぜなら、このアプリを作る目的は「スタンプを作ること」ではなく、「スタンプを販売して副業収入を得ること」だからです。
攻めの機能:画像を見て感情を読む「マーケティングアシスタント」
LINEスタンプの販売申請には、日本語と英語のタイトル・説明文が必要です。「40個の画像を作るだけで精一杯なのに、英語の説明文なんて考えたくない……」。
そう思った私は、Cursorに最後の無茶振りをしました。
「ねえ、作ったスタンプ画像をAIが見て、勝手に販売用の説明文を書いてくれない?」
これは、S2で紹介した「画像生成」の逆、「画像認識(Vision)」の技術です。
Gemini 3.0 Proなどの最新モデルは、テキストだけでなく画像も理解できます(マルチモーダル機能)。
私は以下のような指示を出しました。
プロンプト:
「『マーケティング』タブを作って。
そこには、生成したスタンプの中からメイン画像など数枚を読み込ませる。
ボタンを押したら、画像をGeminiに送信して、そのキャラの雰囲気や表情を分析し、**『売れそうな』タイトルと説明文(日英両方)**を提案させて。」
実装された機能は、私の想像を遥かに超えていました。
アプリのスタンプ画像をGeminiが「視る」。そして数秒後、こんなテキストが出力されたのです。
| 項目 | AIが生成した内容 |
|---|---|
| タイトル(JA) | 限界OLの虚無かわいい日常スタンプ |
| タイトル(EN) | Exhausted Office Lady’s Void Life |
| 説明文 | 毎日が辛い、でも辞められない。そんな社畜の悲哀を、パステルカラーの可愛い少女が代弁します。既読スルーや虚無の返信に最適。 |
「私よりマーケティング上手くない……?」
従来のプログラムなら「ピンク色(#FFC0CB)が多い」程度しか判別できませんが、Geminiはキャラクターの死んだ目を見て「虚無感」という感情を読み取り、それを「社畜」「限界OL」という、今の市場に刺さる文脈に翻訳したのです。
守りの機能:一夜にして100万円請求?「セキュリティ」の罠
攻めの機能ができたら、次は「守り」です。
ここを見落とすと、あなたのアプリ開発は「成功談」ではなく「怪談」になります。
このアプリは、将来的に他の人にも配布・販売することを想定しています。
その時、ユーザーに入力してもらったAPIキーを平文で保存し、もしそれが流出したら……。
世界中の誰かがあなたのAPIキーを使い放題になり、翌月あなたの元に数百万円の請求が届くかもしれません。
「怖い! どうすればいいの?」
パニックになりかけた私に、Cursorは冷静に一つの解を提示しました。Electronの「safeStorage(セーフストレージ)」です。
これは、Windowsなら「DPAPI」、Macなら「キーチェーン」といった、OS標準の頑丈な金庫を使ってデータを暗号化する仕組みです。
プロンプト:
「APIキーを保存する時は、Electronの safeStorage を使って暗号化して。セキュリティ事故は絶対に起こしたくない。」
するとCursorは、涼しい顔でメインプロセスを書き換え、暗号化処理を追加しました。
「セキュリティなんて分からない」と逃げるのではなく、「セキュリティを実装して」とAIに頼む。これだけで、あなたのアプリは「素人の工作」から「信頼できるプロダクト」へと進化します。
自分のアイコンが、デスクトップに輝く瞬間
機能は揃いました。最後にやることは一つ。
このプログラムを、誰でもダブルクリックで起動できる「exeファイル」にすることです。
プロンプト:
「Windows用のインストーラー(exe)を作りたい。electron-builder の設定をして。」
ターミナルに文字列が流れること数分。Done の文字と共に、dist フォルダの中に、私がデザインしたアイコンの Stamp Factory Setup.exe が生成されました。
震える手でそれをダブルクリックします。
見慣れたWindowsのインストーラーが立ち上がり、「インストールしています」のバーが伸びていく。
そして、デスクトップに私のアプリのショートカットが現れました。
それをクリックして、アプリが起動した瞬間。
私は、ただの「AIツールの消費者」を卒業しました。
5. まとめ:あなたは「エンジニア」ではなく「監督」になれ
長い旅にお付き合いいただき、ありがとうございました。
デスクトップに生成された Stamp Factory.exe のアイコンを見つめながら、私は今、不思議な感覚に包まれています。
数週間前まで、「Electron」のスペルすら怪しかった私が、今は自分だけのツールを使ってLINEスタンプを量産し、副業の準備を進めているのです。
この「開発記録」を通じて、私があなたに伝えたかったことは、たった一つです。
「プログラミングの勉強は、もうしなくていい」
誤解を恐れずに言えば、そういうことです。
もちろん、知識があるに越したことはありません。しかし、2025年のモノづくりにおいて最も重要なスキルは、「コードを書く技術(Coding)」から「AIを動かす技術(Directing)」へと完全にシフトしました。
あなたが座るべき椅子は「監督席」
映画作りを想像してみてください。
これまでのアプリ開発は、あなたが「脚本」を書き、自分で「カメラ」を回し、自分で「照明」を当て、自分で「編集」をする必要がありました。だから、カメラの操作方法を覚えるだけで数年かかり、映画(アプリ)を撮る前に挫折していたのです。
しかし、CursorとGeminiという「最強のスタッフ」が手に入った今、あなたが座るべきは「監督席(ディレクターズ・チェア)」です。
- カメラマン(AI):「監督、このシーンはどう撮りますか?」
- あなた(監督):「ここは縦書きで、和風の情緒を出したいんだ。」
- カメラマン(AI):「了解です。(複雑な計算式を書いて)……こんな感じでどうでしょう?」
これが、現代の開発風景です。
あなたは、レンズの構造(Canvasのレンダリング)を知らなくてもいい。
必要なのは、「どんな映画(アプリ)を撮りたいか」という強烈なビジョンと、スタッフに指示を出し続ける「熱意」だけです。
「知識ゼロ」は、もはやハンデではない
むしろ、私はこうさえ思っています。
「知識ゼロの素人こそが、最強のイノベーターになれる」と。
熟練のエンジニアほど、「それは技術的に難しい」とブレーキをかけてしまいがちです。
しかし、知識のない私たちは、技術的な制約など知りません。ただ純粋な「欲望」があるだけです。
「画像から勝手に説明文を書いてほしい」
「ボタン一つで背景を消してほしい」
私が『Stamp Factory』で実装したこれらの機能は、まさに素人の無茶振りが生んだイノベーションです。
今、世界中で「個人のわがまま」が、大企業の会議室で決まったプロダクトを凌駕する現象が起きています。
今日から始める「監督」へのロードマップ
この記事を読み終えた瞬間が、あなたのスタートラインです。
「いつかやろう」ではありません。今すぐ、以下の3ステップを踏み出してください。
STEP 1:Cursorをインストールする
まずは道具を揃えましょう。VS Codeを使っている人も、騙されたと思ってCursorに乗り換えてください。
STEP 2:「模倣」から始める
「作りたいアプリなんて思いつかない」
そんな方は、この記事の冒頭で紹介した『Stamp Factory』の仕様書をコピーしてください。
そして、Cursorにこう伝えてください。
「この仕様書に書かれているような機能を持つ、LINEスタンプ生成アプリを作りたい。まずは外枠の画面レイアウトから作って」
模倣は創造の第一歩です。AI時代の開発に、アイデアの壁はありません。
STEP 3:エラーを愛する
必ずエラーは出ます。でも、そこで「やっぱり無理だ」と思わないでください。
そのエラー画面をスクショして、AIに「直して」と言うだけです。その一言が言えれば、あなたは立派な開発者です。
最後に
冒頭でお見せした立派な「仕様書」。
あれが、アプリ完成後にAIに書かせたものだということを、最後にもう一度思い出してください。
完璧な設計図なんてなくていい。
正しい専門用語なんて知らなくていい。
泥臭く、不格好でも、AIと対話しながら一歩ずつ進めば、気づいた時にはあなたの手の中に「世界に一つだけのツール」が握られています。
さあ、監督。
次は何を作りますか?
AIという優秀なスタッフたちが、あなたの「アクション!」の声を待っています。
アプリ仕様書
「プロンプトの核心部分(=独自のノウハウ)」を抽象的な表現に書き換えた、**ブログ公開用の修正版**を作成しました。
特に、**「API仕様」にあるマーケティングテキスト生成の具体的な指示内容**は、アプリの「頭脳」にあたる部分ですので、そこを重点的にボカしています。一方で、技術的な構成(JSON形式など)は残しているため、記事としての専門性は損なわれません。
こちらをそのままコピーしてご利用ください。
-----
# Stamp Factory - アプリケーション仕様書
**バージョン**: 2.2.4
**最終更新**: 2025年12月7日
**対象OS**: Windows 10/11
-----
## 📋 目次
1. [概要]
2. [システムアーキテクチャ]
3. [機能仕様]
4. [UI/UX仕様]
5. [データ仕様]
6. [API仕様]
7. [セキュリティ仕様]
8. [パフォーマンス仕様]
9. [ビルド・デプロイ仕様]
-----
## 概要
### アプリケーション概要
**Stamp Factory**は、Google Gemini APIを活用したLINEスタンプ生成Windowsデスクトップアプリケーション。AI画像生成から背景削除、白フチ追加、テキスト編集、スタンプ管理、マーケティングテキスト生成まで、スタンプ制作のワークフロー全体をカバー。
### 主要機能
- **AI画像生成**: Gemini APIによる高品質な画像生成(2つのモード対応)
- **画像自動処理**: 背景削除・白フチ追加・リサイズの自動処理
- **テキスト編集**: キャンバス上での縦書き/横書きテキスト編集
- **スタンプ管理**: 40個のスロット管理とドラッグ&ドロップ操作
- **マーケティング支援**: AIによる販売用テキスト自動生成
- **一括エクスポート**: ZIP形式での全スタンプ一括ダウンロード
### 技術スタック
| レイヤー | 技術 | バージョン |
|---------|------|-----------|
| フロントエンド | React | 18.3.1 |
| フレームワーク | Electron | 28.2.0 |
| ビルドツール | Vite | 5.1.4 |
| スタイリング | Tailwind CSS | 3.4.1 |
| UIアイコン | Lucide React | 0.344.0 |
| キャンバス | Fabric.js | 6.9.0 |
| バックエンド | Python | 3.8+ |
| AI SDK | google-generativeai | 最新 |
| 画像処理 | Pillow, rembg, numpy, scipy | 最新 |
-----
## システムアーキテクチャ
### アーキテクチャ図
```
┌─────────────────────────────────────────────────────────┐
│ Electron Main Process │
│ - ウィンドウ管理(メイン・スタンプ管理) │
│ - IPC通信ハンドラー │
│ - Python子プロセス実行 │
│ - ファイル保存ダイアログ │
│ - APIキー暗号化保存(safeStorage) │
└────────────────┬────────────────────────────────────────┘
│ IPC通信
┌────────────────┴────────────────────────────────────────┐
│ Electron Renderer Process │
│ ┌──────────────────────────────────────────────────┐ │
│ │ React Application (App.jsx) │ │
│ │ - スタンプモード / フリー生成モード切り替え │ │
│ │ - プロンプトビルダー │ │
│ │ - 画像プレビュー │ │
│ │ - テキスト編集(Fabric.js) │ │
│ └──────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Components │ │
│ │ - PromptPanel: プロンプト構築UI │ │
│ │ - GenerationPanel: 生成パネル │ │
│ │ - FabricCanvas: テキスト編集キャンバス │ │
│ │ - SettingsPanel: 設定パネル │ │
│ │ - StatsPanel: 統計情報パネル │ │
│ │ - ConfirmModal: 確認ダイアログ │ │
│ └──────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ StampManager.jsx (別ウィンドウ) │ │
│ │ - スタンプスロット管理(40個) │ │
│ │ - Main/Tab画像管理 │ │
│ │ - ドラッグ&ドロップ機能 │ │
│ │ - マーケティングアシスタント │ │
│ └──────────────────────────────────────────────────┘ │
└────────────────┬────────────────────────────────────────┘
│ 子プロセス実行
┌────────────────┴────────────────────────────────────────┐
│ Python Processing Layer │
│ ┌──────────────────────────────────────────────────┐ │
│ │ engine.py (画像生成エンジン) │ │
│ │ - Gemini API呼び出し │ │
│ │ - Image-to-Image生成 │ │
│ │ - 背景削除(rembg) │ │
│ │ - 白フチ追加(scipy + numpy) │ │
│ │ - リサイズ処理(Pillow) │ │
│ │ - ふきだし背景白化処理 │ │
│ └──────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ text_generator.py (テキスト生成エンジン) │ │
│ │ - Gemini API呼び出し │ │
│ │ - 画像分析(最大5枚) │ │
│ │ - マーケティングテキスト生成(JSON形式) │ │
│ │ - JSONクリーニング処理 │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
```
### プロセス間通信(IPC)
| チャネル名 | 方向 | 用途 |
|-----------|------|------|
| `generate-sticker` | Renderer → Main | スタンプ画像生成リクエスト |
| `save-image` | Renderer → Main | 画像保存ダイアログ表示 |
| `save-reference-image` | Renderer → Main | 参照画像を一時保存 |
| `open-stamp-manager` | Renderer → Main | スタンプ管理ウィンドウを開く |
| `close-stamp-manager` | Renderer → Main | スタンプ管理ウィンドウを閉じる |
| `save-api-key` | Renderer → Main | APIキーを暗号化保存 |
| `get-api-key` | Renderer → Main | 保存されたAPIキーを取得 |
| `generate-marketing-text` | Renderer → Main | マーケティングテキスト生成 |
### データフロー
#### 画像生成フロー
```
1. ユーザー入力(プロンプト、参照画像、設定)
↓
2. Renderer → IPC → Main Process
↓
3. Main Process → Python子プロセス起動(engine.py)
↓
4. engine.py:
- Gemini API呼び出し(画像生成)
- 背景削除(rembg)
- 白フチ追加(scipy/numpy)
- リサイズ(Pillow)
- Base64エンコード
↓
5. Python → Main Process(JSON形式)
↓
6. Main Process → IPC → Renderer
↓
7. Renderer: プレビュー表示・localStorage保存
```
#### マーケティングテキスト生成フロー
```
1. スタンプ管理画面でテキスト生成ボタンクリック
↓
2. Renderer: 登録済み画像(最大5枚)を取得
↓
3. Renderer → IPC → Main Process
↓
4. Main Process → Python子プロセス起動(text_generator.py)
↓
5. text_generator.py:
- 標準入力からJSON受信
- Base64画像デコード(PIL Image変換)
- Gemini API呼び出し(画像 + プロンプト)
- JSONクリーニング処理
- 標準出力にJSON出力
↓
6. Python → Main Process
↓
7. Main Process → IPC → Renderer
↓
8. Renderer: テキスト表示・編集可能
```
-----
## 機能仕様
### 1\. 画像生成機能
#### 1.1 生成モード
##### スタンプモード
- **目的**: LINEスタンプ用の画像生成
- **出力サイズ**: 370×320px(固定)
- **自動処理**:
- 背景削除(オプション、デフォルト: ON)
- 白フチ追加(3px、オプション、デフォルト: ON)
- ふきだし背景白化処理(自動)
- アスペクト比維持リサイズ
- **プロンプト拡張**: セリフ表示機能や画風調整に関するシステムプロンプトを自動追加
- **ランダムセリフ**: セリフカテゴリからランダムにセリフを追加可能
##### フリー生成モード
- **目的**: 自由な画風・サイズでの画像生成
- **アスペクト比選択**:
- 正方形(1:1): 1024×1024px
- 横長(16:9): 1408×792px
- 縦長(9:16): 792×1408px
- ワイド(2:1): 1536×768px
- **オプション**:
- 背景削除: ON/OFF選択可能(デフォルト: OFF)
- 白フチ追加: ON/OFF選択可能(デフォルト: OFF)
- **プロンプト**: ユーザープロンプトのみ使用(システムプロンプトなし)
- **temperature設定**: 1.0(高めにして多様性確保)
- **ギャラリー**: 生成画像を自動保存・一覧表示
#### 1.2 プロンプトビルダー
##### カテゴリ構成
| カテゴリ | 説明 | タグ数 |
|---------|------|--------|
| quality | 品質・画風 | 12個 |
| subject | 被写体 | 11個 |
| style | デフォルメスタイル | 6個 |
| hairStyle | 髪型 | 24個 |
| bangs | 前髪スタイル | 14個 |
| hairColor | 髪色 | 21個 |
| eyes | 目の形状 | 7個 |
| eyeColor | 瞳の色 | 10個 |
| expression | 表情 | 10個 |
| accessories | アクセサリー | 25個 |
| outfit | 服装 | 40個 |
| pose | ポーズ | 55個 |
| action | アクション | 90個以上 |
| background | 背景 | 40個 |
| effect | エフェクト | 30個 |
| dialogue | セリフ | 100個以上 |
##### タグ選択機能
- **選択方式**: クリックで選択・再クリックで解除
- **視覚的フィードバック**: 選択中のタグは青色ハイライト
- **カテゴリ折りたたみ**: 各カテゴリは折りたたみ可能
- **選択タグリスト**: 選択中のタグを一覧表示(表示/非表示切り替え可能)
- **個別削除**: 選択タグリストから個別にタグを削除可能
##### プロンプト構成
```
[ポジティブプロンプト]
quality, subject, style, hairStyle, bangs, hairColor, eyes, eyeColor,
expression, accessories, outfit, pose, action, background, effect, dialogue
[ネガティブプロンプト]
[品質維持のための標準的なネガティブプロンプトセット],
signature, watermark, username, blurry
```
#### 1.3 参照画像機能(Image-to-Image)
- **アップロード方法**:
- ドラッグ&ドロップ
- ファイル選択ダイアログ
- **対応形式**: PNG, JPEG, GIF, WebP
- **プレビュー**: アップロード後に参照画像をプレビュー表示
- **削除**: ✕ボタンで参照画像を削除
- **一時保存**: Electronメインプロセスがtempフォルダに一時保存
- **生成への影響**: キャラクターのスタイル・特徴を維持した画像生成
#### 1.4 ガチャ機能
- **目的**: ランダムなアクションを追加して多様なポーズ生成
- **動作**: `action`カテゴリからランダムに1つタグを追加
- **アイコン**: 🎲(サイコロアイコン)
- **使用シーン**: アイデアに困ったときのランダム要素追加
#### 1.5 ランダムセリフ機能(スタンプモードのみ)
- **目的**: スタンプに適したセリフを自動追加
- **カテゴリ**: `dialogue`カテゴリからランダムに選択
- **セリフ例**: 「おはよう」「ありがとう」「了解」「おつかれさま」など
- **プロンプトへの反映**: 独自のテキスト指定構文にてプロンプトに追加
#### 1.6 プリセット機能
- **保存**: 現在のプロンプト(ポジティブ・ネガティブ)を名前をつけて保存
- **読み込み**: 保存したプリセットを選択して即座に適用
- **削除**: 不要なプリセットを削除
- **保存先**: localStorage(`stampFactory_presets`)
- **データ形式**:
<!-- end list -->
```json
[
{
"name": "プリセット名",
"positive": "ポジティブプロンプト",
"negative": "ネガティブプロンプト"
}
]
```
### 2\. テキスト編集機能
#### 2.1 テキスト追加
- **方法**: キャンバス上でダブルクリック
- **初期設定**:
- フォント: M PLUS Rounded 1c
- サイズ: 40px
- 色: 白(\#FFFFFF)
- 縁取り: 黒(\#000000)、幅3px
- フォントウェイト: 900(太字)
#### 2.2 テキストスタイル調整
| プロパティ | 調整方法 | 範囲/選択肢 |
|-----------|---------|------------|
| フォントサイズ | スライダー | 10〜200px |
| 文字色 | カラーピッカー | RGB |
| 縁取り色 | カラーピッカー | RGB |
| 縁取り幅 | スライダー | 0〜20px |
| フォントウェイト | セレクトボックス | 100〜900(100刻み) |
| 背景色 | カラーピッカー + チェックボックス | RGB、ON/OFF |
| 角丸 | 固定 | 16px |
#### 2.3 縦書き/横書き機能
##### 横書きモード(デフォルト)
- **行間**: `lineHeight: 1.16`(標準)
- **表示**: 通常の横書きテキスト
- **編集**: そのまま編集可能
##### 縦書きモード
- **実装方式**: 改行挿入 + 行間調整
- **行間**: `lineHeight: 0.6`(文字を詰める)
- **文字の向き**: 正立(回転なし)
- **変換ロジック**:
```javascript
// 横書き → 縦書き
"あいう" → "あ\nい\nう"
// 縦書き → 横書き
"あ\nい\nう" → "あいう"
```
##### 切り替え動作
| 状態 | 操作 | 結果 |
|------|------|------|
| テキスト編集中 | 縦書きボタンクリック | `_isVertical: true` フラグ設定 |
| 編集終了(Esc) | - | フラグに応じて自動変換 + 行間調整 |
| 横書きテキスト選択中 | 縦書きボタンクリック | 即座に縦書きに変換 |
| 縦書きテキスト選択中 | 横書きボタンクリック | 即座に横書きに変換 |
#### 2.4 テキスト操作
- **移動**: ドラッグ&ドロップ
- **削除**: Deleteキーまたは削除ボタン
- **複製**: (現在未実装)
- **前面/背面**: (現在未実装)
#### 2.5 Undo/Redo
- **履歴管理**: 最大20ステップ
- **対応操作**:
- テキスト追加・削除
- テキスト移動
- スタイル変更
- **ショートカット**:
- Undo: Ctrl+Z
- Redo: Ctrl+Y
- **実装**: Fabric.jsの状態スナップショット管理
### 3\. スタンプ管理機能
#### 3.1 スタンプスロット構成
| スロットタイプ | 数量 | サイズ | 用途 |
|-------------|------|--------|------|
| Main画像 | 1個 | 240×240px | スタンプセットのメイン画像 |
| Tab画像 | 1個 | 96×74px | タブ表示用サムネイル |
| スタンプ画像 | 40個 | 370×320px | スタンプ本体(01〜40番) |
#### 3.2 画像登録
##### 自動登録
- **トリガー**: メイン画面で画像生成後、「スタンプ追加」ボタンをクリック
- **動作**: 空いている最若番号のスロットに自動登録
- **登録不可条件**: すべてのスロットが埋まっている場合はエラー表示
##### 手動登録(ドラッグ&ドロップ)
- **外部ファイル**: 画像ファイルを直接スロットにドロップ
- **スロット間移動**:
- Main/Tabへのドロップ: コピーモード(元画像保持)
- スタンプスロット間: 入れ替えモード(スワップ)
- **自動クロップ**: 各スロットサイズに合わせて自動クロップ
- **自動スクロール**: ドラッグ中にウィンドウ端に近づくと自動スクロール
#### 3.3 画像編集
##### スマートクロップアルゴリズム
```javascript
1. 元画像のアスペクト比を計算
2. 目標サイズのアスペクト比と比較
3. はみ出る方向を判定
4. 中央を基準にクロップ領域を計算
5. クロップ後、目標サイズにリサイズ(LANCZOS)
```
##### 削除機能
- **個別削除**: 各スロットの「✕」ボタンで削除
- **全クリア**: 「すべてクリア」ボタンですべてのスロット削除
- **確認ダイアログ**: 全クリア時は確認ダイアログ表示
#### 3.4 スタンプ管理ウィンドウ
- **開き方**: メイン画面の「スタンプ管理」ボタン
- **ウィンドウタイプ**: 別ウィンドウ(モーダルなし)
- **位置**: メインウィンドウから50px右下にオフセット
- **同期**: localStorageを介してメイン画面とリアルタイム同期
- **戻るボタン**: スタンプ管理ウィンドウからメイン画面にフォーカス
### 4\. マーケティングアシスタント機能
#### 4.1 画像分析
- **対象画像**: 登録済みスタンプ画像(最大5枚)
- **優先順位**:
1. Main画像
2. スタンプ01〜40(若い番号順)
- **送信データ**: Base64エンコードされた画像データ
- **AI処理**: Gemini APIがビジュアル特徴を分析
#### 4.2 生成内容
| フィールド | 文字数制限 | 言語 | 用途 |
|-----------|-----------|------|------|
| `title_ja` | 40字以内 | 日本語 | LINEストアタイトル(日本語) |
| `title_en` | 40文字以内 | 英語 | LINEストアタイトル(英語) |
| `desc_ja` | 80字以内 | 日本語 | 説明文(日本語) |
| `desc_en` | 160文字以内 | 英語 | 説明文(英語) |
| `tags` | - | カンマ区切り | 検索タグ |
#### 4.3 入力パラメータ
| パラメータ | 必須 | 説明 |
|-----------|------|------|
| `characterName` | 任意 | キャラクター名 |
| `concept` | 任意 | コンセプト・テーマ |
| `positivePrompt` | 任意 | 生成に使用した要素・キーワード |
#### 4.4 操作機能
- **生成**: 「テキスト生成」ボタンでAI生成開始
- **個別コピー**: 各フィールドのコピーボタンでクリップボードにコピー
- **一括コピー**: すべてのテキストを整形してコピー
- **編集**: 生成後に手動で編集可能(`contentEditable`)
- **タイムアウト**: 2分以内に応答がない場合はタイムアウトエラー
### 5\. エクスポート機能
#### 5.1 ZIP一括ダウンロード
- **ファイル名**: `stamp-factory-export-{timestamp}.zip`
- **含まれるファイル**:
```
main.png // Main画像(240×240px)
tab.png // Tab画像(96×74px)
01.png〜40.png // スタンプ画像(370×320px)
marketing-text.txt // マーケティングテキスト(生成済みの場合)
```
- **ライブラリ**: JSZip + FileSaver.js
- **エラーハンドリング**: 画像が1枚も登録されていない場合はエラー表示
#### 5.2 個別保存
- **方法**: 各スロットの「保存」ボタン
- **ダイアログ**: Electronのネイティブ保存ダイアログ
- **デフォルトファイル名**: `stamp-{番号}.png`または`main.png`/`tab.png`
- **フォーマット**: PNG(透過対応)
#### 5.3 プロジェクト保存(将来実装予定)
- **保存内容**: スタンプスロット、プリセット、設定
- **フォーマット**: JSON
- **読み込み**: 保存したプロジェクトファイルを読み込み
### 6\. プレビュー機能
#### 6.1 生成画像プレビュー
- **表示位置**: メイン画面右側パネル
- **サイズ**: 最大370×320px(スタンプモード)または可変(フリーモード)
- **操作**:
- 保存ボタン: 個別保存
- スタンプ追加ボタン: スタンプ管理に登録
- クリア: プレビューをクリア
#### 6.2 LINE風プレビュー(将来実装予定)
- **表示**: トークルーム風の背景
- **背景選択**: デフォルト/ダーク/カスタム
- **デバイスフレーム**: スマートフォン風表示
### 7\. 統計・設定機能
#### 7.1 統計情報
| 項目 | 説明 | 保存先 |
|------|------|--------|
| 今日の生成数 | 本日生成した画像枚数 | localStorage |
| 今日のコスト | 本日のAPI推定コスト | localStorage |
| 累計生成数 | 全期間の生成数 | localStorage |
| 累計コスト | 全期間のコスト | localStorage |
| 画像生成コスト | 画像生成APIのコスト | 計算 |
| テキスト生成コスト | マーケティングテキスト生成コスト | 計算 |
##### コスト計算式
```javascript
// 画像生成(入力)
const inputCost = (promptLength / 1000) * 0.075; // $0.075 per 1K chars
// 画像生成(出力) - 仮定: 1024x1024px
const outputCost = 1 * 0.3; // $0.30 per image
// マーケティングテキスト生成(入力)
const textInputCost = (promptLength / 1000) * 0.075;
// マーケティングテキスト生成(出力)
const textOutputCost = (responseLength / 1000) * 0.3;
```
#### 7.2 APIキー設定
- **入力フィールド**: パスワード形式(マスク表示)
- **記憶オプション**: チェックボックスで記憶する/しないを選択
- **デフォルト**: 記憶しない(セキュリティ優先)
- **保存方式**:
- **記憶ON**: Electron safeStorage(暗号化)に保存
- **記憶OFF**: セッション中のみメモリ保持
- **フォールバック**: 暗号化利用不可の場合はBase64エンコード(平文注意)
#### 7.3 モデル選択
- **対応モデル**:
- `gemini-3-pro-image-preview`(Nano Banana Pro)
- `gemini-2.5-flash-image`
- その他のGemini画像生成モデル
- **デフォルト**: `gemini-3-pro-image-preview`
- **自動検出**: Python側で利用可能なモデルを自動リスト表示
-----
## UI/UX仕様
### レイアウト構成
#### メイン画面
```
┌─────────────────────────────────────────────────────────────┐
│ ヘッダー │
│ [モード切替] [設定] [スタンプ管理] [統計] │
├──────────────┬────────────────────────────────────────────┤
│ │ │
│ プロンプト │ プレビュー │
│ ビルダー │ │
│ │ │
│ [カテゴリ1] │ [生成画像] │
│ [カテゴリ2] │ │
│ [カテゴリ3] │ [操作ボタン] │
│ ... │ │
│ │ │
│ [プリセット]│ │
│ [参照画像] │ │
│ [生成ボタン]│ │
└──────────────┴────────────────────────────────────────────┘
```
#### スタンプ管理画面
```
┌─────────────────────────────────────────────────────────────┐
│ ヘッダー │
│ [戻る] [全クリア] [ZIP一括DL] │
├─────────────────────────────────────────────────────────────┤
│ Main画像 (240×240) Tab画像 (96×74) │
│ ┌──────────┐ ┌────────┐ │
│ │ [画像] │ │ [画像] │ │
│ └──────────┘ └────────┘ │
├─────────────────────────────────────────────────────────────┤
│ スタンプスロット(370×320) │
│ ┌────┬────┬────┬────┬────┬────┬────┬────┐ │
│ │ 01 │ 02 │ 03 │ 04 │ 05 │ 06 │ 07 │ 08 │ │
│ ├────┼────┼────┼────┼────┼────┼────┼────┤ │
│ │ 09 │ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │ │
│ ... │
│ └────┴────┴────┴────┴────┴────┴────┴────┘ │
├─────────────────────────────────────────────────────────────┤
│ マーケティングアシスタント │
│ [キャラ名] [コンセプト] [要素] │
│ [テキスト生成] │
│ [生成結果] [コピーボタン] │
└─────────────────────────────────────────────────────────────┘
```
### カラースキーム
#### ダークテーマ
| 要素 | カラーコード | 用途 |
|------|-------------|------|
| 背景(メイン) | `#0f172a` | メイン背景 |
| 背景(パネル) | `#1e293b` | パネル背景 |
| 背景(カード) | `#334155` | カード・ボタン背景 |
| テキスト(メイン) | `#f1f5f9` | メインテキスト |
| テキスト(サブ) | `#94a3b8` | サブテキスト |
| アクセント(青) | `#3b82f6` | 選択状態・アクション |
| アクセント(緑) | `#10b981` | 成功・完了 |
| アクセント(赤) | `#ef4444` | 削除・エラー |
| グラデーション | `from-purple-600 to-pink-600` | ボタン・装飾 |
### アイコンセット(Lucide React)
| アイコン | 用途 |
|---------|------|
| `Sparkles` | 生成ボタン |
| `Download` | 保存・ダウンロード |
| `Upload` | アップロード |
| `Settings` | 設定 |
| `Package` | スタンプ管理 |
| `Trash2` | 削除 |
| `Copy` | コピー |
| `ChevronDown/Up` | 折りたたみ |
| `Grid3x3` | グリッド表示 |
| `Smartphone` | プレビュー |
| `Dices` | ガチャ |
| `Type` | テキスト編集 |
| `Palette` | カラー選択 |
### レスポンシブ対応
- **最小ウィンドウサイズ**: 1400×900px(推奨)
- **スクロール**: 縦方向スクロール対応
- **パネル折りたたみ**: 画面が狭い場合は自動折りたたみ
-----
## データ仕様
### localStorage保存データ
| キー | データ型 | 説明 |
|------|---------|------|
| `stampFactory_stamps` | JSON文字列 | スタンプスロット画像データ(Base64) |
| `stampFactory_mainImage` | Base64文字列 | Main画像 |
| `stampFactory_tabImage` | Base64文字列 | Tab画像 |
| `stampFactory_presets` | JSON文字列 | プロンプトプリセット |
| `stampFactory_stats` | JSON文字列 | 統計情報 |
| `stampFactory_freeGallery` | JSON文字列 | フリー生成ギャラリー画像 |
| `stampFactory_marketingText` | JSON文字列 | マーケティングテキスト |
#### スタンプスロットデータ構造
```json
{
"1": "data:image/png;base64,iVBORw0KGgo...",
"2": "data:image/png;base64,iVBORw0KGgo...",
...
"40": "data:image/png;base64,iVBORw0KGgo..."
}
```
#### プリセットデータ構造
```json
[
{
"name": "可愛い女の子",
"positive": "1girl, cute, smile, chibi, ...",
"negative": "[標準的なネガティブプロンプト]"
},
...
]
```
#### 統計データ構造
```json
{
"today": {
"date": "2025-12-07",
"count": 10,
"cost": 3.75
},
"total": {
"count": 150,
"cost": 56.25
},
"imageGenCost": 50.0,
"textGenCost": 6.25
}
```
### ファイルシステム保存データ
#### APIキー保存
- **保存先**: `app.getPath('userData')`(Electronのユーザーデータフォルダ)
- **ファイル名**:
- 暗号化版: `api-key.enc`
- Base64版(フォールバック): `api-key.dat`
- **暗号化**: Electron safeStorage API使用
#### 一時ファイル
- **参照画像**: `{temp}/stamp-factory/reference-{timestamp}.png`
- **クリーンアップ**: アプリ終了時またはOS側の一時ファイルクリーンアップ
-----
## API仕様
### Google Gemini API
#### 画像生成API
**エンドポイント**: `generateContent`
**モデル**: `gemini-3-pro-image-preview` または `gemini-2.5-flash-image`
##### リクエスト(テキストのみ)
```python
model = genai.GenerativeModel(model_id)
response = model.generate_content(
prompt,
generation_config={
"temperature": 0.7, # スタンプモード
# "temperature": 1.0, # フリーモード
"top_p": 0.95,
"top_k": 40,
}
)
```
##### リクエスト(Image-to-Image)
```python
response = model.generate_content(
[prompt, reference_image],
generation_config={
"temperature": 0.8,
"top_p": 0.95,
"top_k": 40,
}
)
```
##### レスポンス構造
```python
response.candidates[0].content.parts[0].inline_data.data
# → バイナリデータまたはBase64文字列
```
#### マーケティングテキスト生成API
**エンドポイント**: `generateContent`
**モデル**: 自動選択(`gemini-1.5-flash`優先)
##### リクエスト(画像あり)
```python
content_parts = [image1, image2, ..., prompt]
response = model.generate_content(content_parts)
```
##### プロンプトテンプレート
```text
[ここに、スタンプ画像の特徴(表情、色使い、雰囲気など)を分析し、
LINEストアでの販売に最適化されたタイトル・説明文を生成するための
開発者独自のシステムプロンプト(指示命令)が入ります]
入力パラメータ:
- キャラ名: {characterName}
- コンセプト: {concept}
- 要素: {positivePrompt}
出力制約:
- 以下のJSON形式のみで出力すること
- 各フィールドの文字数制限を厳守すること
- 日本語および英語の自然な翻訳を含めること
```
##### レスポンス
```json
{
"success": true,
"data": {
"title_ja": "かわいい猫ちゃんスタンプ",
"title_en": "Cute Cat Sticker",
"desc_ja": "毎日使えるかわいい猫ちゃんのスタンプです。",
"desc_en": "Cute cat stickers for everyday use.",
"tags": "猫,かわいい,動物,日常"
}
}
```
### IPC API(Electron)
#### `generate-sticker`
**用途**: スタンプ画像生成
**リクエスト**:
```javascript
{
prompt: string,
referenceImagePath: string | null,
apiKey: string,
modelId: string,
width: number | null, // フリーモードのみ
height: number | null, // フリーモードのみ
enableBgRemoval: boolean, // true/false
enableWhiteBorder: boolean // true/false
}
```
**レスポンス**:
```javascript
{
success: true,
imageBase64: "data:image/png;base64,..."
}
// または
{
success: false,
error: "エラーメッセージ"
}
```
#### `generate-marketing-text`
**用途**: マーケティングテキスト生成
**リクエスト**:
```javascript
{
apiKey: string,
characterName: string,
concept: string,
positivePrompt: string,
images: string[] // Base64画像データの配列(最大5枚)
}
```
**レスポンス**:
```javascript
{
success: true,
data: {
title_ja: string,
title_en: string,
desc_ja: string,
desc_en: string,
tags: string
}
}
```
-----
## セキュリティ仕様
### APIキー保護
#### 暗号化保存(推奨)
- **暗号化方式**: Electron safeStorage API(OS標準の暗号化機能を使用)
- Windows: DPAPI(Data Protection API)
- macOS: Keychain
- Linux: libsecret
- **保存ファイル**: `api-key.enc`(バイナリ)
- **復号化**: アプリ起動時に自動復号化
#### フォールバック(Base64)
- **条件**: safeStorageが利用不可の場合
- **エンコード**: Base64エンコード(**平文と同等、注意**)
- **保存ファイル**: `api-key.dat`(テキスト)
- **警告**: 共用PC・セキュリティ重視の場合は「記憶しない」オプション推奨
### コマンドインジェクション対策
⚠️ エリートAIの強制要約:
結論:コマンドインジェクション対策とは、外部入力値をOSシェルに直接渡さず、安全なAPIの利用や厳格なエスケープにより不正なシステムコマンド実行を防ぐセキュリティ手法です。
- OSコマンド呼び出しの回避:シェル経由の実行関数(system、exec等)を廃止し、言語標準のセキュアなAPIやライブラリへ置き換える。
- 入力値の厳格な検証:外部パラメーターに対してホワイトリスト方式で文字種を制限し、危険なメタ文字は完全に無害化・エスケープする。
- 最小権限の原則:万が一の侵入に備え、Webサーバーや実行プロセスのOS権限を最小限に絞り、権限昇格や横展開の被害を防ぐ。
#### サニタイゼーション関数
```javascript
function sanitizeCommandArgument(arg) {
if (typeof arg !== 'string') {
return String(arg);
}
// 危険な文字を検出(Windows環境)
const dangerousChars = /[&|;<>$`\n\r]/g;
if (dangerousChars.test(arg)) {
console.warn('[Security] Potentially dangerous characters detected');
return arg.replace(dangerousChars, '');
}
return arg;
}
```
#### 子プロセス実行
- **shell: false**: cmd.exeを経由せず直接実行
- **引数配列**: コマンドと引数を分離して渡す
- **パス検証**: 実行ファイルの存在確認
### データ保護
- **localStorage**: クライアント側のみ、外部送信なし
- **APIキー送信**: Gemini APIへの送信時のみHTTPS通信
- **画像データ**: Base64エンコード、ローカル保存のみ
-----
## パフォーマンス仕様
### 画像処理最適化
#### Base64エンコード
- **目的**: DOM表示・localStorage保存の効率化
- **タイミング**: Python側でエンコード済みのデータを受信
- **サイズ**: 約33%増(バイナリ → Base64変換)
#### スマートクロップ
- **アルゴリズム**: 中央基準のクロップ + LANCZOS リサンプリング
- **処理時間**: 100ms以下(通常)
- **キャッシュ**: なし(都度計算)
### UI最適化
#### レンダリング最適化
- **React.memo**: 不要な再レンダリングを防止
- **useCallback**: 関数の再生成を防止
- **debounce**: 入力処理の最適化(未実装)
#### 大量データ処理
- **タグ表示**: すべてのタグを一度に表示(仮想スクロールなし)
- **スタンプスロット**: 40個すべてを一度にレンダリング
- **ギャラリー**: フリー生成モードの画像をすべて表示
### タイムアウト設定
| 処理 | タイムアウト | 理由 |
|------|------------|------|
| 画像生成 | なし | ユーザー待機 |
| マーケティングテキスト生成 | 2分(120秒) | 画像処理のため延長 |
| Python子プロセス起動 | なし | エラーハンドリングで対応 |
-----
## ビルド・デプロイ仕様
### 開発環境
#### 環境構築
```bash
# Node.js依存関係
npm install
# Python依存関係
pip install -r requirements.txt
```
#### 開発サーバー起動
```bash
# Viteサーバー起動(デフォルト: http://localhost:5173)
npm run dev
# Electronアプリ起動(開発モード)
npm run electron:dev
```
### 本番ビルド
#### Pythonスクリプトのビルド
**ツール**: PyInstaller
**ビルドスクリプト**: `scripts/build-python.js`
**出力**:
- `py_dist/stamp_engine.exe`
- `py_dist/stamp_text_generator.exe`
**ビルドコマンド**:
```bash
npm run build:python # 通常ビルド(既存EXEがあればスキップ)
npm run build:python:force # 強制リビルド
```
**PyInstallerオプション**:
```bash
pyinstaller --onefile --windowed --name stamp_engine python/engine.py
pyinstaller --onefile --windowed --name stamp_text_generator python/text_generator.py
```
#### Reactアプリのビルド
**ツール**: Vite
**ビルドコマンド**:
```bash
npm run build
```
**出力先**: `dist/`
**含まれるファイル**:
- `index.html`
- `assets/`(JS、CSS、画像)
#### Electronパッケージング
**ツール**: electron-builder
**ビルドコマンド**:
```bash
# Python EXE + React + Electronを一括ビルド
npm run build:win
# 完全リビルド(Python EXEも強制再ビルド)
npm run build:win:full
```
**出力先**: `dist/`(electron-builder出力)
**インストーラー**:
- `Stamp-Factory-Setup-{version}.exe`(NSISインストーラー)
**設定**(`package.json`):
```json
{
"build": {
"appId": "com.stampfactory.app",
"productName": "Stamp Factory",
"files": [
"dist/**/*",
"electron/**/*",
"node_modules/**/*"
],
"extraResources": [
{
"from": "py_dist/stamp_engine.exe",
"to": "stamp_engine.exe"
},
{
"from": "py_dist/stamp_text_generator.exe",
"to": "stamp_text_generator.exe"
}
],
"win": {
"target": "nsis",
"icon": "assets/icon.ico"
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true
}
}
}
```
### バージョン管理
#### バージョン番号
- **フォーマット**: `{major}.{minor}.{patch}`
- **現在**: `2.2.4`
- **自動インクリメント**: `scripts/bump-version.js`(ビルド時に自動実行)
#### バージョンアップルール
- **major**: 破壊的変更、大規模リファクタリング
- **minor**: 新機能追加
- **patch**: バグフィックス、軽微な改善
### デプロイ
#### 配布方法
1. **GitHubリリース**: リリースページにインストーラーを添付
2. **直接配布**: `Stamp-Factory-Setup-{version}.exe`を配布
#### インストール
1. `Stamp-Factory-Setup-{version}.exe`をダブルクリック
2. インストール先を選択
3. インストール完了
4. デスクトップショートカットまたはスタートメニューから起動
#### アンインストール
- Windowsの「設定」→「アプリ」→「Stamp Factory」→「アンインストール」
-----
## トラブルシューティング
### よくある問題
#### Pythonスクリプトが実行できない
**症状**: 画像生成時にエラー「Pythonスクリプトの実行に失敗しました」
**原因**:
- Python 3.8+がインストールされていない
- `py`コマンドがパスに通っていない(開発環境)
- Python EXEが同梱されていない(本番環境)
**解決策**:
- Python 3.8以上をインストール
- `npm run build:python:force`で強制リビルド
- `py_dist/`フォルダの存在確認
#### rembgがインストールできない
**症状**: `pip install rembg`でエラー
**解決策**:
```bash
pip install rembg[new]
```
#### 画像生成が失敗する
**症状**: 「画像生成に失敗しました」エラー
**原因**:
- APIキーが無効
- モデルIDが間違っている
- インターネット接続の問題
- Gemini APIの利用制限
**解決策**:
- APIキーを確認・再入力
- モデルIDを`gemini-3-pro-image-preview`または`gemini-2.5-flash-image`に変更
- インターネット接続を確認
- Gemini APIの利用制限を確認
#### APIキーが保存されない
**症状**: アプリを再起動するとAPIキーが消える
**原因**:
- 「APIキーを記憶する」チェックボックスがOFF
- safeStorageが利用不可でフォールバックも失敗
**解決策**:
- 「APIキーを記憶する」にチェックを入れる
- ユーザーデータフォルダの書き込み権限を確認
#### スタンプ管理ウィンドウが表示されない
**症状**: 「スタンプ管理」ボタンをクリックしても何も起こらない
**原因**:
- preload.jsが正しく読み込まれていない
- IPCハンドラーのエラー
**解決策**:
- 開発者ツール(F12)でエラーログを確認
- アプリを再起動
-----
## 付録
### 依存関係一覧
#### Node.js依存関係(`package.json`)
**本番依存関係**:
- `fabric@6.9.0`: キャンバスベースのテキスト編集
- `file-saver@2.0.5`: ファイル保存
- `jszip@3.10.1`: ZIP圧縮
- `lucide-react@0.344.0`: アイコンセット
- `react@18.3.1`: UIフレームワーク
- `react-dom@18.3.1`: ReactのDOM操作
**開発依存関係**:
- `@vitejs/plugin-react@4.3.1`: React用Viteプラグイン
- `autoprefixer@10.4.18`: CSSベンダープレフィックス自動付与
- `cross-env@7.0.3`: クロスプラットフォーム環境変数
- `electron@28.2.0`: Electronフレームワーク
- `electron-builder@24.9.1`: Electronパッケージング
- `postcss@8.4.35`: CSS処理ツール
- `tailwindcss@3.4.1`: CSSフレームワーク
- `vite@5.1.4`: ビルドツール
- `vite-plugin-electron@0.28.1`: Electron用Viteプラグイン
- `vite-plugin-electron-renderer@0.14.5`: Electronレンダラー用Viteプラグイン
#### Python依存関係(`requirements.txt`)
```
google-generativeai
Pillow
rembg
numpy
scipy
```
### ディレクトリ構造
```
Stamp Factory powered by Gemini/
├── assets/ # アセット(アイコンなど)
│ └── icon.png/icon.ico
├── electron/ # Electronメインプロセス
│ ├── main.js # メインプロセススクリプト
│ └── preload.js # プリロードスクリプト
├── python/ # Pythonスクリプト
│ ├── engine.py # 画像生成エンジン
│ ├── text_generator.py # テキスト生成エンジン
│ ├── list_models.py # モデルリスト表示
│ └── requirements.txt # Python依存関係
├── py_dist/ # Python EXE出力先(ビルド後)
│ ├── stamp_engine.exe
│ └── stamp_text_generator.exe
├── scripts/ # ビルドスクリプト
│ ├── build-python.js # Pythonビルドスクリプト
│ ├── bump-version.js # バージョン自動インクリメント
│ └── clean-build.js # ビルドクリーンアップ
├── src/ # Reactソースコード
│ ├── components/ # Reactコンポーネント
│ │ ├── ConfirmModal.jsx # 確認ダイアログ
│ │ ├── FabricCanvas.jsx # テキスト編集キャンバス
│ │ ├── GenerationPanel.jsx # 生成パネル
│ │ ├── PromptPanel.jsx # プロンプトパネル
│ │ ├── SettingsPanel.jsx # 設定パネル
│ │ └── StatsPanel.jsx # 統計情報パネル
│ ├── utils/ # ユーティリティ
│ │ └── logger.js # ロガー
│ ├── App.jsx # メインアプリコンポーネント
│ ├── StampManager.jsx # スタンプ管理コンポーネント
│ ├── main.jsx # エントリーポイント
│ ├── index.css # グローバルスタイル
│ └── electron.d.ts # TypeScript型定義
├── dist/ # ビルド出力(Vite + electron-builder)
├── node_modules/ # Node.js依存関係
├── index.html # HTMLテンプレート
├── package.json # Node.jsパッケージ設定
├── vite.config.js # Vite設定
├── tailwind.config.js # Tailwind CSS設定
├── requirements.txt # Python依存関係(トップレベル)
├── README.md # 使い方ガイド
├── FEATURES.md # 機能一覧
├── SPECIFICATION.md # 本仕様書
└── *.md # リリースノート、修正ドキュメント
```
### キーボードショートカット
| ショートカット | 機能 |
|--------------|------|
| `Ctrl+Z` | Undo(元に戻す) |
| `Ctrl+Y` | Redo(やり直す) |
| `Delete` | 選択中のテキストを削除 |
| `Esc` | テキスト編集を終了 |
| `F12` | 開発者ツールを開く(開発モード) |
### 対応ファイル形式
#### 画像入力
- PNG
- JPEG/JPG
- GIF
- WebP
#### 画像出力
- PNG(透過対応)
#### テキスト出力
- TXT(マーケティングテキスト)
- JSON(プロジェクト保存、将来実装)
-----
## 変更履歴
| バージョン | 日付 | 変更内容 |
|-----------|------|---------|
| 2.2.4 | 2025-12-07 | 仕様書初版作成 |
| 2.2.0 | 2025-11-XX | 縦書き機能実装 |
| 2.1.7 | 2025-11-XX | UI/UX大幅改善 |
| 2.1.0 | 2025-10-XX | フリー生成モード追加 |
| 1.0.0 | 2025-XX-XX | 初回リリース |
-----
**Document Version**: 1.0
**Author**: Stamp Factory Development Team
**Last Updated**: 2025年12月7日
💡 Frequently Asked Questions (FAQ)
Q. Can someone with zero programming knowledge build a custom LINE sticker generator using Cursor?
A. Yes. As detailed in the development log, even creators who stopped at basic coding concepts like ‘Hello World’ can develop advanced applications by leveraging the AI-powered IDE Cursor alongside detailed specification documents. Cursor acts as an autonomous pair programmer, translating natural language instructions, architecture outlines, and functional requirements into working code. By preparing comprehensive technical specifications (such as Specification v2.2.3 described in the guide) and feeding structured prompts into Cursor, non-engineers can overcome technical roadblocks that would normally require years of full-stack engineering expertise.
Q. Why is a detailed specification document essential when developing applications with AI like Cursor?
A. A detailed specification document serves as the single source of truth for AI-driven development. While Cursor excels at writing and debugging code, it relies entirely on precise context to maintain architectural consistency and avoid hallucinated dependencies. Providing a versioned specification—such as Specification v2.2.3—outlines the exact data flow, UI/UX logic, API integrations, and asset formatting required for LINE stickers. This upfront clarity drastically reduces code regressions, ensures seamless prompt generation, and allows Cursor to accurately implement complex features without derailing the project.






















この記事へのコメントはありません。