前置き
Jetpack Compose for Desktop version 0.2.0 での話です。
Jetpack Compose for Desktop での画像表示の現状
Jetpack compose for Desktop のSDK では 画像を表示する関数 Image()
が定義されています。
Image()
関数では、 ImageBitmap
, Painter
, ImageVetor
のいずれかの Class のインスタンスを関数呼び出し時に引数として渡します。
どれもが Jetpack Compose for Desktop の SDK 内で定義されたクラスになります。
Painter class のインスタンスを作成するためには ImageBitmap が必要になるため無視します。
また、 ImageVector class も Vector Image を表示するときには使えますが、今回は 普通の .png 等々に絞るため無視します。
ここまでで、 Jetpack Compose for Desktop で画像を表示するために使う関数は Image() を ImageBitmap の引数付きで呼び出す必要があることまでわかりました。
@Composable inline fun Image( bitmap: ImageBitmap, // 省略 )
余談ですが、 ImageBitmap を引数に渡して呼び出す関数は ImagePainter を渡すときの関数の Syntax sugar です。
Resource に追加済の Image を表示する
Resource に追加済の画像を表示するためには以下のようにヘルパー関数が用意されているので呼び出すだけで済みます。
Image(imageResource("path/to/resource/image.png"))
Skia の 関数を利用してLocal に存在する画像を読み込めるようにする
imageResource()
関数を呼び出すとThread Context に存在するResourceから画像を読み込もうとします。
しかし、Local の アプリケーション外に存在する画像はResource に登録されてるはずがないので失敗します。
先ほど出てきた imageResource()
関数、Resource から画像ファイルを読み込む場合は、 最終的にByteArray に変換しています。
変換したものを利用し skija(Jetbrains が開発している Skia の Java binding ライブラリ) に存在する、 Image class のインスタンスを作成しています。
fun Image.makeFromEncoded(byteArray)
解決策
画像を読み込みByteArray を作成するところまでを独自で書けば良さそう。 局所的に変更できない・Image から ImageBitmap へのヘルパー関数が使える。
等々を考慮して以下のようなコードになりました。
Image(Image.makeFromEncoded(File(dummyImagePath).readBytes()).asImageBitmap())
実際に使うときにはラッパー関数を用意すると便利そう 例:
fun imageLocalResource(path: String): ImageBitmap { return imageLocalResource(path) } fun imageLocalResource(path: File): ImageBitmap { return makeFromEncoded(path.readBytes()).asImageBitmap() } // from Resource Image(imageResource("path/to/image")) // from Local Image(imageLocalResource("path/to/image"))