Хорошо, вот как я решил это.
В моем случае проблема не имела никакого отношения к поддержке JPEG. JPEG уже поддерживается, однако в моем коде были некоторые ошибки, кроме того, я использовал другой подход к масштабированию изображения.
- Первая ошибка в этой строке:
val scaledImage = BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB)
ImageIO.write
не может найти ImageWriter
, который соответствует BufferedImage.TYPE_INT_ARGB
и JPG
/ JPEG
. Итак, я изменил его на BufferedImage.TYPE_INT_RGB
.
Исправление приводит к тому, что исключение выдается на
ato.filter(image, scaledImage)
Exception in thread "main" java.awt.image.ImagingOpException: Unable to transform src image
Я не знаю, в чем причина этого исключения и как его исправить, но с использованием Graphics2D
объект для масштабирования и рендеринга изображения работал для меня.
Несмотря на то, что создан правильный файл изображения, но он содержит только черный фон. И это потому, что предоставленные значения
scale()
были несовместимы.
Ниже приведен окончательный код, в котором это работает успешно, и как были исправлены точки 2 и 3.
import java.awt.Graphics2D
import java.awt.image.BufferedImage
import java.io.File
import javax.imageio.ImageIO
fun main() {
val file = File("storage/test/original.jpg")
val image = ImageIO.read(file.inputStream())
val thumbnail = thumbnailOf(image)
val thumbnailFile = File("storage/test/thumbnail.jpg")
thumbnailFile.parentFile.mkdirs()
thumbnailFile.outputStream().use { output ->
ImageIO.write(thumbnail, "JPEG", output)
}
}
fun thumbnailOf(image: BufferedImage): BufferedImage {
val width = image.width
val height = image.height
val ratio = width / height.toDouble()
if (ratio == 0.0) {
error("Cannot determine ratio for ($width*$height)")
}
val newWidth = 600
val newHeight = (newWidth / ratio).toInt()
val scale = newWidth / width.toDouble()
val scaledImage = BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB)
val graph = scaledImage.graphics as Graphics2D
// graph.scale((newWidth / width).toDouble(), (newHeight / height).toDouble())
graph.scale(scale, scale)
// everything drawn with graph from now on will get scaled.
graph.drawImage(image, 0, 0, null)
graph.dispose()
return scaledImage
}