0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Flutter で画像に手書き・図形描画・回転を加える — image_painter_rotate

0
Last updated at Posted at 2026-03-04

はじめに

Flutter アプリで画像にアノテーション(手書きや図形)を追加したい場面があります。
たとえば写真への注釈付け、署名機能、図面への書き込みなどです。

image_painter_rotate は、画像の上に直接描画できる Flutter パッケージです。
人気パッケージ image_painter をフォークし、画像の回転対応・描画オブジェクトの選択移動・削除などの機能を追加した強化版です。

デモ


元パッケージとの違い

機能 image_painter(原作) image_painter_rotate(本パッケージ)
基本描画ツール
画像の回転(quarterTurns)
描画オブジェクトの選択・移動
描画オブジェクトの削除(長押し)

インストール

# pubspec.yaml
dependencies:
  image_painter_rotate: ^1.1.0
import 'package:image_painter_rotate/image_painter_rotate.dart';

描画モード

7種類の描画モードに対応しています。

モード 内容
Line 直線
Box / Rectangle 矩形
Circle
Freestyle / Signature フリーハンド・署名
Dotted Line 点線
Arrow 矢印
Text テキスト

基本的な使い方

コントローラーの初期化

final controller = ImagePainterController();

画像の読み込み

ネットワーク画像、アセット、ファイル、メモリバイトの4種類に対応しています。

// ネットワーク画像
ImagePainter.network(
  'https://example.com/sample.png',
  controller: controller,
  scalable: true,
)

// アセット画像
ImagePainter.asset(
  'assets/sample.png',
  controller: controller,
)

// ファイル
ImagePainter.file(
  File('path/to/image.png'),
  controller: controller,
)

// メモリ(Uint8List)
ImagePainter.memory(
  imageBytes,
  controller: controller,
)

画像の回転(quarterTurns)

本パッケージの追加機能のひとつが quarterTurns パラメータです。
画像を90度単位で回転させた状態で表示・描画できます。

ImagePainter.network(
  'https://example.com/photo.png',
  controller: controller,
  scalable: true,
  quarterTurns: 1, // 0=0°, 1=90°, 2=180°, 3=270°
)

カメラで撮影した画像など、向きが異なる画像をそのまま扱えるため、回転補正のために画像を加工する手間が省けます。


描画オブジェクトの選択・移動

v1.0.0 で追加された機能です。
一度描画したオブジェクトをタップして選択し、ドラッグで移動できます。
選択中のオブジェクトはアニメーション付きのボーダーで表示されます。
空白エリアをタップすると選択が解除されます。


描画オブジェクトの削除

v1.1.0 で追加された機能です。
描画済みのオブジェクトを長押しすると削除メニューが表示され、特定のオブジェクトだけを削除できます。


画像のエクスポート

描画後の画像を Uint8List として取得できます。
ファイル保存やアップロードに活用できます。

// ボタン押下時に画像をエクスポート
ElevatedButton(
  onPressed: () async {
    final Uint8List? imageBytes = await controller.exportImage();
    if (imageBytes != null) {
      // ファイルに保存
      await File('path/output.png').writeAsBytes(imageBytes);
    }
  },
  child: const Text('保存'),
)

アンドゥ・クリア

// 直前の操作を元に戻す
controller.undo();

// すべての描画をクリア
controller.clearAll();

実装例:写真アノテーション画面

class AnnotationScreen extends StatefulWidget {
  const AnnotationScreen({super.key, required this.imageUrl});
  final String imageUrl;

  @override
  State<AnnotationScreen> createState() => _AnnotationScreenState();
}

class _AnnotationScreenState extends State<AnnotationScreen> {
  final _controller = ImagePainterController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('アノテーション'),
        actions: [
          IconButton(
            icon: const Icon(Icons.undo),
            onPressed: _controller.undo,
          ),
          IconButton(
            icon: const Icon(Icons.delete_sweep),
            onPressed: _controller.clearAll,
          ),
          IconButton(
            icon: const Icon(Icons.save),
            onPressed: _exportImage,
          ),
        ],
      ),
      body: ImagePainter.network(
        widget.imageUrl,
        controller: _controller,
        scalable: true,
      ),
    );
  }

  Future<void> _exportImage() async {
    final bytes = await _controller.exportImage();
    if (bytes == null) return;

    // bytes をファイル保存・アップロード等で使用
    debugPrint('exported: ${bytes.length} bytes');
  }
}

対応プラットフォーム

プラットフォーム 対応
iOS
Android
macOS
Windows
Linux
Web

まとめ

image_painter_rotate を使うことで、以下の機能を Flutter アプリに手軽に組み込めます。

  • 7種類の描画ツール(直線・矩形・円・フリーハンド・点線・矢印・テキスト)
  • 画像の回転表示(quarterTurns)
  • 描画オブジェクトの選択・移動・削除
  • アンドゥ・クリア・画像エクスポート

画像へのアノテーション機能が必要な場合にぜひ活用してみてください。


リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?