概要
- iPhoneのカメラで画像を作成した場合、画像の向きはEXIFのorientationに保存される。
- EXIFはimagemagicの
identify
コマンドで確認できる。
$ identify -verbose IMG_1046.png | grep Orient
Orientation: TopLeft
- 画像をリサイズする場合はEXIFを考慮する必要がある。
- 自分で実装するのは大変なのでライブラリを使う。
使用するライブラリ
- sksamuel/scrimage - Java, Scala and Kotlin image processing library
実装
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
}
}
}
}
/**
* 長辺を[size]にしてリサイズする
*
* 長辺が[size]よりも小さい場合は、リサイズしない
*/
fun resize(inputStream: InputStream, size: Int, formatName: String): File {
// オリジナルのファイルを読み込む
val original = ImmutableImage.loader().fromStream(inputStream)
val originalWidth = original.width.toDouble()
val originalHeight = original.height.toDouble()
if (originalWidth <= size && originalHeight <= size) {
// 長辺がsizeよりも小さい場合は、リサイズしない
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
}
}
これで正しい向きでリサイズ画像が作成されます(リサイズ後の画像からはEXIF orientationは失われます。)
備考
- Javaのサムネイル作成ライブラリとして thumbnailator が有名ですが、こちらはEXIFのorientationを考慮していないようでした。