Compose for Desktopで画像を表示するには、Imageコンポーザブル関数を使用します。
@Composable
fun Image(
bitmap: ImageBitmap,
contentDescription: String?,
modifier: Modifier = Modifier,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null,
filterQuality: FilterQuality = DefaultFilterQuality
)
FileオブジェクトからImageBitmapを取得するには、org.jetbrains.skia.ImageのmakeFromEncoded()とtoComposeImageBitmap()を使用します。
表示画像のスケーリングは、contentScaleで指定します。
ContentScale.Fitは表示領域に合わせて画像が拡大縮小されます。
ContentScale.Insideは表示領域に収まるように画像が縮小されます。
Image(
bitmap = Image.makeFromEncoded(imageFile!!.readBytes()).toComposeImageBitmap(),
contentDescription = null,
modifier = androidx.compose.ui.Modifier.fillMaxSize(),
contentScale = ContentScale.Inside
)
次のサンプルプログラムは、ファイル選択ダイアログで選択した画像を表示します。
@Composable
@Preview
fun App() {
var isOpenFileDialog by remember { mutableStateOf(false) }
var imageFile by remember { mutableStateOf<File?>(null) }
MaterialTheme {
Column {
Button(onClick = { isOpenFileDialog = true }) { Text("Choose a file") }
if (imageFile != null) {
Image(
bitmap = Image.makeFromEncoded(imageFile!!.readBytes()).toComposeImageBitmap(),
contentDescription = null,
modifier = androidx.compose.ui.Modifier.fillMaxSize(),
contentScale = ContentScale.Inside
)
}
}
if (isOpenFileDialog) {
FileDialog(mode = FileDialog.LOAD,
filenameFilter = { _, name -> name?.matches(Regex("(.+\\.jpg)|(.+\\.png)|(.+\\.gif)")) ?: false },
onCloseRequest = { directory, file ->
isOpenFileDialog = false
if (directory != null && file != null) {
println(File(directory, file).absolutePath)
imageFile = File(directory, file)
}
})
}
}
}
@Composable
private fun FileDialog(
parent: Frame? = null,
title: String = "Choose a file",
mode: Int = FileDialog.LOAD,
filenameFilter: FilenameFilter? = null,
onCloseRequest: (directory: String?, result: String?) -> Unit
) = AwtWindow(
create = {
object : FileDialog(parent, title, mode) {
init {
filenameFilter?.let { setFilenameFilter(filenameFilter) }
}
override fun setVisible(value: Boolean) {
super.setVisible(value)
if (value) {
onCloseRequest(directory, file)
}
}
}
}, dispose = FileDialog::dispose
)
fun main() = application {
Window(onCloseRequest = ::exitApplication) {
App()
}
}