NullPointerException с использованием ImageIO.read - PullRequest
0 голосов
/ 18 мая 2009

Я получаю NPE при попытке прочитать файл изображения, и я не могу понять, почему. Вот моя строка:

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

imgPath в основном гарантированно действителен, и непосредственно перед тем, как попасть сюда, он копирует файл с сервера. Когда он попадает в эту строку, я получаю следующую трассировку стека:

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>

Кроме того, это выброшено в мое окно вывода:

Не могу создать ICOFile: Не могу прочитать байты: 2

Понятия не имею, что происходит, тем более что конструктор File успешно работает. Кажется, я не могу найти никого, кто имел подобную проблему. У кого-нибудь есть идеи? (Java 5, если это имеет какое-либо значение)

Ответы [ 6 ]

2 голосов
/ 18 мая 2009

Я еще немного покопался и обнаружил, что вы можете указать, какой ImageReader ImageIO будет использовать, и читать его таким образом. Я осмотрел нашу кодовую базу и обнаружил, что у нас уже есть функция, позволяющая делать именно то, что я пытался сделать здесь. Просто для всех, кто сталкивается с подобной проблемой, вот суть кода (часть дерьма определена выше, но это должно помочь всем, кто пытается это сделать):

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);
}

Спасибо за предложения и помогите всем.

1 голос
/ 15 апреля 2013

Также обратите внимание, что ImageIO.read не является поточно-ориентированным (он повторно использует кэшированные ImageReader s, которые не являются потоко-безопасными).

Это означает, что вы не можете легко читать несколько файлов параллельно. Для этого вам придется иметь дело с ImageReader s самостоятельно.

1 голос
/ 18 мая 2009

Конструктор файлов почти наверняка завершится успешно, независимо от того, указывает ли он на действительный / существующий файл . По крайней мере, я бы проверил, существует ли ваш базовый файл с помощью метода exists().

0 голосов
/ 18 мая 2009

"это JPEG, но не имеет JPEG расширение. "

Это может быть и так.

Похоже, что библиотека AC.lib-ICO выбрасывает NPE. Поскольку эта библиотека предназначена для чтения файлов формата Microsoft ICO, может возникнуть проблема с JPEG.

Попробуйте явно указать формат, используя альтернативный метод .

0 голосов
/ 18 мая 2009

Google для класса ICOReader приводит к одному удару: IconsFactory из jide-common .
Видимо у них была такая же проблема:

// 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;
//        }
//    }

Что они сделали вместо этого?

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]));
}

Так что вы можете попробовать тот же подход: прочитать необработанные байты и использовать Toolkit для создания изображения из них.

0 голосов
/ 18 мая 2009

Считаете ли вы, что файл может быть просто поврежден или ImageIO пытается прочитать его как неправильный тип файла?

...