Flutterで9パッチ画像を使う方法

2025年1月13日

9 パッチ画像は、開発者が画像を拡大縮小する際に、画像の特定領域を変形させずに保持することで、画像の歪みを回避できる特殊な PNG 画像です。これは、ボタンの背景、プログレスバーなど、スケーラブルな UI 要素を作成する際に非常に役立ちます。Flutter 自体は 9 パッチ画像のネイティブ形式を直接サポートしていませんが、いくつかのテクニックを使って同様の効果を実現できます。

9 Patch Editor を使って 9 パッチ画像を作成する

まず、PNG 画像を用意する必要があります。次に、9 Patch Editorツールを使って 9 パッチ画像を作成します。このツールでは、画像の伸縮可能領域とコンテンツ領域を指定できます。具体的な手順は以下のとおりです。

  1. 9 Patch Editorのウェブサイトにアクセスします。
  2. PNG 画像をアップロードします。
  3. ツールが提供するエディターを使って、画像の伸縮可能領域を選択します(画像の左端と上端をドラッグします)。
  4. 画像のコンテンツ領域を選択します(画像の右端と下端をドラッグします。これらの領域は伸縮時に変形しません)。
  5. 生成された 9 パッチ画像をダウンロードします(ご自身のプランに応じて異なる画像をダウンロードしてください)。

Flutter で 9 パッチ画像を使う

Flutter には、9 パッチ画像を直接読み込むメカニズムはありません。サードパーティのライブラリを利用するか、Flutter に組み込まれているImage.centerSliceプロパティを使って、9 パッチ画像の効果をシミュレートする必要があります。

方法 1:サードパーティのライブラリを使う

現在、Flutter のいくつかのサードパーティライブラリは、9 パッチ画像の読み込みとレンダリングを支援できます。例えば、ninepatch_imagenine_patchがあります。

ninepatch_image ライブラリを使う

pubspec.yamlファイルに依存関係を追加する必要があります。

dependencies:
  ninepatch_image: ^0.0.4

PNG 画像を Flutter プロジェクトのassetsフォルダに配置し、pubspec.yamlファイルで宣言します。

flutter:
  assets:
    - assets/my_image.9.png

次に、NinePatchImageウィジェットを使って 9 パッチ画像を表示できます。

NinePatchImage(
  imageProvider: AssetImage("assets/my_image.9.png"),
  child: Text( "Lorem Ipsum is simply dummy text of the printing "))

詳細な使用方法については、ninepatch_imageのドキュメントを参照してください。

nine_patch ライブラリを使う

pubspec.yamlファイルに依存関係を追加する必要があります。

dependencies:
  nine_patch: ^1.0.0

assetsフォルダに 9 パッチ画像情報を格納した JSON ファイルを作成し、元の画像assetsフォルダに配置する必要があります。

assets/TextBox_Side.9.jsonassets/2.0x/TextBox_Side.png
(1ピクセルの境界線なし)
{
  "stretch": {
    "x": 118,
    "y": 40,
    "width": 121,
    "height": 60
  },
  "contents": {
    "x": 19,
    "y": 18,
    "width": 248,
    "height": 101
  },
  "dimensions": {
    "x": 285,
    "y": 167
  },
  "name": "TextBox_Side.png",
  "scale": 2
}

TextBox_Side.pngという名前の9パッチPNGファイルの例

stretchは画像の伸縮可能領域、contentsは画像のコンテンツ領域、dimensionsは画像のサイズです。9 Patch Editorツールでこれらの情報を確認するか、nine_patcherツールを使ってこれらの情報を生成できます。

次に、NinePatchImageウィジェットを使って 9 パッチ画像を表示できます。

import 'package:nine_patch/nine_patch.dart';

...

// 新しいNinePatchImageウィジェットを作成します。
NinePatchImage.fromAssetMetadata(
    name: "my_image.9.json",
)

assets/my_image.9.jsonを 9 パッチ画像の JSON ファイルのパスに置き換えることを忘れないでください。

詳細な使用方法については、nine_patchのドキュメントを参照してください。

方法 2:Image.centerSlice を使う

サードパーティのライブラリを使いたくない場合は、Flutter に組み込まれているImage.centerSliceプロパティを使って、9 パッチ画像の効果をシミュレートできます。画像の伸縮可能領域を手動で指定する必要があります。

Image.asset(
  'assets/my_image.png',
  width: 200,
  height: 100,
  centerSlice: Rect.fromLTWH(20, 20, 160, 60), // 伸縮可能領域を手動で指定します
),

注意:画像は元の画像またはコンパイル済みの画像を使用する必要があります。

画像のcenterSliceプロパティの値を手動で調整する必要があります。9 Patch Editorツールでこれらの情報を確認できます。

まとめ

Flutter は 9 パッチ画像を直接サポートしていませんが、サードパーティのライブラリまたはImage.centerSliceプロパティを使用して、同様の効果を実現できます。より簡単に使えるninepatch_imageライブラリの使用をお勧めします。より柔軟で強力な機能が必要な場合は、nine_patchの使用を検討できます。サードパーティのライブラリを導入したくない場合は、Image.centerSliceメソッドを使用できますが、機能が限られており、伸縮可能領域を手動で指定する必要があります。どの方法を選択するかは、具体的なニーズとプロジェクトの複雑さによって異なります。