【问题标题】:How to keep compressing a image with ImageWriter in JAVA?如何在 JAVA 中使用 ImageWriter 继续压缩图像?
【发布时间】:2018-08-31 03:03:51
【问题描述】:

我需要压缩每个大于 500 KB 的图像。 所以,我正在尝试创建一个代码来测试每个压缩质量,直到我得到

我最大的问题是 ImageWriter 的 writer 方法将我的新图像附加到旧图像。所以,如果我有一个 600kb 的图像并写一个低质量的新图像,我将有 600kb + 可能 500kb(新图像的大小)在同一个 .jpg 文件中并且质量低。

我的代码:

public byte[] imageCompressor(String filePath, String newFileName, String formatName) throws IOException {

    File input = new File(filePath);
    BufferedImage image = ImageIO.read(input);

    File compressedImageFile = new File(newFileName);
    String compressedWithFormat = compressedImageFile + "." + formatName;
    OutputStream os = new FileOutputStream(compressedWithFormat);

    Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
    ImageWriter writer = (ImageWriter) writers.next();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    ImageOutputStream ios = ImageIO.createImageOutputStream(os);
    writer.setOutput(ImageIO.createImageOutputStream(baos));

    ImageWriteParam param = writer.getDefaultWriteParam();
    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    writer.write(null, new IIOImage(image, null, null), param);
    float contador = 1f;

    while (imageSizeChecker(compressedWithFormat) > 500) {
        param.setCompressionQuality(contador -= 0.09f); // Change the quality value you prefer
        writer.write(null, new IIOImage(image, null, null), param);
        System.out.println(imageSizeChecker(compressedWithFormat));
        writer.dispose();
    }

    writer.dispose();
    return baos.toByteArray();
}

public Long imageSizeChecker(String filePath) {
    File insertFile = new File(filePath);
    Long fileSize = insertFile.length() / 1024;

    return fileSize;
}

另外,我想以字节数组的形式返回图像(如下所示),并且我试图将参数上的图像文件作为字节数组发送(将字符串文件路径替换为字节 [] 文件路径)

【问题讨论】:

  • "ImageWriter 将我的新图像附加到旧图像" -- 所以将新图像写入不同的文件。这里有什么问题?
  • 他新建了一个,参数为newFileName。但我不想以手动方式执行此操作(可能代码需要将 1mb 的图像压缩两次以上,所以我需要继续创建三个或更多文件?)它将在机器人中运行,我需要压缩大于 500kb 的附件

标签: java java-io javax.imageio


【解决方案1】:

您不断将多个图像写入同一个 ByteArrayOutputStream。要重置输出流并丢弃每个图像之间的数据,您可以使用:

baos.reset();

还有其他几个问题——比如检查一个你从未写过的文件——但如果你发现附加数据是主要问题,这似乎就是原因。

【讨论】:

  • 我之前没有尝试过这个原因,因为我之前试图创建一个新的图像文件,然后我意识到通过字节数组尝试可以成功
猜你喜欢
  • 1970-01-01
  • 2011-02-12
  • 2018-04-20
  • 1970-01-01
  • 2020-04-27
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 2018-09-10
相关资源
最近更新 更多