🌱

【Flutter】OSやデバイスにあったアプリアイコンをコマンド一発で生成する(2024年1月更新)

2022/04/01に公開
3

はじめに

アプリを作るときに必ず作ることになるアプリアイコンですが、アイコン画像を作ったはよいものの、OSやデバイスの解像度に合うように様々なサイズの画像に変換が必要でめちゃくちゃ大変です。

Flutterでは様々なサイズのアプリアイコンに自動で変換してくれるパッケージ flutter_launcher_icons がありますので、その導入方法について解説します。

https://pub.dev/packages/flutter_launcher_icons

更新履歴
更新日 内容
2024/1/9 flutter_launcher_icons 0.13.1 に合わせて全体的に修正(初版時は 0.9.2)
2022/4/1 初版

環境

Flutter 3.16.5 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 78666c8dc5 (3 weeks ago) • 2023-12-19 16:14:14 -0800
Engine • revision 3f3e560236
Tools • Dart 3.2.3 • DevTools 2.28.4

手順

アイコン画像を2種類用意する

アイコン画像のサイズや種類についての指定は特にありません。サイズは512x512くらいあれば十分でしょう。
今回は以下の画像を用意しました。画像は icon8 からダウンロードしました。

icon.png
icon.png
背景色(#ffffff)あり

Android8以上はアダプティブアイコンといって、デバイスモデルごとに異なるアイコンの図形を表示できますので、背景透過し約50%縮小した画像も用意します。今回画像の縮小は PEKO-STEP を利用しました。
アダプティブアイコンに対応しないこともできますが、Android端末でアイコンが見切れてしまうので対応は必須と思います。

icon_adaptive_foreground.png
icon_adaptive_foreground.png
背景透過、約50%縮小

それぞれ以下に保存しておきます。

assets
└── images
    ├── icon.png
    └── icon_adaptive_foreground.png

pubspec.yamlを編集する

pubspec.yaml
  dev_dependencies:
+   flutter_launcher_icons: ^0.13.1

+ flutter_launcher_icons:
+   android: true
+   ios: true
+   image_path: 'assets/images/icon.png'
+   adaptive_icon_background: '#ffffff'
+   adaptive_icon_foreground: 'assets/images/icon_adaptive_foreground.png'

^0.13.1の部分は最新バージョンを指定してください。
image_path のアイコン画像はiOSとAndroid8未満に適用されます。
adaptive_icon_background は Androidのアダプティブアイコンの背景色です。お好きな色を指定してください。

コマンドを実行してアイコン画像を生成する

ターミナルで以下のコマンドを実行してアイコン画像を生成してもらいます。

flutter pub get
flutter pub run flutter_launcher_icons

動作確認する

ビルドして各OSで実行してみます。AndroidとiOSとも良い感じに出来ました!余白の部分や背景色はお好きな感じにアレンジしてください。

Pixel 5 (Android 12) iPhone 12 Pro (iOS 15.4)
Pixel 5 (Android 12 iPhone 12 Pro (iOS 15.4)
Pixel 5 (Android 12 iPhone 12 Pro (iOS 15.4)

ちなみに、icon.pngの背景を透過にすると、iOSで背景が黒色になってしまいAndroidと見た目が変わってしまうのでご注意ください。

AndroidとiOSで別々のアイコン画像を指定したい

下記のようにそれぞれ指定することができます。

pubspec.yaml
  flutter_launcher_icons:
    android: true
    ios: true
-   image_path: 'assets/images/icon.png'
+   image_path_android: 'assets/images/icon_android.png'
+   image_path_ios: 'assets/images/icon_ios.png'
    adaptive_icon_background: '#ffffff'
    adaptive_icon_foreground: 'assets/images/icon_adaptive_foreground.png'

開発環境と本番環境で別々のアイコン画像を指定したい

下記のようにルートディレクトリにflutter_launcher_icons-<flavor>.yamlを環境毎作成し、pubspec.yamlflutter_iconsセクションに書いていた内容を書き移します。

flutter_launcher_icons-dev.yaml(開発環境用)
flutter_launcher_icons:
  android: true
  ios: true
  image_path: 'assets/images/icon_dev.png'
  adaptive_icon_background: '#ffffff'
  adaptive_icon_foreground: 'assets/images/icon_adaptive_foreground_dev.png'
flutter_launcher_icons-prod.yaml(本番環境用)
flutter_launcher_icons:
  android: true
  ios: true
  image_path: 'assets/images/icon_prod.png'
  adaptive_icon_background: '#ffffff'
  adaptive_icon_foreground: 'assets/images/icon_adaptive_foreground_prod.png'

画像作成のコマンド実行時にエラー

コマンド実行時に以下のエラーが出ることがあります。

Unhandled exception:
FormatException: Invalid number (at character 1)

^

#0      int._handleFormatError (dart:core-patch/integers_patch.dart:129:7)
#1      int.parse (dart:core-patch/integers_patch.dart:55:14)
#2      minSdk (package:flutter_launcher_icons/android.dart:309:18)
#3      createIconsFromConfig (package:flutter_launcher_icons/main.dart:94:47)
#4      createIconsFromArguments (package:flutter_launcher_icons/main.dart:60:7)
#5      main (file:///Users/susa/Develop/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_launcher_icons-0.9.2/bin/main.dart:6:26)
#6      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:295:32)
#7      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
pub finished with exit code 255

その場合は android/app/build.gradle を以下のように修正すれば解決します。minSdkVersiontargetSdkVersionの値はご自分で好きな値にしてください。

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "jp.keyber.flutter_launcher_icons_sample"
-        minSdkVersion flutter.minSdkVersion
-        targetSdkVersion flutter.targetSdkVersion
+        minSdkVersion 26
+        targetSdkVersion 31
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }

最後に

Flutter 大学という Flutter エンジニアに特化した学習コミュニティに所属しています。オンラインでわいわい議論したり、Flutter の最新情報をゲットしたりできます!ぜひ Flutter 界隈を盛り上げていきましょう!

https://flutteruniv.com?invite_id=9hsdZHg0qtaMIr6RPRulAaRJfA83

あわせて読みたい

https://medium.com/flutter-jp/icon-935d637d2da0

Discussion

yamadayamada

貴重な記事をありがとうございます。
一つ質問なのですが、pubspec.yamlに記述しているコードで
flutter_icons:とありますが、パッケージのREADMEをみるとflutter_launcher_icons:と記述されています。この違いというのは何かしらの意図があるのでしょうか?

すさすさ

ご質問ありがとうございます!また、返信が遅れて申し訳ございません。
記載頂いた違いは flutter_launcher_icons のバージョンの違いによるもので、現時点の最新版の 0.13.1 では flutter_launcher_icons: と記載するのが正しいです。

本記事の内容も最新版に合わせて更新しました。

yamadayamada

そうなんですね!
教えていただいてありがとうございます。