Copy and write image launches java.lang.Illegalargumentexception: image == null!

Asked

Viewed 326 times

4

I created an algorithm to traverse a directory tree and mirror its contents. The exception is when the program enters a directory with 400 images. It copies the images until it reaches an image around 320 and casts the following exception, in the copy methodFile, conditional isImagemJPG:

Exception in thread "main" java.lang.IllegalArgumentException: image == null!
at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(Unknown Source)
at javax.imageio.ImageIO.getWriter(Unknown Source)
at javax.imageio.ImageIO.write(Unknown Source)
at Main.copiaArquivo(Main.java:53)
at Main.entraDiretorio(Main.java:44)
at Main.entraDiretorio(Main.java:42)
at Main.entraDiretorio(Main.java:42)
at Main.entraDiretorio(Main.java:42)
at Main.main(Main.java:31)

The code is as follows::

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import javax.imageio.ImageIO;

public class Main {

private static File raizDiretorio;
private static File raizDiretorioCP;
private static String caminho = "D:\\Ultimate Collection\\info\\xyz\\";

public static void main(String[] args) throws IOException {

    raizDiretorio = new File(caminho);
    raizDiretorioCP = new File(caminho + "copia\\");
    raizDiretorioCP.mkdir();

    File[] files = raizDiretorio.listFiles();

    entraDiretorio(files);

}

private static void entraDiretorio(File[] files) throws FileNotFoundException, IOException {
    for (File file : files) {
        if (file.isDirectory() && !file.getAbsolutePath().equals(raizDiretorioCP.getAbsolutePath())) {
            File[] listSubDiretorio = file.listFiles();
            file = new File(preparaCaminhoFileSaida(file));
            System.out.println("Criando diretorio " + file.getAbsolutePath());
            file.mkdir();
            entraDiretorio(listSubDiretorio);
        } else if (file.isFile() && !file.getAbsolutePath().equals(raizDiretorioCP.getAbsolutePath())) {
            copiaArquivo(file);
        }
    }
}

private static void copiaArquivo(File file) throws FileNotFoundException, IOException {
    String caminhoSaida = preparaCaminhoFileSaida(file);
    if (isImagemJPG(file)) {
        BufferedImage img = ImageIO.read(file);
        System.out.println("Copiando imagem de :" + file.getPath() + "\n para: " + caminhoSaida);
        ImageIO.write(img, "jpg", new File(caminhoSaida));

    } else

    {

        File outFile = new File(caminhoSaida);
        if (!outFile.exists() && outFile.isDirectory())
            outFile.mkdir();
        System.out.println("Copiando arquivo: " + file.getAbsolutePath());
        OutputStream ou = new FileOutputStream(outFile);
        OutputStreamWriter osw = new OutputStreamWriter(ou);
        BufferedWriter bw = new BufferedWriter(osw);

        String texto = "";
        BufferedReader reader = new BufferedReader(new FileReader(file));
        String linha = reader.readLine();
        while (linha != null) {
            texto += linha;
            linha = reader.readLine();
        }

        texto = texto.replaceAll("nomealeatorio", "");

        bw.write(texto);
        bw.close();

    }

}

private static boolean isImagemJPG(File file) {
    return file.getName().endsWith(".jpg");
}

private static String preparaCaminhoFileSaida(File file) throws IOException {
    String path = file.getAbsolutePath();
    path = path.replace(caminho, raizDiretorioCP.getCanonicalPath() + "\\");
    return path;
}
}

If I put a conditional to skip this photo that throws the exception the program continues but after a few photos it throws again the exception in another photo. I have already checked the extension of the photos and they are all jpg. There is no other file type in the directory. I don’t understand why to a certain extent the algorithm works and then it doesn’t.

  • Already checked if those files that launch the exception are even images. They may have the extension jpg and are not.

  • 1

    Some other points do not fit directly in the answer. Your code is loaded with methods and static variables (which is not a good sign). Also, it seems to me that you are reinventing the wheel... Take a look at the class Files, There is enough thing ready to walk file trees and do simple read/write/copy operations.

  • If the idea is to copy an entire directory take a look at FileUtils.copyDirectory library Apache Commons IO

1 answer

5


Of the documentation of ImageIO.read:

Returns a BufferedImage as a result of the decoding of File supplied with a ImageReader automatically chosen from among those currently registered. If no ImageReader registered claims to be able to read the resulting stream, null is returned [my annoyance].

img is null for some of your files jpg (you can confirm this by printing img). Probably this occurs because the method read can’t read some of the files. I can’t tell you exactly what’s making Imageio choke, but I know this class does not behave well with CMYK and some ICC color profiles.

That said, I don’t understand why you’re trying to "interpret" the files if the goal is just to copy them from one place to another. If you do not want to change the files a direct copy method like the below should solve your problem:

Files.copy(file.toPath(), new File(caminhoSaida).toPath());
  • Thanks, I didn’t know the Files class and it solved this problem and a few others! And really this code needed a refactoring. Thanks for the tips!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.