Flutter: Image.fileにwidthやheightのプロパティがあるのに、取得するとnullになる
結論:「image_size_getter」パッケージを使う
2022/8/28 Flutter エラー・バグ日記
表示している画像のサイズ(横幅、縦幅)を取得したかったので、表示に使用している「Image.file」から、「width」と「height」を取得したら、いずれの値も「null」しか取得できなかった。
書いていたコードは以下のとおり。
// クラス・メソッド・プロパティについて、筆者が作成したものには、末尾に大文字のオー「O」をつけて表記 // ※パッケージで予め決められているものとの区別しやすくするため imageFileO = Image.file(File(画像ファイルのパス))); print("width: ${imageFileO.width}, height: ${imageFileO.height}");
自分のコードの間違い箇所を探すも発見できず。
ソースコードを見ても「Image.file」には、「width」と「height」というプロパティが用意されており、実際に上記のようにコードを書いてもエラーにはならない。
なのになぜ「null」になってしまうのだろうか?
変換する手順が重要だった
調べてみると、以下の情報があった(ズバリの情報ありがとうございます!)。
なんと、File型→Image型という変換をしただけだと、横・縦幅が取得できないとのこと。
上記記事では、変換前のデータが、「image_picker」パッケージなどを用いた際に出てくる「XFile」型となる前提で紹介されているが、それ以外の型(例えば、直接、画像の保存パスを指定して作成したFile型など)でも同じだった。
対処法としては、
- File型を「readAsBytes」メソッドで、いったん「Uint8List」型に変換し、
- それを「decodeImage」メソッドで、「Image」型に変換する
というもの。
「decodeImage」メソッドの利用には、「image」パッケージのインポートが必要。
確かに、この方法で「Uint8List」型→「Image」型に変換したら、横・縦幅を取得することができた。
「decodeImage」メソッドが遅すぎる。。。
しかし、この方法に変えたら、とてつもなく時間がかかるようになってしまった。。
原因を調べると、「decodeImage」メソッドの有無で、大きく処理時間が違うと分かった。
ネットを見ると、同様の報告がいくつか見つかった。
画像サイズ取得専門のパッケージのほうが高速
試しに、画像サイズ取得に特化したパッケージがないか調べたところ、複数見つかった。
上記参考記事で紹介されている「flutter_native_image」も良さそうだったが、バージョン番号が0番始まりで、安定版ではない位置づけだったので(現時点でバージョン「0.0.6+1」)、既に安定版になっている「image_size_getter」を使ってみることにした(現時点でバージョン「2.1.2」)。
導入してみると、直接「File」型から横幅・縦幅を取得でき、かつ圧倒的に高速だった。
書くコードもわかりやすく、下記のような記載のみで取得できた。
final sizeO = ImageSizeGetter.getSize(FileInput(File(画像ファイルのパス))); print("width: ${sizeO.width}, height: ${sizeO.height}");
当初は、画像サイズの把握のためだけにパッケージを入れるのはどうかな、、と考えていたが、この方法が便利過ぎるので、素直に「image_size_getter」を使わせていただくことにした。
\一般的なエラー対処法をまとめた記事はこちら/
リリースしたアプリ(全てFlutterで開発)
個人アプリ開発で役立ったもの
おすすめの学習教材
\超初心者向けでオススメな元Udemyの講座/
\キャンペーン時を狙えば安価で網羅的な内容が学べる(日本語訳あり)/
\Gitの基礎について無料で学べる/
おすすめの学習書籍
\実用的。image_pickerに関してかなり助けられた/
\Dartの基礎文法を素早くインプットできる/