Comprimir imagens usando Kotlin – Jetpack Compose

Tempo de leitura: 2 minutes

Visão geral

Criaremos um pequeno aplicativo que permite que o usuário escolha uma imagem da galeria e, depois disso, possa compactá-la.

Implementação

Vamos começar adicionando a dependência do Coil no arquivo :app/build.gradle.kts .

dependency {
    implementation("io.coil-kt:coil-compose:2.5.0")
}

Para começar, precisamos criar duas funções:

  • Uri.toDrawable() – Pega o URI que recebemos da galeria e o converte em um drawable.
  • Context.reduceImageSize() – Reduz o tamanho do drawable e o converte em um Bitmap.

toDrawable

Cria um fluxo de entrada aberto que passamos para Drawable.createFromStream para criar o drawable.

fun Uri.toDrawable(context: Context): Drawable? {
    val contentResolver = context.contentResolver
    val inputStream = contentResolver.openInputStream(this)
    return Drawable.createFromStream(inputStream, this.toString())
}

 

reduceImageSize

Isso cria uma matriz de bytes que é decodificada e retornada como um Bitmap.

fun Context.reduceImageSize(drawable: Drawable?): Bitmap? {
    if (drawable == null) {
        return null
    }

    // Criando a matriz de bytes
    val baos = ByteArrayOutputStream()
    // Você pode alterar o tamanho de acordo com suas necessidades
    val bitmap = drawable.toBitmap(100, 100, Bitmap.Config.ARGB_8888)
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
    val imageBytes: ByteArray = baos.toByteArray()

    // Retorno de bitmap
    return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
}

 

Escolha a imagem e comprima-a

Comece criando duas variáveis:

  • currentImage – Contém o URI da imagem da galeria
  • compressedImage – Contém o bitmap compactado
var currentImage by remember {
    mutableStateOf(Uri.EMPTY)
}

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

Agora vamos criar o galleryLauncher . Ele é usado para iniciar a galeria e tem um ouvinte que retorna a imagem selecionada.

val galleryLauncher = rememberLauncherForActivityResult(
    contract = ActivityResultContracts.GetContent(),
    onResult = { uri ->
        uri?.let {
            currentImage = uri
        }
    }
)

Vamos também obter o contexto, pois precisaremos dele em breve.

val context = LocalContext.current

Agora vamos criar o Button que abre a galeria e exibe a imagem selecionada. Além disso, envolva-os com uma colunm .

Column(
    modifier = Modifier.fillMaxSize(),
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.CenterHorizontally
) {
    Button(
        onClick = { galleryLauncher.launch("image/*") }
    ) {
        Text(text = "Pick image")
    }

    AsyncImage(
        model = currentImage,
        contentDescription = null
    )
}

Abaixo da AsyncImage, criaremos o botão compactar imagem e também exibiremos a imagem compactada.

Column(
    // ...
) {
    // ...

    if (currentImage != null) {
        Button(
            onClick = {
                val drawable = currentImage.toDrawable(context)
                compressedImage = context.reduceImageSize(drawable)
            }
        ) {
            Text(text = "Compress Image")
        }

        AsyncImage(
            model = compressedImage,
            contentDescription = null
        )
    }
}