Java 将JPEG编码器/解码器支持添加到已安装的OpenJDK

Java 将JPEG编码器/解码器支持添加到已安装的OpenJDK,java,jpeg,javax.imageio,openjdk-12,Java,Jpeg,Javax.imageio,Openjdk 12,我正在尝试缩放JPEG图像并使用以下代码将其保存回去,但是,生成的storage/test/thumbnail.jpg文件只是一个空文件。我用PNG格式检查了相同的代码,它工作得非常好。然而,对于我的用例,我需要一个JPG图像,而不是PNG import java.awt.geom.AffineTransform import java.awt.image.AffineTransformOp import java.awt.image.BufferedImage import java.io.F

我正在尝试缩放JPEG图像并使用以下代码将其保存回去,但是,生成的
storage/test/thumbnail.jpg
文件只是一个空文件。我用
PNG
格式检查了相同的代码,它工作得非常好。然而,对于我的用例,我需要一个JPG图像,而不是PNG

import java.awt.geom.AffineTransform
import java.awt.image.AffineTransformOp
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 scaledImage = BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB)
    val at = AffineTransform()
    at.scale(newWidth / width.toDouble(), newHeight / height.toDouble())
    val ato = AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC)

    return ato.filter(image, scaledImage)
}
到目前为止,我能找到的最好的答案是这个答案,它表明OpenJDK没有JPEG编码器。那么,如果是这样的话,如何将JPEG编码器(或解码器)添加到当前安装的OpenJDK中

我当前安装的OpenJDK

openjdk version "12" 2019-03-19
OpenJDK Runtime Environment (build 12+33)
OpenJDK 64-Bit Server VM (build 12+33, mixed mode, sharing)

好的,下面是我如何解决这个问题的

就我而言,这个问题与JPEG支持无关。JPEG已经被支持了,但是,我的代码中有一些错误。此外,我使用了不同的方法来缩放图像

  • 第一个bug出现在这一行:
  • ImageIO.write
    找不到与
    BuffereImage.TYPE_INT\u ARGB
    JPG
    /
    JPEG
    匹配的
    ImageWriter
    。因此,我将其更改为
    BufferedImage.TYPE\u INT\u RGB

  • 修复此问题将导致在
    ato.filter(图像、缩放图像)
  • 我不知道这个异常的原因是什么以及如何修复它,但是使用
    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
    }
    
    Exception in thread "main" java.awt.image.ImagingOpException: Unable to transform src image
    
    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
    }