Java: Как добавить метаинформацию к нескольким типам изображений универсальным способом

Что должно быть сделано

Мне нужно добавить пользовательскую мета-информацию в файлы изображений.
Поддерживаемые типы должны быть: JPEG, GIF, BMP, TIF, PNG

Как это делается

Я решил использовать метаданные imageio Standard, чтобы обеспечить общее решение для всех типов файлов.
Я также использую библиотеку Java Advanced Imaging, так как не все типы файлов поддерживаются общим API.

Вот фрагмент кода основной функции, которая добавляет метаданные:

    public static byte[] writeCustomMetaInformation(byte[] imageByteArray, String contentType) throws IOException {
    ImageWriter writer = null;

    String formatName = "javax_imageio_1.0";

    ImageOutputStream stream = null;
    if (contentType.toLowerCase().contains("gif")) {
        IIORegistry registry = IIORegistry.getDefaultInstance();
        registry.registerServiceProvider(new GIFImageWriterSpi());
        writer = ImageIO.getImageWritersByFormatName("gif").next();

    } else if (contentType.toLowerCase().contains("png")) {
        writer = ImageIO.getImageWritersByFormatName("png").next();

    } else if (contentType.toLowerCase().contains("bmp")) {
        IIORegistry registry = IIORegistry.getDefaultInstance();
        registry.registerServiceProvider(new BMPImageWriterSpi());
        writer = ImageIO.getImageWritersByFormatName("bmp").next();

    } else if (contentType.toLowerCase().contains("tif")) {
        IIORegistry registry = IIORegistry.getDefaultInstance();
        registry.registerServiceProvider(new TIFFImageWriterSpi());
        writer = ImageIO.getImageWritersByFormatName("tif").next();

    } else { //by default jpeg
        writer = ImageIO.getImageWritersByFormatName("jpeg").next();
    }

    BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(imageByteArray));

    ImageWriteParam writeParam = writer.getDefaultWriteParam();
    ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);

    /*
     * Add metadata to the file
     * See http://docs.oracle.com/javase/6/docs/api/javax/imageio/metadata/doc-files/standard_metadata.html
     * for reference on default image metadata DTD
     */
    IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);

    IIOMetadataNode root = new IIOMetadataNode(formatName);

    //Add RGB tag, otherwise BMP writing throws NPE
    IIOMetadataNode chroma = new IIOMetadataNode("Chroma");
    IIOMetadataNode colorSpaceType = new IIOMetadataNode("ColorSpaceType");
    colorSpaceType.setAttribute("name", "RGB");
    chroma.appendChild(colorSpaceType);
    root.appendChild(chroma);

    IIOMetadataNode text = new IIOMetadataNode("Text");
    IIOMetadataNode textEntry = new IIOMetadataNode("TextEntry");
    textEntry.setAttribute("keyword", "metainformation");
    textEntry.setAttribute("value", "This is some custom meta information!");
    textEntry.setAttribute("encoding", "UTF-8");
    textEntry.setAttribute("language", "EN");
    textEntry.setAttribute("compression", "none");
    text.appendChild(textEntry);

    root.appendChild(text);

    metadata.mergeTree(formatName, root);

    // writing the data
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    stream = ImageIO.createImageOutputStream(baos);

    writer.setOutput(stream);

    IIOImage img = new IIOImage(bufferedImage, null, metadata);
    writer.write(metadata, img, writeParam);
    stream.close();

    return baos.toByteArray();
}

Что в итоге

Я использую ImageMagick -verbose для просмотра результата добавления метаинформации.

  1. В файлы JPG, PNG и GIF добавлена ​​метаинформация
  2. BMP и TIF ​​либо не добавили метаинформацию, либо ImageMagick не может ее прочитать.

Итак, кто-нибудь знает, почему метаинформация, добавленная в BMP и TIF, кажется, не вступает в силу? Стандартные метаданные DTD не применимы к ним? Должен ли я использовать метаданные BMP/TIF вместо этого?

Если вы хотите проверить поведение, вот ссылка на полностью настроенный проект, который демонстрирует преобразование и его проблемы.

0 ответов

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