jauharshaikh / metadata-extractor

Automatically exported from code.google.com/p/metadata-extractor
0 stars 0 forks source link

Support javax.imageio #3

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Investigate supporting javax.imageio types:

{{{
Metadata readMetadata(IIOMetadata metadata)
Metadata readMetadata(ImageInputStream in) 
Metadata readMetadata(IIOImage image)
Metadata readMetadata(ImageReader reader)
}}}

Original issue reported on code.google.com by drewnoakes on 24 Apr 2011 at 6:26

GoogleCodeExporter commented 8 years ago

Original comment by drewnoakes on 24 Apr 2011 at 6:26

GoogleCodeExporter commented 8 years ago
http://download.oracle.com/javase/1.4.2/docs/guide/imageio/

Original comment by drewnoakes on 30 Apr 2011 at 7:24

GoogleCodeExporter commented 8 years ago

Original comment by drewnoakes on 16 Oct 2012 at 4:03

GoogleCodeExporter commented 8 years ago
Very interesting!

https://community.oracle.com/thread/1264022?tstart=559 might contain some 
relevant code (e.g. how to get EXIF info from an IIOMetadata-object, as a 
byte[])

Original comment by eirik.ly...@gmail.com on 12 Feb 2014 at 9:53

GoogleCodeExporter commented 8 years ago
A basic implementation of readMetadata(ImageInputStream):

    private Metadata readMetadata(final ImageInputStream imageInputStream) throws ImageProcessingException, IOException {

        // ImageMetadataReader needs a BufferedInputStream
        // - ImageInputStream does not implement InputStream, we need a wrapper
        // - ImageMetadataReader does not implement available() or length(), so, what's a boy to do?
        // - ImageMetadataReader indiscriminately calls close() on *my* stream, but that is a no-op here
        BufferedInputStream bis = new BufferedInputStream(new InputStream() {
            @Override
            public int read() throws IOException {
                return imageInputStream.read();
            }
            public int available() throws IOException {
                return Integer.MAX_VALUE;
            }
        });

        imageInputStream.mark();

        try {
            imageInputStream.seek(0);
            return ImageMetadataReader.readMetadata(bis, false);
        } finally {
            imageInputStream.reset();
        }
    }

Original comment by eirik.ly...@gmail.com on 13 Feb 2014 at 9:19

GoogleCodeExporter commented 8 years ago
Similarly, an attempt at reading metadata based on an IIOMetadata object. This 
would probably also cater for readMetadata (ImageReader) and readMetadata 
(IIOImage).

    private Metadata readMetadata(IIOMetadata iioMetadata) {

        // Metadata in ImageIO works like this
        // - ImageIO reads metadata into an IIOMetadata object, exposing them in an XML-like structure
        // - Well-known metadata is placed in a well-known structure, ref
        //   http://docs.oracle.com/javase/6/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html#image
        // - Unknown metadata segments is included as "unknown" elements
        // This code then does as follows
        // - First find all unknown segments, and send them to the JpegMetadataReader for parsing
        // - Next add all the well-known information
        // - Since JpegMetadataReader always creates a new object, it must be done in this sequence

        // Find the suitable JPEG-node, and take it from there
        String JPEGMetaFormat = "javax_imageio_jpeg_image_1.0";
        IIOMetadataNode root = (IIOMetadataNode) iioMetadata.getAsTree(JPEGMetaFormat);
        IIOMetadataNode markerSequence = (IIOMetadataNode) root.getElementsByTagName("markerSequence").item(0);

        // Find the various unknown segments present in the IIOMetadata object; these will be
        // passed to the JpegMetadataReader for processing
        JpegSegmentData jpegSegmentData = new JpegSegmentData();
        NodeList unknowns = markerSequence.getElementsByTagName("unknown");
        for (int i = 0; i < unknowns.getLength(); i++) {
            IIOMetadataNode unknown = (IIOMetadataNode) unknowns.item(i);
            String segmentMarker = unknown.getAttribute("MarkerTag");
            jpegSegmentData.addSegment((byte) Integer.parseInt(segmentMarker), (byte[]) unknown.getUserObject());
        }

        // First load the unknown segments. Do this first, because we can't extract JpegSegmentData
        // into an already existing Metadata-object
        Metadata metadata = JpegMetadataReader.extractMetadataFromJpegSegmentReader(jpegSegmentData);

        // Now load standard Jpeg metadata. Since this is understood by the IIOMetadata-code, these
        // Note that this code only handles a strict subset of
        // values (only parts of the SOF-tag); there are plenty others in the defined metadata format
        // that are not handled, ref
        if (!metadata.containsDirectory(JpegDirectory.class)) {
            final IIOMetadataNode sof = (IIOMetadataNode) markerSequence.getElementsByTagName("sof").item(0);
            final String samplePrecision = sof.getAttribute("samplePrecision");
            final String numLines = sof.getAttribute("numLines");
            final String samplesPerLine = sof.getAttribute("samplesPerLine");
            JpegDirectory jpegDirectory = metadata.getOrCreateDirectory(JpegDirectory.class);
            jpegDirectory.setInt(JpegDirectory.TAG_JPEG_DATA_PRECISION, Integer.valueOf(samplePrecision));
            jpegDirectory.setInt(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT, Integer.valueOf(numLines));
            jpegDirectory.setInt(JpegDirectory.TAG_JPEG_IMAGE_WIDTH, Integer.valueOf(samplesPerLine));
        }

        return metadata;
    }

Original comment by eirik.ly...@gmail.com on 13 Feb 2014 at 11:22