Question

I'm getting an NPE while trying to read in an image file, and I can't for the life of me figure out why. Here is my line:

BufferedImage source = ImageIO.read(new File(imgPath));

imgPath is basically guaranteed to be valid and right before it gets here it copies the file from the server. When it hits that line, I get this stack trace:

Exception in thread "Thread-26" java.lang.NullPointerException
    at com.ctreber.aclib.image.ico.ICOReader.getICOEntry(ICOReader.java:120)
    at com.ctreber.aclib.image.ico.ICOReader.read(ICOReader.java:89)
    at javax.imageio.ImageIO.read(ImageIO.java:1400)
    at javax.imageio.ImageIO.read(ImageIO.java:1286)
    at PrintServer.resizeImage(PrintServer.java:981)    <---My function
    <Stack of rest of my application here>

Also, this is thrown into my output window:

Can't create ICOFile: Can't read bytes: 2

I have no idea what is going on, especially since the File constructor is succeeding. I can't seem to find anybody who has had a similar problem. Anybody have any ideas? (Java 5 if that makes any difference)

Was it helpful?

Solution

I poked around some more and found that you can specify which ImageReader ImageIO will use and read it in that way. I poked around our codebase and found that we already had a function in place for doing EXACTLY what I was trying to accomplish here. Just for anybody else who runs into a similar issue, here is the crux of the code (some of the crap is defined above, but this should help anybody who tries to do it):

File imageFile = new File(filename);
Iterator<ImageReader> imageReaders = ImageIO.getImageReadersByFormatName("jpeg");
if ( imageReaders.hasNext() ) {
    imageReader = (ImageReader)imageReaders.next();
    stream = ImageIO.createImageInputStream(imageFile);
    imageReader.setInput(stream, true);
    ImageReadParam param = imageReader.getDefaultReadParam();
    curImage = imageReader.read(0, param);
}

Thanks for the suggestions and help all.

OTHER TIPS

The File constructor will almost certainly succeed, regardless of whether it points to a valid/existing file. At the very least, I'd check whether your underlying file exists via the exists() method.

Also note that ImageIO.read is not thread-safe (it reuses cached ImageReaders which are not thread-safe).

This means you can't easily read multiple files in parallel. To do that, you'll have to deal with ImageReaders yourself.

Have you considered that the file may simply be corrupted, or that ImageIO is trying to read it as the wrong type of file?

Googling for the ICOReader class results in one hit: IconsFactory from jide-common.
Apparently they had the same problem:

// Using ImageIO approach results in exception like this.
//    Exception in thread "main" java.lang.NullPointerException
//            at com.ctreber.aclib.image.ico.ICOReader.getICOEntry(ICOReader.java:120)
//            at com.ctreber.aclib.image.ico.ICOReader.read(ICOReader.java:89)
//            at javax.imageio.ImageIO.read(ImageIO.java:1400)
//            at javax.imageio.ImageIO.read(ImageIO.java:1322)
//            at com.jidesoft.icons.IconsFactory.b(Unknown Source)
//            at com.jidesoft.icons.IconsFactory.a(Unknown Source)
//            at com.jidesoft.icons.IconsFactory.getImageIcon(Unknown Source)
//            at com.jidesoft.plaf.vsnet.VsnetMetalUtils.initComponentDefaults(Unknown Source)

//    private static ImageIcon createImageIconWithException(final Class<?> baseClass, final String file) throws IOException {
//        try {
//            InputStream resource =
//                    baseClass.getResourceAsStream(file);
//            if (resource == null) {
//                throw new IOException("File " + file + " not found");
//            }
//            BufferedInputStream in =
//                    new BufferedInputStream(resource);
//            return new ImageIcon(ImageIO.read(in));
//        }
//        catch (IOException ioe) {
//            throw ioe;
//        }
//    }

What did they do instead?

private static ImageIcon createImageIconWithException(
        final Class<?> baseClass, final String file)
        throws IOException {
    InputStream resource = baseClass.getResourceAsStream(file);

    final byte[][] buffer = new byte[1][];
    try {
        if (resource == null) {
            throw new IOException("File " + file + " not found");
        }
        BufferedInputStream in = new BufferedInputStream(resource);
        ByteArrayOutputStream out = new ByteArrayOutputStream(1024);

        buffer[0] = new byte[1024];
        int n;
        while ((n = in.read(buffer[0])) > 0) {

            out.write(buffer[0], 0, n);
        }
        in.close();
        out.flush();
        buffer[0] = out.toByteArray();
    } catch (IOException ioe) {
        throw ioe;
    }

    if (buffer[0] == null) {
        throw new IOException(baseClass.getName() + "/" + file
                + " not found.");
    }
    if (buffer[0].length == 0) {
        throw new IOException("Warning: " + file
                + " is zero-length");
    }

    return new ImageIcon(Toolkit.getDefaultToolkit().createImage(
            buffer[0]));
}

So you might want to try the same approach: read the raw bytes and use Toolkit to create an image from them.

"it's a jpeg but doesn't have a jpeg extension."

That might be it.

It appears that the library AC.lib-ICO is throwing the NPE. Since this library is intended to read the Microsoft ICO file format, a JPEG might be a problem for it.

Consider explicitly providing the format using an alternative method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top