Как изменить размер изображения в каталоге? - PullRequest
2 голосов
/ 20 марта 2012

Этот код пытается изменить размер изображения в каталоге с именем "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()));
    }
}

enter image description here

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

Ответы [ 5 ]

2 голосов
/ 20 марта 2012

Я не уверен, почему итерация списка файлов будет мешать генерации миниатюр, но вы в частном порядке упомянули мне, что используете 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...

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

2 голосов
/ 20 марта 2012

ОК, я понял это.сейчас работает.Вы (или тот, кто создал загружаемый проект, который вы вставили здесь) используете 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 возвращает имя и путь.Дайте мне знать, как это работает

2 голосов
/ 20 марта 2012

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

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

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

0 голосов
/ 20 марта 2012

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

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

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

0 голосов
/ 20 марта 2012

Один очевидный способ отладки этого для вывода конкретного 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())

...