Jetpack Composeで選択画像をリサイズして表示する

選択した画像ファイルのサイズを変更して、表示するサンプルプログラムです。

画像ファイルを選択するにはActivityResultContracts.GetContentを使用します。
rememberLauncherForActivityResult()を使用してActivityResultContracts.GetContentの結果を取得します。

val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
}

画像ファイルのUriからBitmapを取得します。

UriからBitmapを取得する方法はAndroidのバージョンによって異なります。
バージョンの違いを吸収するための処理を用意します。

fun Uri.getBitmapOrNull(contentResolver: ContentResolver): Bitmap? {
    return kotlin.runCatching {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val source = ImageDecoder.createSource(contentResolver, this)
            ImageDecoder.decodeBitmap(source)
        } else {
            MediaStore.Images.Media.getBitmap(contentResolver, this)
        }
    }.getOrNull()
}

UriからBitmapを取得します。

val context = LocalContext.current

uri?.getBitmapOrNull(context.contentResolver)?.let { bitmap: Bitmap ->
}

取得したBitmapのサイズを変更します。

imageBitmap = Bitmap.createScaledBitmap(bitmap, 500, 500, true)

画像の表示にはCoilを使用します。
build.grableを編集します。

implementation 'io.coil-kt:coil-compose:1.4.0'

imageBitmapがnullでなければ、表示します。

var imageBitmap by remember { mutableStateOf<Bitmap?>(null) }

if (imageBitmap != null) {
    Image(
        painter = rememberImagePainter(imageBitmap),
        contentDescription = null,
        contentScale = ContentScale.None
    )
}

ボタンを押すと、画像を選択します。

Button(onClick = { launcher.launch("image/*") }) {
    Text(text = "Load Image")
}

全体のソースコードは次のようになります。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ResizeImageTheme {
                // A surface container using the 'background' color from the theme
                Surface(color = MaterialTheme.colors.background) {
                    MainContent()
                }
            }
        }
    }
}

@Composable
fun MainContent() {
    val context = LocalContext.current
    var imageBitmap by remember { mutableStateOf<Bitmap?>(null) }

    val launcher =
        rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
            uri?.getBitmapOrNull(context.contentResolver)?.let { bitmap: Bitmap ->
                imageBitmap = Bitmap.createScaledBitmap(bitmap, 500, 500, true)
            }
        }


    Column {
        Button(onClick = { launcher.launch("image/*") }) {
            Text(text = "Load Image")
        }
        if (imageBitmap != null) {
            Image(
                painter = rememberImagePainter(imageBitmap),
                contentDescription = null,
                contentScale = ContentScale.None
            )
        }
    }
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    ResizeImageTheme {
        MainContent()
    }
}

fun Uri.getBitmapOrNull(contentResolver: ContentResolver): Bitmap? {
    return kotlin.runCatching {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val source = ImageDecoder.createSource(contentResolver, this)
            ImageDecoder.decodeBitmap(source)
        } else {
            MediaStore.Images.Media.getBitmap(contentResolver, this)
        }
    }.getOrNull()
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください