【问题标题】:Image Metadata for a specified directory in JavaJava中指定目录的图像元数据
【发布时间】:2018-06-25 10:18:42
【问题描述】:

这里我有显示 1 个文件的元数据的代码。我想知道如何使用来显示指定目录的元数据?

import java.io.*;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import javax.imageio.*;
import javax.imageio.stream.*;
import javax.imageio.metadata.*;
import java.util.Scanner;

public class Metadata{

    public static void main(String[] args) {
        Metadata meta = new Metadata();


        if (new File("./images/test.jpg").exists()) {
            System.out.println("Can find " + "test.jpg file");
            meta.readAndDisplayMetadata("test.jpg");
        } else {
            System.out.println("cannot find file: " + "test.jpg");
        }


    }


    void readAndDisplayMetadata(String fileName ) {//or String fileName
        try {

            File file = new File(fileName);

            ImageInputStream iis = ImageIO.createImageInputStream(file);
            Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);



            if (readers.hasNext()) {

                // pick the first available ImageReader
                ImageReader reader = readers.next();

                // attach source to the reader
                reader.setInput(iis, true);

                // read metadata of first image
                IIOMetadata metadata = reader.getImageMetadata(0);

                String[] names = metadata.getMetadataFormatNames();
                int length = names.length;
                for (int i = 0; i < length; i++) {
                    System.out.println( "Format name: " + names[ i ] );
                    displayMetadata(metadata.getAsTree(names[i]));
                }
            }

        }
        catch (Exception e) {

            e.printStackTrace();
        }
    }

    void displayMetadata(Node root) {
        displayMetadata(root, 0);
    }

    void indent(int level) {
        for (int i = 0; i < level; i++)
            System.out.print("    ");
    }

    void displayMetadata(Node node, int level) {
        // print open tag of element
        indent(level);
        System.out.print("<" + node.getNodeName());
        NamedNodeMap map = node.getAttributes();
        if (map != null) {

            // print attribute values
            int length = map.getLength();
            for (int i = 0; i < length; i++) {
                Node attr = map.item(i);
                System.out.print(" " + attr.getNodeName() +
                                 "=\"" + attr.getNodeValue() + "\"");
            }
        }

        Node child = node.getFirstChild();
        if (child == null) {
            // no children, so close element and return
            System.out.println("/>");
            return;
        }

        // children, so close current tag
        System.out.println(">");
        while (child != null) {
            // print children recursively
            displayMetadata(child, level + 1);
            child = child.getNextSibling();
        }

        // print close tag of element
        indent(level);
        System.out.println("</" + node.getNodeName() + ">");
    }
} 

我使用过 DirectoryPath,但遗憾的是 ImageInputStream 没有目录接口。

是否有任何可用的库或框架可以自动将目录的图像元数据作为 JSON 提供?

【问题讨论】:

  • File API 有一个方法可以让你测试你的文件是否是一个目录。您可以使用list()listFiles() 来获取文件。现在您可以为每个文件使用readAndDisplayMetadata。这就是你所需要的。
  • 我能得到包括源代码在内的完整答案吗?

标签: java metadata nio javax.imageio


【解决方案1】:

鉴于您已经有代码来显示单个文件的元数据,修改它以支持多个文件是很简单的。

您只需要FileisDirectory()listFiles() 方法(或者,如果您使用的是Java 8+,则可以使用Files.list(Path) 方法,用于延迟迭代*)。

如果你的输入文件是一个目录,列出每个文件并递归:

public class Metadata {

    public static void main(String[] args) {
        Metadata meta = new Metadata();

        File file = new File(args[0]);

        if (file.exists()) {
            System.out.println("Can find " + file);
            meta.readAndDisplayMetadata(file);
        }
        else {
            System.out.println("cannot find file: " + file);
        }
    }

    void readAndDisplayMetadata(File file)  {
        // If you *don't* want recursive behavior, 
        // move this block "outside" or to a separate method 
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File f : files) {
                readAndDisplayMetadata(f);
            }
        }

        // Rest of method as is...
    }
}

*) 如果可以使用下面的更好,因为如果目录中有很多文件,上面的可能内存不足。

void readAndDisplayMetadata(File file) throws IOException {
    Path path = file.toPath();
    if (Files.isDirectory(path /* optional, handle symbolic links */)) {
        Files.list(path)
             .forEach(p -> readAndDisplayMetadata(p.toFile()));
    }

    // Rest of method as is...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 2015-04-26
    • 2011-04-26
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多