Convert a PNG to PPM using ImageIO TwelveMonkey extension

217 views Asked by At

I have a requirement to convert a PNG file to PPM file. In the same project, I have used TwelveMonkey extension to convert a PPM to PNG and it results perfectly. 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.

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
1

There are 1 answers

1
Harald K On BEST ANSWER

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.

This is easy to fix, just convert your image to TYPE_3BYTE_BGR instead of TYPE_INT_RGB, and your code works fine. In 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. So I think this could be classified as a bug.