[Java] [Java / Kotlin] Resize considering the orientation of the image

1 minute read

Overview

–When you create an image with the iPhone camera, the orientation of the image is saved in EXIF orientation.
–EXIF can be confirmed with imagemagic’s ʻidentify` command.

$ identify -verbose IMG_1046.png | grep Orient
  Orientation: TopLeft

–EXIF needs to be considered when resizing the image.
–I use a library because it is difficult to implement by myself.

Library to use

Implementation

build.gradle


dependencies {
    ...
    implementation "com.sksamuel.scrimage:scrimage-core:4.0.4"
    ...
}

ImageResizer.kt


object ImageResizer {
    enum class ImageFormat {
        JPEG,
        PNG;

        companion object {
            fun fromName(formatName: String): ImageFormat? {
                return when (formatName) {
                    "jpg", "jpeg" -> JPEG
                    "png" -> PNG
                    else -> null
                }
            }
        }
    }

    /**
     *Long side[size]And resize
     *
     *The long side is[size]If it is smaller than, do not resize
     */
    fun resize(inputStream: InputStream, size: Int, formatName: String): File {
        //Read the original file
        val original = ImmutableImage.loader().fromStream(inputStream)
        val originalWidth = original.width.toDouble()
        val originalHeight = original.height.toDouble()

        if (originalWidth <= size && originalHeight <= size) {
            //If the long side is smaller than size, do not resize
            return createImageTempFile(original, formatName)
        }

        val resizedWidth: Double
        val resizedHeight: Double
        if (originalWidth > originalHeight) {
            resizedWidth = size.toDouble()
            resizedHeight = size * originalHeight / originalWidth
        } else {
            resizedHeight = size.toDouble()
            resizedWidth = size * originalWidth / originalHeight
        }

        val resized = original.fit(resizedWidth.roundToInt(), resizedHeight.roundToInt())
        return createImageTempFile(resized, formatName)
    }

    private fun createImageTempFile(image: ImmutableImage, formatName: String): File {
        val format = ImageFormat.fromName(formatName)
            ?: throw BadRequestException("The image format $formatName is not supported ")
        val outFile = createTempFile(suffix = ".$formatName")
        when (format) {
            ImageFormat.JPEG -> image.output(JpegWriter(), outFile)
            ImageFormat.PNG -> image.output(PngWriter(), outFile)
        }
        return outFile
    }
}

This will create a resized image with the correct orientation (EXIF orientation will be lost from the resized image)

Remarks

Thumbnailator is famous as a Java thumbnail creation library, but it didn’t seem to consider EXIF orientation.
- https://github.com/coobird/thumbnailator/issues/108

reference