Как изменить размер изображения в каталоге?

Этот код пытается изменить размер изображения в каталоге с именем "imgs". К сожалению, по какой-то причине, когда я раскомментирую цикл listFiles(..) ImageIO.read(sourceImageFile) вернет ноль. Тем не менее, обработка одного и того же файла сразу за пределами цикла (res("imgs/foto_3.jpg")) работает. Таким образом, очевидно, этот цикл предотвращает чтение файлов. Решения?

import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import static org.imgscalr.Scalr.*;

public class App {

    public static void main(String[] args) throws IOException {
//        for (File sourceImageFile : new File("imgs").listFiles()) {
//            res("imgs/"+sourceImageFile.getName());
//        }
        res("imgs/foto_3.jpg");

    }

    public static void res(String arg) throws IOException {

        File sourceImageFile = new File(arg);
        BufferedImage img = ImageIO.read(sourceImageFile);

        BufferedImage thumbnail = resize(img, 500);

        thumbnail.createGraphics().drawImage(thumbnail, 0, 0, null);
        ImageIO.write(thumbnail, "jpg", new File("resized/" + sourceImageFile.getName()));
    }
}

Чтобы воспроизвести проблему, вы можете скачать проект Maven.

5 ответов

Решение

Я изменил метод Res:

public static void res(File arg) throws IOException {
        if (arg.contains(".DS_Store")) {
            return;
        }

Mac-проблема (или должна фильтровать не файлы изображений, как было предложено)!

Вы можете изменить res принять File объект, а не строка? Тогда вы могли бы написать следующее, что намного лучше:

for (File sourceImageFile : new File("imgs").listFiles()) {
    res(sourceImageFile);
}

Что касается вашего исходного вопроса, попробуйте добавить несколько операторов трассировки или использовать отладчик, чтобы найти, что именно передается res,

Хорошо, я понял это. сейчас работает. Вы (или тот, кто создал загружаемый проект, который вы вставили здесь) используете Mac OS, и он автоматически создает файл.DS_Store. Когда вы пытаетесь передать его методу res, он не знает, как обрабатывать файл без изображения, и действует как ноль.

   public static void main(String[] args) throws IOException {
        for (File sourceImageFile : new File("imgs").listFiles()) {
            if (sourceImageFile.getName().endsWith(".jpg"))
                res(sourceImageFile.getAbsolutePath());
        }
    }

Это модифицированный метод void main. это работает, вы можете уточнить оператор if для более глубокой фильтрации неправильных файлов. Также я изменил аргумент, данный методу res. теперь это выглядит лучше, так как getAbsoulutePath возвращает имя и путь. Дайте мне знать, как это работает

Я не уверен, почему итерация листинга файлов будет мешать генерации миниатюр, но вы в частном порядке упомянули мне, что используете imgscalr, и вам было любопытно, как будет выглядеть правильный код для пакетной обработки каталога, поэтому я написал этот пример код для вас.

Код ниже будет обрабатывать любой каталог (imgs жестко запрограммирован, чтобы соответствовать вашему примеру кода) и записать его в любой другой каталог (resized используется, чтобы оставаться последовательным - смело меняйте любой каталог)

import static org.imgscalr.Scalr.*;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ScaleDirExample {
    public static void main(String[] args) throws IOException {
        File[] images = new File("imgs").listFiles();

        for (File f : images) {
            System.out.println("Processing: " + f.getName() + "...");

            if (f.isDirectory()) {
                System.out.println("\tSkipping, file is a directory...");
                continue;
            } else
                process(f);
        }
    }

    private static void process(File file) throws IOException {
        // Load image.
        BufferedImage image = ImageIO.read(file);

        // Resize image.
        image = resize(image, 500);

        // Save the resized image as the thumbnail.
        saveThumbnail(file, image);
    }

    private static void saveThumbnail(File originalFile, BufferedImage thumbnail)
            throws IOException {
        String filename = originalFile.getName();

        // Determine file extension.
        String fileExt = filename.substring(filename.lastIndexOf('.') + 1);

        // Save the thumbnail to the resized dir.
        ImageIO.write(thumbnail, fileExt, new File("resized/" + filename));
    }
}

Призыв к resize(image, 500) может быть изменен в соответствии с любым из методов Scalr.resize - вы можете пропустить фильтры или улучшить качество, если хотите.

Пример вывода из моей тестовой установки выглядит так:

Processing: flower-dog-gimp.jpg...
Processing: flower-dog.jpg...
Processing: logoOXdaComida.png...
Processing: mr-t-thumbnail.jpg...
Processing: mr-t.jpg...
Processing: problem-trans-peter-griffin.png...

Надеюсь, это поможет!

Один очевидный способ отладки этого для вывода конкретного sourceImageFile тот ImageIO.read(..) возвращает ноль на. Я подозреваю, потому что listFiles выдаст вам список всех файлов и каталогов, которые находятся в каталоге изображений. listFiles Javadoc. Вы можете предотвратить это, используя FileFilter, который гарантирует, что listFiles возвращает только файлы и, кроме того, файлы правильного типа.

Ниже приведен пример фильтра файлов, который возвращает только файл:

import java.io.FileFilter
class RegularFilesOnlyFileFilter implements FileFilter {
   public boolean accept(File pathName) {
       return pathName.isFile();
   }
}

Способ использования этого фильтра заключается в следующем - new File("imgs").listFiles(new RegularFilesOnlyFilesFilter())

Другие вопросы по тегам