画像アノテーション:ペン、矢印、円形ツールで画像をマークアップ
この章で学べること
- ✅ プランレビューまたはコードレビューで画像を添付する
- ✅ ペンツールで自由に描画する
- ✅ 矢印ツールで重要な箇所を指し示す
- ✅ 円形ツールで領域を囲む
- ✅ アノテーションの色とストロークサイズを調整する
- ✅ ショートカットキーでツールを素早く切り替える
現在の課題
課題1:UIデザインやフローチャートをレビューする際、テキストだけでは直感的に伝わらず、問題箇所を囲んで示したい。
課題2:コードレビューにスクリーンショットを添付したいが、「ここに問題がある」とテキストで説明するしかなく、画像上に直接マークできない。
課題3:チームから共有された画像リンクに素早くフィードバックを付けたいが、ローカルにダウンロードして別のツールで処理するのは面倒。
Plannotatorでできること:
- ブラウザ上で直接画像をマークアップ、ダウンロード不要
- ペン、矢印、円形の3つのツールであらゆるマークアップシーンに対応
- 5色のカラーと5段階のストロークサイズで柔軟に調整
- ショートカットキーで効率的に操作
こんなときに使う
適した使用シナリオ:
- UIデザイン、フローチャート、アーキテクチャ図のレビューで問題箇所をマークしたい
- コードレビューでスクリーンショットを撮り、コードの問題箇所をマークしたい
- マークアップ付きの画像をチームメンバーに共有したい
- 画像上で重要な領域を囲んだり、矢印で指し示したい
🎒 始める前の準備
前提条件
このチュートリアルでは、以下を完了していることを前提としています:
コアコンセプト
画像アノテーションの3つのツール:
| ツール | アイコン | ショートカット | 用途 |
|---|---|---|---|
| ペン | 🖊️ | 1 | 自由描画、手書きメモや任意の形状を描くのに最適 |
| 矢印 | ➡️ | 2 | 重要な箇所を指し示す、ポイントtoポイントのマークに最適 |
| 円形 | ⭕ | 3 | 領域を囲む、特定の要素を強調するのに最適 |
ワークフロー:
画像をアップロード → ツールを選択 → 色とサイズを調整 → 画像上に描画 → 保存ステップバイステップ
ステップ1:プランレビューまたはコードレビュー画面を開く
なぜ Plannotatorの画像アノテーション機能は、プランレビューとコードレビューに統合されています。
操作
- プランレビューを起動(Claude Codeのトリガーまたは OpenCodeの submit_plan 呼び出し)
- または
/plannotator-reviewコマンドでコードレビューを起動
期待される結果:
- ブラウザでレビュー画面が開く
- 右上に「Upload」または「添付」ボタンがある
ステップ2:画像をアップロード
なぜ マークアップするには、まず画像をアップロードする必要があります。
操作
- ページ右上の「Upload」または「添付」ボタンをクリック
- マークアップしたい画像を選択(PNG、JPEG、WebP形式に対応)
- アップロード後、画像がアノテーションリストに表示される
期待される結果:
- 画像のサムネイルがアノテーションエリアに表示される
- サムネイルをクリックするとマークアップエディタが開く
画像の取得方法
以下の方法で画像を取得できます:
- スクリーンショットを撮ってペースト(Ctrl+V / Cmd+V)
- ローカルファイルから選択
- 画像をページにドラッグ&ドロップ
ステップ3:画像アノテーションエディタを開く
なぜ マークアップエディタには描画ツールとカラー選択機能があります。
操作
- アップロードした画像のサムネイルをクリック
- 画像アノテーションエディタがポップアップで開く
期待される結果:
- 画像が中央に表示される
- 上部にツールバーがある
- ツールバーの構成(左から右):ツール選択、ストロークサイズ、カラー選択、元に戻す、クリア、保存
ステップ4:ペンツールで自由に描画
なぜ ペンツールは手書きメモや任意の形状を描くのに最適です。
操作
- ペンツール(🖊️ アイコン)が選択されていることを確認(デフォルトで選択済み)
- マウスの左ボタンを押しながら画像上に描画
- マウスを離すと描画が完了
期待される結果:
- マウスの動きに追従する線が描かれる
- マウスを離すと、描いた形状が画像上に固定される
ペンツールの特徴
- perfect-freehand ライブラリによる滑らかな手描き効果
- 圧力感知に対応(デバイスがサポートしている場合)
- ストロークが太いほど、線が滑らかになる
ステップ5:矢印ツールで重要な箇所を��ーク
なぜ 矢印はポイントtoポイントのマークに最適で、問題箇所を明確に指し示せます。
操作
- 矢印ツール(➡️ アイコン)をクリック、またはショートカットキー
2を押す - 画像上でクリックして矢印の始点を決定
- 目標位置までドラッグし、マウスを離して矢印を完成
期待される結果:
- 始点から終点への直線が描かれる
- 終点に矢印の先端があり、目標位置を指している
矢印描画のコツ
- 始点は矢印の尾部、終点は矢印の先端
- ドラッグ中に矢印の方向をリアルタイムでプレビュー可能
- 「ここに問題がある」「ここを修正して」などのシーンに最適
ステップ6:円形ツールで領域を囲む
なぜ 円形は特定の要素を強調し、範囲を明確に示すのに最適です。
操作
- 円形ツール(⭕ アイコン)をクリック、またはショートカットキー
3を押す - 画像上でクリックして円の一辺を決定
- 反対側までドラッグし、マウスを離して円を完成
期待される結果:
- 始点から終点を結ぶ線が直径となる円が描かれる
- 円の中心は2点を結ぶ線の中点
円形描画の仕組み
円形ツールは端から端へ描画します:
- 1回目のクリック:円の一辺
- ドラッグ:円の直径を決定
- 離す:円の描画が完了
ソースコード実装(utils.ts:95-124):
// 中心は始点と終点の中点
const cx = (x1 + x2) / 2;
const cy = (y1 + y2) / 2;
// 半径は2点間の距離の半分
const radius = Math.hypot(x2 - x1, y2 - y1) / 2;ステップ7:アノテーションの色を調整
なぜ 異なる色でアノテーションの種類を区別できます(例:赤はエラー、緑は提案)。
操作
- ツールバーのカラードットをクリック
- 選択可能な色:赤、黄、緑、青、白
期待される結果:
- 現在選択中のカラードットが拡大表示される
- 新しく描くアノテーションはすべて現在の色が適用される
色の使い分けの提案
- 赤:エラー、問題、削除すべき内容
- 黄:警告、注意、確認が必要な箇所
- 緑:提案、最適化、改善案
- 青:補足説明、メモ
- 白:暗い背景の画像に最適
ステップ8:ストロークサイズを調整
なぜ 異なるサイズのストロークは、異なるマークアップシーンに適しています。
操作
- ツールバーの
-または+ボタンをクリック - 現在のストロークサイズのプレビュー(ドット)を確認
期待される結果:
- ストロークサイズの選択肢:3、6、10、16、24
- ツールバー中央に現在のストロークサイズのプレビュードットが表示される
ストロークサイズの目安
- 3:小さな要素(ボタン、アイコンなど)の精密なマーク
- 6:通常のマーク(デフォルト値)
- 10:太い線でのマーク、大きな領域を囲むのに最適
- 16:非常に太いマーク、重要な箇所を強調するのに最適
- 24:最大のストローク、超大型の領域を強調するのに最適
ステップ9:元に戻すとクリア
なぜ マークアップ中にミスは避けられないため、元に戻すか最初からやり直す必要があります。
操作
- 元に戻す:元に戻すアイコン(↩️)をクリック、または
Cmd+Z/Ctrl+Z - すべてクリア:クリアアイコン(❌)をクリック
期待される結果:
- 元に戻す:最後に描いたアノテーションが消える
- クリア:すべてのアノテーシ��ンが削除され、元の画像に戻る
クリアに関する注意
クリア操作は元に戻せません。慎重に使用してください。まずは元に戻すで段階的に戻すことをお勧めします。
ステップ10:アノテーションを保存
なぜ 保存すると、画像がアノテーションと統合され、レビューで確認できるようになります。
操作
- ツールバー右側の保存アイコン(✅)をクリック
- または
EscまたはEnterキーを押す - またはポップアップの外側をクリック
期待される結果:
- ポップアップが閉じる
- 画像のサムネイルがマークアップ後のバージョンに更新される
- 画像が現在のアノテーションに添付される
保存の仕組み
- アノテーションを描いていない場合、元の画像がそのまま保存される
- アノテーションがある場合、元の画像とアノテーションが1枚の新しい画像に統合される
- 統合された画像はPNG形式で保存され、高品質を維持
チェックポイント ✅
学習成果を確認:
- [ ] レビュー画面に画像をアップロードできる
- [ ] ペン、矢印、円形の3つのツールでマークアップできる
- [ ] アノテーションの色とストロークサイズを調整できる
- [ ] ショートカットキー(1/2/3、Cmd+Z、Esc)で素早く操作できる
- [ ] 間違ったアノテーションを元に戻せる
- [ ] マークアップ後の画像を保存できる
よくあるトラブル
問題1:矢印の方向が逆になった
現象:矢印が間違った方向を指している。
原因:矢印ツールは始点(尾部)から終点(先端)へ描画します。
解決方法:
- 再度描画し、始点が矢印の尾部、終点が矢印の先端になるようにする
- すでに描いた場合は、元に戻してから再描画
問題2:円形の位置がずれた
現象:円形が目標の領域を囲んでいない。
原因:円形ツールは端から端へ描画し、中心は2点の中点になります。
解決方法:
- 最初のクリックを目標領域の端で行う
- 反対側までドラッグし、目標領域が円内に収まるようにする
- 調整が必要な場合は元に戻して再描画
問題3:ストロークが太すぎる/細すぎる
現象:マークアップの見た目が理想的でない。
原因:ストロークサイズが現在のシーンに適していない。
解決方法:
- ツールバーの
-または+ボタンでストロークサイズを調整 - 小さな要素には3-6、大きな領域には10-24を使用
問題4:色が見えにくい
現象:暗い背景で黒いストロークを使用すると、マークアップが見えない。
原因:色の選択が不適切。
解決方法:
- 暗い背景には白または黄色を使用
- 明るい背景には赤、緑、または青を使用
ショートカットキー一覧
| ショートカット | 機能 |
|---|---|
1 | ペンツールに切り替え |
2 | 矢印ツールに切り替え |
3 | 円形ツールに切り替え |
Cmd+Z / Ctrl+Z | 元に戻す |
Esc / Enter | アノテーションを保存 |
この章のまとめ
この章で学んだこと:
- 画像のアップロード:アップロードボタンまたはペーストでレビュー画面に追加
- 3つのマークアップツール:
- ペン(1):自由描画、手書きメモに最適
- 矢印(2):ポイントtoポイントのマーク、重要な箇所を指し示すのに最適
- 円形(3):領域を囲む、強調表示に最適
- マークアップスタイルの調整:5色のカラー、5段階のストロークサイズ
- 元に戻すとクリア:間違ったマークアップを修正
- アノテーションの保存:マークアップを画像に統合
次の章の予告
次の章では**コードレビュー基礎**を学びます。
学べる内容:
- /plannotator-review コマンドで git diff をレビューする方法
- side-by-side と unified ビューの切り替え
- 行番号をクリックしてコード範囲を選択
- 行レベルのアノテーション(comment/suggestion/concern)を追加
- 異なる diff タイプの切り替え
- フィードバックを AI Agent に送信
付録:ソースコード参照
クリックしてソースコードの場所を表示
更新日:2026-01-24
| 機能 | ファイルパス | 行番号 |
|---|---|---|
| ツールタイプ定義 | packages/ui/components/ImageAnnotator/types.ts | 1-40 |
| レンダリング関数 | packages/ui/components/ImageAnnotator/utils.ts | 1-148 |
| メインコンポーネント | packages/ui/components/ImageAnnotator/index.tsx | 1-233 |
| ツールバーコンポーネント | packages/ui/components/ImageAnnotator/Toolbar.tsx | 1-219 |
| Annotation インターフェース | packages/ui/types.ts | 11-33 |
主要な型:
Tool(ツールタイプ):
export type Tool = 'pen' | 'arrow' | 'circle';Point(座標点):
export interface Point {
x: number;
y: number;
pressure?: number;
}Stroke(ストローク):
export interface Stroke {
id: string;
tool: Tool;
points: Point[];
color: string;
size: number;
}AnnotatorState(アノテーターの状態):
export interface AnnotatorState {
tool: Tool;
color: string;
strokeSize: number;
strokes: Stroke[];
currentStroke: Stroke | null;
}COLORS(カラー配列):
export const COLORS = [
'#ef4444', // red
'#eab308', // yellow
'#22c55e', // green
'#3b82f6', // blue
'#ffffff', // white
] as const;STROKE_SIZES(ストロークサイズ):
const STROKE_SIZES = [3, 6, 10, 16, 24];主要な関数:
renderPenStroke()(ペンストロークのレンダリング):
- perfect-freehand ライブラリで滑らかな手描き効果を実現
- 圧力感知に対応(pressure フィールド)
renderArrow()(矢印のレンダリング):
- 始点から終点への直線を描画
- 終点に矢印の先端を描画
renderCircle()(円形のレンダリング):
- 2点の中点を円の中心として計算
- 2点間の距離の半分を半径として計算
renderStroke()(ツールタイプに応じたレンダリング):
- tool フィールドに応じて対応するレンダリング関数を呼び出し
- スケーリングに対応(scale パラメータ)
Annotation.imagePaths(添付画像フィールド):
export interface Annotation {
// ...
imagePaths?: string[]; // Attached images (local paths or URLs)
}ショートカットキー処理(index.tsx:33-59):
// 1/2/3 to switch tools
if (e.key === '1') setState(s => ({ ...s, tool: 'pen' }));
if (e.key === '2') setState(s => ({ ...s, tool: 'arrow' }));
if (e.key === '3') setState(s => ({ ...s, tool: 'circle' }));
// Cmd+Z to undo
if ((e.metaKey || e.ctrlKey) && e.key === 'z') {
e.preventDefault();
handleUndo();
}