Pergunta

Estou recebendo uma NPE ao tentar ler em um arquivo de imagem, e eu não posso para a vida de me descobrir o porquê. Aqui é a minha linha:

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

imgPath é basicamente garantido para ser válida e à direita antes que ela chegue aqui ele copia o arquivo do servidor. Quando ela atinge essa linha, eu recebo este rastreamento de pilha:

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>

Além disso, este é jogado em minha janela de saída:

Não é possível criar icofile: Não é possível ler bytes: 2

Eu não tenho idéia o que está acontecendo, especialmente desde que o construtor de arquivos está tendo sucesso. Eu não consigo encontrar ninguém que tenha tido um problema semelhante. Alguém tem alguma ideia? (Java 5, se isso faz alguma diferença)

Foi útil?

Solução

Eu coloquei em torno de alguns mais e descobri que você pode especificar quais ImageReader ImageIO vai usar e lê-lo dessa forma. Eu coloquei em torno de nossa base de código e descobriu que já tinha uma função no lugar para fazer exatamente o que eu estava tentando realizar aqui. Apenas para qualquer outra pessoa que corre para um problema semelhante, aqui está o cerne do código (alguns dos porcaria é definido acima, mas isso deve ajudar alguém que tenta fazê-lo):

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

Obrigado pelas sugestões e ajuda todos.

Outras dicas

O construtor Arquivo quase certamente irá ter sucesso, , independentemente de ele aponta para um arquivo válido / existente . No mínimo, eu iria verificar se o arquivo subjacente existe através do método exists().

Observe também que ImageIO.read não é thread-safe (reutiliza ImageReaders em cache que não são thread-safe).

Isto significa que você não pode ler facilmente vários arquivos em paralelo. Para fazer isso, você vai ter que lidar com ImageReaders si mesmo.

Você considerou que o arquivo pode simplesmente ser corrompido, ou que ImageIO está tentando lê-lo como o tipo errado de arquivo?

pesquisando para os resultados da turma ICOReader em um hit: IconsFactory de Jide-comum .
Aparentemente, eles tinham o mesmo problema:

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

O que eles fizeram em vez disso?

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

Então você pode querer tentar a mesma abordagem: ler os bytes crus e uso Toolkit para criar uma imagem a partir deles.

"é um jpeg, mas não tem um jpeg extensão. "

Isso poderia ser ele.

Parece que a biblioteca AC.lib-ICO está jogando o NPE. Uma vez que esta biblioteca é a intenção de ler o formato de arquivo do Microsoft ICO, um JPEG pode ser um problema para ele.

Considere fornecer explicitamente o formato usando um método alternativo .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top