Flutterアプリ開発で
- 画像にぼかしを入れたい
- セピアやグレースケールなどのフィルターを適用したい
- 画像の明るさやコントラストを調整したい
- 一部分だけにエフェクトを適用したい
- 大きな画像をリサイズしたい
- 画像処理をできるだけ高速に実行したい
といったケースはよくあります。
Flutterで画像処理を行う場合、Dart側ですべてのピクセルを処理すると、画像サイズによってはパフォーマンスに影響する可能性があります。
そんなときに注目したいのが fast_image_editor パッケージです。
fast_image_editor は、画像処理をネイティブCで実行し、Dart FFIを通してFlutterから利用できる画像編集ライブラリです。
ぼかしやセピア、彩度、明るさ、コントラスト、シャープ化、グレースケールなどのフィルターに対応しているほか、画像全体ではなく特定の領域だけにエフェクトを適用することもできます。
この記事では、fast_image_editor の基本的な使い方から、部分的なフィルター処理、非同期処理、画像リサイズまで詳しく解説します。
fast_image_editorとは?
fast_image_editor は、Flutterから画像データを高速に編集するためのパッケージです。
画像処理のコア部分はCで実装されており、Dart FFIを利用してFlutterからネイティブコードを呼び出します。
そのため、Dart側で画像の各ピクセルを1つずつ処理するような実装を避けられるのが特徴です。
主な機能は以下の通りです。
| 機能 | 対応 |
|---|---|
| ぼかし | ○ |
| セピア | ○ |
| 彩度調整 | ○ |
| 明るさ調整 | ○ |
| コントラスト調整 | ○ |
| シャープ化 | ○ |
| グレースケール | ○ |
| 部分的なフィルター | ○ |
| 円形領域へのフィルター | ○ |
| 画像リサイズ | ○ |
| JPEG | ○ |
| PNG | ○ |
| 同期処理 | ○ |
| 非同期処理 | ○ |
| Android | ○ |
| iOS | ○ |
画像編集に必要となる基本的な機能をシンプルなAPIで利用できます。
インストール
pubspec.yaml にパッケージを追加します。
dependencies:
fast_image_editor: ^1.0.4
その後、
flutter pub get
を実行します。
コードから利用する場合は、
import 'package:fast_image_editor/fast_image_editor.dart';
をインポートします。
基本的な使い方
fast_image_editor のAPIは、画像のバイトデータを渡して編集後のバイトデータを取得するというシンプルな設計になっています。
例えば、画像をぼかす場合は以下のように実装できます。
final result = FastImageEditor.blur(
bytes: imageBytes,
radius: 15,
);
imageBytes にはJPEGやPNGなどの画像データを Uint8List として渡します。
処理結果も画像のバイトデータとして返されるため、そのまま、
Image.memory- ファイル保存
- サーバーアップロード
などに利用できます。
例えばFlutter上に表示するなら、
Image.memory(result)
のように利用できます。
画像をぼかす
最もシンプルな例が画像全体へのぼかし処理です。
final result = FastImageEditor.blur(
bytes: imageBytes,
radius: 15,
);
radius の値を変更することで、ぼかしの強さを調整できます。
例えば、
final result = FastImageEditor.blur(
bytes: imageBytes,
radius: 30,
);
のようにすると、より強いぼかしを適用できます。
プロフィール画像や背景画像をぼかしたり、個人情報を隠したりする用途にも利用できます。
セピアフィルター
写真をレトロな雰囲気にしたい場合は、セピアフィルターを利用できます。
final result = FastImageEditor.sepia(
bytes: imageBytes,
intensity: 0.8,
);
intensity でセピア効果の強さを調整できます。
例えば、
0.0
↓
セピア効果なし
0.5
↓
弱めのセピア
1.0
↓
強いセピア
というように、用途に応じて調整できます。
写真加工アプリやSNSアプリなどで利用しやすい機能です。
彩度を調整する
画像の色の鮮やかさを変更する場合は、saturation を利用します。
final result = FastImageEditor.saturation(
bytes: imageBytes,
value: 1.5,
);
彩度を高くすれば色鮮やかな画像に、低くすればモノクロに近い表現にできます。
例えば画像編集UIで、
彩度
●━━━━━━━○
のようなスライダーを用意して、ユーザーがリアルタイムに調整するような機能も実装できます。
明るさを調整する
画像の明るさを変更したい場合は、brightness を利用します。
final result = FastImageEditor.brightness(
bytes: imageBytes,
value: 0.2,
);
写真が暗すぎる場合に明るくしたり、逆に明るすぎる画像を暗くしたりできます。
写真編集アプリの基本的な調整機能として利用できます。
コントラストを調整する
画像の明暗差を調整する場合は、contrast を利用します。
final result = FastImageEditor.contrast(
bytes: imageBytes,
value: 1.2,
);
コントラストを調整することで、画像をよりメリハリのある見た目にできます。
シャープ化する
画像を少しぼやけた印象から、よりくっきり見せたい場合は sharpen を利用できます。
final result = FastImageEditor.sharpen(
bytes: imageBytes,
amount: 1.5,
);
画像の輪郭を強調することで、シャープな見た目に調整できます。
グレースケールに変換する
画像をモノクロ風にしたい場合は、grayscale を利用できます。
final result = FastImageEditor.grayscale(
bytes: imageBytes,
);
例えば、
カラー画像
↓
grayscale
↓
モノクロ画像
という変換を簡単に実装できます。
写真アプリのモノクロフィルターなどに利用できます。
一部分だけにフィルターを適用する
fast_image_editor の特徴的な機能の一つが、画像の一部分だけにエフェクトを適用できることです。
例えば、画像の上30%と下30%だけにセピアフィルターを適用する場合は、
final result = FastImageEditor.sepia(
bytes: imageBytes,
intensity: 0.8,
region: EditRegion(
top: 0.3,
bottom: 0.3,
),
);
のように指定できます。
これにより、
┌──────────────┐
│ セピア │ ← 上30%
├──────────────┤
│ │
│ 元画像 │
│ │
├──────────────┤
│ セピア │ ← 下30%
└──────────────┘
のように、画像の一部分だけを加工できます。
左半分だけグレースケールにする
例えば、画像の左半分だけをモノクロにすることもできます。
final result = FastImageEditor.grayscale(
bytes: imageBytes,
region: EditRegion(
left: 0.5,
),
);
これにより、
┌──────────────┐
│ モノクロ │カラー │
│ モノクロ │カラー │
│ モノクロ │カラー │
└──────────────┘
というような加工ができます。
画像編集アプリで「Before / After」を1枚の画像内に表現したい場合などにも使えそうです。
片側だけにエフェクトを適用する
特定の辺だけを対象にしたい場合は、便利なコンストラクタも用意されています。
例えば上側だけなら、
final result = FastImageEditor.sepia(
bytes: imageBytes,
intensity: 0.8,
region: EditRegion.topOnly(0.3),
);
のように指定できます。
同様に、
EditRegion.topOnly(...)
EditRegion.bottomOnly(...)
EditRegion.leftOnly(...)
EditRegion.rightOnly(...)
を利用できます。
画像の端だけにフィルターを適用したい場合に便利です。
円形領域にエフェクトを適用する
矩形だけではなく、円形の領域を対象にすることもできます。
例えば画像の中央部分だけにぼかしを適用する場合は、
final result = FastImageEditor.blur(
bytes: imageBytes,
radius: 20,
radialRegion: RadialRegion(
centerX: 0.0,
centerY: 0.0,
radius: 0.3,
),
);
のように指定できます。
これを利用すると、
- 円形のぼかし
- 中央だけのエフェクト
- 周囲だけを加工する表現
などを実装できます。
例えば、人物の顔周辺だけをぼかしたい場合や、画像の中心に注目させるような演出にも応用できます。
画像をリサイズする
fast_image_editor では、画像のリサイズにも対応しています。
例えば、
final result = FastImageEditor.resize(
bytes: imageBytes,
outputWidth: 800,
outputHeight: 600,
);
のように指定します。
リサイズにはバイキュービック補間が利用されており、単純な縮小・拡大よりも高品質な画像リサイズを実現できます。
例えば、ユーザーが撮影した高解像度の写真をサーバーへアップロードする前に、
カメラ画像
↓
800 × 600へリサイズ
↓
サーバーへアップロード
という処理を実装できます。
画像アップロード時の通信量を削減したい場合にも便利です。
JPEGとPNGに対応
fast_image_editor はJPEGとPNGの画像データを扱えます。
画像フォーマットは自動的に検出できます。
例えば、
final format =
FastImageEditor.detectFormat(
imageBytes,
);
とすることで、画像形式を確認できます。
結果として、
ImageFormat.jpeg
や、
ImageFormat.png
などを取得できます。
対応していない画像形式を処理する前にチェックしたい場合にも利用できます。
JPEGの品質を指定する
JPEGとして出力する場合は、画質を指定できます。
final result = FastImageEditor.blur(
bytes: imageBytes,
radius: 10,
quality: 90,
);
品質は1〜100の範囲で指定できます。
例えば、
quality = 100
↓
高画質・ファイルサイズ大
quality = 70
↓
画質とサイズのバランス
quality = 30
↓
低画質・ファイルサイズ小
というように、用途に合わせて設定できます。
なお、PNGの場合はJPEGのような品質設定は適用されません。
非同期処理を利用する
画像処理は、画像サイズが大きくなるほどCPU負荷が高くなる可能性があります。
そのため、fast_image_editor では各処理に非同期版のAPIも用意されています。
例えばぼかし処理なら、
final result =
await FastImageEditor.blurAsync(
bytes: imageBytes,
radius: 10,
);
のように利用できます。
非同期版は Isolate.run を利用して処理を実行するため、重い画像処理をUIスレッドから分離できます。
大量の画像や高解像度の写真を扱う場合には、非同期APIを利用するのがおすすめです。
同期処理と非同期処理の使い分け
基本的には、処理内容や画像サイズに応じて使い分けるとよいでしょう。
| 処理 | API |
|---|---|
| 小さな画像をすぐ処理 | 同期API |
| 大きな画像を処理 | 非同期API |
| UIを止めたくない | 非同期API |
| バックグラウンド処理 | 非同期API |
| 単純な変換 | 同期API |
例えばサムネイル程度の小さな画像なら同期処理でも問題ないケースがあります。
一方、スマートフォンのカメラで撮影した高解像度画像を加工する場合は、非同期APIを利用した方が安全です。
image_pickerと組み合わせる
実際のFlutterアプリでは、image_picker と組み合わせるケースが考えられます。
例えば、
final image =
await ImagePicker().pickImage(
source: ImageSource.gallery,
);
if (image != null) {
final bytes =
await image.readAsBytes();
final edited =
await FastImageEditor.blurAsync(
bytes: bytes,
radius: 10,
);
}
という流れで、
ギャラリーから画像選択
↓
Uint8Listへ変換
↓
fast_image_editorで加工
↓
加工後の画像を表示
↓
保存・アップロード
という画像編集フローを構築できます。
画像アップロード前の加工にも便利
ユーザーが画像をアップロードするアプリでは、アップロード前に画像を処理したいケースがあります。
例えば、
画像選択
↓
リサイズ
↓
フィルター適用
↓
JPEG品質調整
↓
サーバーアップロード
というパイプラインを作ることができます。
プロフィール画像、SNS投稿、商品画像、フリマアプリなど、ユーザーが画像をアップロードするサービスとの相性が良いでしょう。
SNSアプリとの相性が良い
SNSアプリでは、
- セピア
- モノクロ
- 明るさ
- コントラスト
- 彩度
- シャープ化
などの画像フィルターがよく利用されます。
fast_image_editor を使えば、これらの基本的な画像編集機能をFlutterから実装できます。
さらに部分的なエフェクトにも対応しているため、単純な「画像全体へのフィルター」だけではなく、より複雑な画像加工機能にも応用できます。
ネイティブCによる高速処理
fast_image_editor の大きな特徴は、画像処理のコア部分をCで実装していることです。
一般的に画像処理では、
画像
↓
大量のピクセル
↓
各ピクセルを処理
↓
新しい画像を生成
という処理が必要になります。
これをDart側だけで実装すると、処理内容によってはパフォーマンス上の問題が発生する可能性があります。
fast_image_editor では、
Flutter / Dart
↓
Dart FFI
↓
Native C
↓
画像処理
という構成になっています。
そのため、画像処理を高速化したいアプリでは有力な選択肢になります。
どんなアプリに向いている?
写真加工アプリ
フィルターや明るさ、コントラストなどの画像編集機能を実装できます。
SNSアプリ
投稿前の画像加工やリサイズに利用できます。
プロフィール画像編集
ユーザーがアップロードするプロフィール画像を加工できます。
EC・フリマアプリ
商品画像のリサイズや加工、アップロード前の最適化に利用できます。
画像アップロードアプリ
高解像度画像をリサイズしてからサーバーへ送信する用途に向いています。
個人情報保護
画像の一部をぼかす処理などにも応用できます。
メリット
ネイティブCで高速な画像処理
Dart FFIを利用してCで画像処理を行うため、パフォーマンスを重視した画像編集に向いています。
APIがシンプル
画像のバイトデータを渡して結果を受け取るだけなので、導入しやすい設計です。
部分的なフィルターに対応
画像全体だけでなく、矩形領域や円形領域を指定してエフェクトを適用できます。
非同期処理に対応
Isolate.run を利用した非同期APIが用意されているため、大きな画像の処理にも対応しやすくなっています。
基本的なフィルターが揃っている
ぼかし、セピア、彩度、明るさ、コントラスト、シャープ化、グレースケールという、画像編集アプリでよく使う機能が揃っています。
高品質なリサイズ
バイキュービック補間による画像リサイズに対応しています。
注意点
AndroidとiOSのみ対応
現時点ではAndroidとiOSがサポート対象です。
Flutter WebやWindows、macOS、Linuxなどで同じコードを利用したい場合は、別の画像処理ライブラリを検討する必要があります。
JPEGとPNGが中心
対応フォーマットはJPEGとPNGです。
WebPやGIFなど、その他の画像形式を扱う場合は事前に変換する必要がある可能性があります。
UIとしての画像編集画面は提供しない
fast_image_editor は画像処理エンジンに近いパッケージです。
例えば、
- トリミングUI
- フィルター選択UI
- スライダー
- 回転UI
- 編集ツールバー
といった完成済みの画像編集画面が提供されるわけではありません。
そのため、画像編集アプリを作る場合はFlutter側でUIを構築し、fast_image_editor を画像処理部分として利用する形になります。
まとめ
fast_image_editor は、Flutterアプリで高速な画像処理を実現したい場合に注目したいパッケージです。
ネイティブCによる画像処理とDart FFIを組み合わせることで、Flutterから高速な画像編集機能を利用できます。
主な機能として、
- ぼかし
- セピア
- 彩度調整
- 明るさ調整
- コントラスト調整
- シャープ化
- グレースケール
- 部分的なフィルター
- 円形領域へのエフェクト
- 高品質なリサイズ
- JPEG / PNG対応
- 同期・非同期処理
などが用意されています。
特に、画像全体にフィルターを適用するだけではなく、EditRegion や RadialRegion を使って画像の一部分だけを加工できる点は面白いポイントです。
また、画像処理をCで実行するため、高解像度の画像を扱うアプリや大量の画像処理が必要なアプリでも検討しやすいでしょう。
写真加工アプリやSNS、EC、フリマアプリなど、Flutterで画像を扱うアプリを開発している場合は、画像処理部分のライブラリとして一度試してみてはどうでしょうか。
