【问题标题】:Add JPEG encoder/decoder support to installed OpenJDK将 JPEG 编码器/解码器支持添加到已安装的 OpenJDK
【发布时间】:2020-03-11 03:28:22
【问题描述】:

我正在尝试缩放 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)
}

到目前为止,我能找到的最好的东西是这个答案 https://stackoverflow.com/a/16026254/4112200 ,它指出 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)

【问题讨论】:

    标签: java jpeg javax.imageio openjdk-12


    【解决方案1】:

    好的,这就是我解决这个问题的方法。

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

    1. 第一个错误在这一行:
    val scaledImage = BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB)
    

    ImageIO.write 找不到与 BufferedImage.TYPE_INT_ARGBJPG / JPEG 匹配的 ImageWriter。所以,我把它改成了BufferedImage.TYPE_INT_RGB

    1. 修复此问题会导致在ato.filter(image, scaledImage) 处引发异常
    Exception in thread "main" java.awt.image.ImagingOpException: Unable to transform src image
    

    我不知道该异常的原因是什么以及如何修复它,但使用 Graphics2D 对象来缩放和渲染图像对我有用。

    1. 即使生成了有效的图像文件,但它只包含黑色背景。那是因为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
    }
    

    【讨论】:

      猜你喜欢
      • 2012-11-24
      • 1970-01-01
      • 2015-11-05
      • 2019-05-21
      • 1970-01-01
      • 2017-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多