Android Resize Image Save to File Using Fresco (Kotlin)

Oct 25, 2019

Resize Image to File

fun resizeImageToFile(uri: Uri, size: Int, mimeType: String?, file: File): Boolean{    val request = ImageRequestBuilder.newBuilderWithSource(uri)        .setResizeOptions(ResizeOptions(size, size))        .build()    val imagePipeline = Fresco.getImagePipeline()    val dataSource = imagePipeline.fetchDecodedImage(request, null)    // the ResizeOptions in the imageRequest will be ignored for this fetch    // val dataSource = imagePipeline.fetchEncodedImage(request, null)    // val ref = dataSource.result    val ref = DataSources.waitForFinalResult(dataSource)    ref?.use { ref ->        val image = ref.get()        if (image is CloseableBitmap) {            val bitmap = image.underlyingBitmap            if (mimeType == "image/jpeg" || mimeType == null) {                val outputStream = file.outputStream()                outputStream.use { outputStream ->                    bitmap.compress(Bitmap.CompressFormat.JPEG, 85, outputStream)                    // https://caniuse.com/#feat=webp                    // bitmap.compress(Bitmap.CompressFormat.WEBP, 85, outputStream)                    return true                }            }            // TODO - handle other file format        }    }    return false}

Usage

val filePath = ...val file = File(filePath)val outputFile = File(...)if (file.exists()) {    val mimeType = MediaUtils.extractMime(filePath)    resizeImageToFile(Uri.fromFile(file), 1600, mimeType, outputFile)}

Resize Image to InputStream

fun resizeImageToInputStream(uri: Uri, size: Int, mimeType: String?): InputStream? {    val request = ImageRequestBuilder.newBuilderWithSource(uri)        .setResizeOptions(ResizeOptions(size, size))        .build()    val imagePipeline = Fresco.getImagePipeline()    val dataSource = imagePipeline.fetchDecodedImage(request, null)    val ref = DataSources.waitForFinalResult(dataSource)    ref?.use { ref ->        val image = ref.get()        if (image is CloseableBitmap) {            val bitmap = image.underlyingBitmap            if (mimeType == "image/jpeg" || mimeType == null) {                val outputStream = ByteArrayOutputStream()                // val inputStream = PipedInputStream()                // val outputStream = PipedOutputStream(inputStream)                outputStream.use { outputStream ->                    bitmap.compress(Bitmap.CompressFormat.JPEG, 85, outputStream)                    // https://caniuse.com/#feat=webp                    // bitmap.compress(Bitmap.CompressFormat.WEBP, 85, outputStream)                    // toByteArray will trigger copy, thus double memory usage                    // consider this solution: https://github.com/nickrussler/ByteArrayInOutStream                    return ByteArrayInputStream(outputStream.toByteArray())                }            }            // TODO - handle other file format        }    }    return null}

Another solution is via Piped Stream to save memory usage.

fun resizeImageToInputStream(uri: Uri, size: Int, mimeType: String?): InputStream? {    val request = ImageRequestBuilder.newBuilderWithSource(uri)        .setResizeOptions(ResizeOptions(size, size))        .build()    val imagePipeline = Fresco.getImagePipeline()    val dataSource = imagePipeline.fetchDecodedImage(request, null)    // val ref = dataSource.result    val ref = DataSources.waitForFinalResult(dataSource)    ref?.use { ref ->        val image = ref.get()        if (image is CloseableBitmap) {            val bitmap = image.underlyingBitmap            if (mimeType == "image/jpeg" || mimeType == null) {                val inputStream = PipedInputStream()                val outputStream = PipedOutputStream(inputStream)                // using coroutines: need to launch this in a thread                launch(Dispatchers.Default) {                    outputStream.use { outputStream ->                        // outputStream will not be written/complete until the inputStream is read                        bitmap.compress(Bitmap.CompressFormat.JPEG, 85, outputStream)                    }                }                return inputStream            }        }    }    return null}

NOTE: Refer Android Convert OutputStream to InputStream.

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.