DEV Community

 AppInitDev
AppInitDev

Posted on

Cómo abrir fotos grandes en Android sin cargar todos sus píxeles en memoria

Cómo abrir fotos grandes en Android sin cargar todos sus píxeles en memoria

Una fotografía de 6.000 × 4.000 píxeles representa 24 millones de píxeles. Si la decodificamos en ARGB_8888, el bitmap sin comprimir puede ocupar alrededor de 96 MB, sin contar copias y otros recursos.

El problema y el alcance del ejemplo

La ficha de Photo Utility Hub: Editor IA resume su función así: «Edita fotos con IA, elimina fondos y convierte archivos de imagen.» Photo Utility Hub describe edición de fotos, eliminación de fondos y conversión de formatos. Antes de cualquiera de esas tareas, existe un problema básico: decodificar una previsualización dimensionada para la pantalla. El siguiente código es una técnica de referencia, no un módulo extraído de la app.

Cómo reproducir la idea

En un proyecto Android Kotlin, selecciona una foto mediante el selector del sistema y pasa su Uri a decodePreview. Ejecuta la función fuera del hilo principal.

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri

fun decodePreview(context: Context, uri: Uri, maxSide: Int = 1600): Bitmap? {
    require(maxSide > 0)
    val bounds = BitmapFactory.Options().apply { inJustDecodeBounds = true }
    val firstStream = context.contentResolver.openInputStream(uri) ?: return null
    firstStream.use { input ->
        BitmapFactory.decodeStream(input, null, bounds)
    }
    if (bounds.outWidth <= 0 || bounds.outHeight <= 0) return null

    var sample = 1
    while (bounds.outWidth / sample > maxSide ||
           bounds.outHeight / sample > maxSide) {
        sample *= 2
    }
    val opts = BitmapFactory.Options().apply { inSampleSize = sample }
    return context.contentResolver.openInputStream(uri)?.use { input ->
        BitmapFactory.decodeStream(input, null, opts)
    }
}
Enter fullscreen mode Exit fullscreen mode

Qué demuestra el código

La primera pasada lee las dimensiones (inJustDecodeBounds) sin construir el bitmap completo. La segunda decodifica con inSampleSize. Dos pasadas implican volver a abrir el flujo de la URI; el proveedor debe permitirlo.

Pruebas recomendadas

Prueba con una foto pequeña y otra de más de 20 MP. Compara las dimensiones del bitmap devuelto y, con Android Studio Profiler, inspecciona el pico de memoria frente a una decodificación completa. No afirmamos ninguna mejora cuantitativa sin medirla.

Límites que conviene reconocer

El muestreo puede dejar un tamaño distinto del objetivo y no maneja automáticamente orientación EXIF, perfiles de color ni todas las particularidades de HEIF/AVIF. Para un editor real hay que preservar la imagen original y realizar la exportación final por separado.

Qué aprendemos

Una aplicación de fotos necesita dos rutas distintas: previsualización rápida y procesamiento de salida de calidad controlada.

Contexto y enlaces del autor

El tema se relaciona con las funciones declaradas públicamente de Photo Utility Hub: Editor IA, una aplicación Android de AppInitDev. El código anterior es un ejemplo independiente: no se ha inspeccionado el repositorio privado ni se afirma que sea la implementación interna de la app. La referencia aparece al final para ofrecer contexto, no como requisito para completar el tutorial.

APPS

Referencia técnica

Android: BitmapFactory.Options

Top comments (0)