简体   繁体   English

使用 ImageIO TwelveMonkey 扩展将 PNG 转换为 PPM

[英]Convert a PNG to PPM using ImageIO TwelveMonkey extension

I have a requirement to convert a PNG file to PPM file.我需要将 PNG 文件转换为 PPM 文件。 In the same project, I have used TwelveMonkey extension to convert a PPM to PNG and it results perfectly.在同一个项目中,我使用 TwelveMonkey 扩展将 PPM 转换为 PNG,结果非常完美。 But when trying the other way round, it results in error.但是当反过来尝试时,它会导致错误。

The output PPM file will always have height=16 and Width=60, so I also need to figure out a way to scale down the PNG without losing on quality drastically. output PPM 文件将始终具有 height=16 和 Width=60,因此我还需要找出一种方法来缩小 PNG 而不会大幅降低质量。

Dependencies:依赖项:

        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-jpeg</artifactId>
            <version>3.9.3</version>
        </dependency>
        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-tiff</artifactId>
            <version>3.9.3</version>
        </dependency>
        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-pnm</artifactId>
            <version>3.9.3</version>
        </dependency>

Code:代码:

public static File convertPngToPPM(File pngFile, String fileName) {

        File ppmFile=new File(fileName.concat(".ppm"));

        try {
            BufferedImage inputImage=ImageIO.read(pngFile);
            
            int imageHeight=inputImage.getHeight()==16 ? inputImage.getHeight() : 16;
            int imageWidth=inputImage.getWidth() == 60 ? inputImage.getWidth() : 60;

            BufferedImage resizedImage=resizeImage(inputImage, imageWidth, imageHeight);

            ImageIO.write(resizedImage, "ppm", ppmFile);

        } catch (Exception e){
            log.error(e.getMessage());
            log.error("Error reading the PPM file");
        }
        return null;
    }

private static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
        Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_SMOOTH);
        BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
        outputImage.getGraphics().drawImage(resultingImage, 0, 0, null);
        return outputImage;
    }

Error:错误:

2022-11-10 17:42:31.438 ERROR 17389 --- [  XNIO-1 task-1] com.mycompany.utilities.ImageUtilities   : Unsupported data type: 3

The error message just prints the exception message out of context, which isn't really that useful.错误消息只是在上下文之外打印异常消息,这并不是很有用。 If you instead print the full stack trace, you'll see that it points to a place in the code which says:如果你改为打印完整的堆栈跟踪,你会看到它指向代码中的一个地方,上面写着:

// TODO: Support TYPE_INT through conversion, if number of channels is 3 or 4 (TYPE_INT_RGB, TYPE_INT_ARGB)

In other words, BufferedImage.TYPE_INT_RGB isn't currently supported.换句话说,目前不支持BufferedImage.TYPE_INT_RGB

This is easy to fix, just convert your image to TYPE_3BYTE_BGR instead of TYPE_INT_RGB , and your code works fine.这很容易修复,只需将您的图像转换为TYPE_3BYTE_BGR而不是TYPE_INT_RGB ,您的代码就可以正常工作。 In resizeImage :resizeImage

BufferedImage outputImage = 
              new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_3BYTE_BGR);

PS: Throwing this exception is not really good behavior from the PNM plugin, as it should instead just report that it doesn't support this input, and ImageIO.write should return false . PS:抛出这个异常并不是 PNM 插件的好行为,因为它应该只是报告它不支持这个输入,而ImageIO.write应该返回false So I think this could be classified as a bug.所以我认为这可以归类为错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM