Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extracting embedded JPEG from Nikon NEF #262

Closed
connyhald opened this issue Mar 31, 2017 · 4 comments
Closed

Extracting embedded JPEG from Nikon NEF #262

connyhald opened this issue Mar 31, 2017 · 4 comments

Comments

@connyhald
Copy link

Nikon raw files (NEF) have an embedded full-size JPEG included inside the EXIF header. I'm trying to extract that.

Using exiftool this would be:

$ exiftool -b -JpgFromRaw DSC_0001.NEF > out.jpg

or

$ exiftool -JpgFromRaw DSC_0001.NEF
Jpg From Raw   : (Binary data 1737279 bytes, use -b option to extract)

Running the following code

ExifSubIFDDirectory directory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
for (Tag tag : directory.getTags()) {
    logger.debug("[{}] - {} = {}", directory.getName(), tag.getTagName(), tag.getDescription());
}

results in

[Exif SubIFD] - New Subfile Type = Reduced-resolution image
[Exif SubIFD] - Compression = JPEG (old-style)
[Exif SubIFD] - X Resolution = 300 dots per inch
[Exif SubIFD] - Y Resolution = 300 dots per inch
[Exif SubIFD] - Resolution Unit = Inch
[Exif SubIFD] - Unknown tag (0x0201) = 1080832
[Exif SubIFD] - Unknown tag (0x0202) = 1737279
[Exif SubIFD] - YCbCr Positioning = Datum point

Now, comparing file sizes (1737279) with exiftools I figured 0x0202 should be the right one. So I do

byte[] imgData = directory.getByteArray(0x0202);

which results in imgData being null.

Am I doing it wrong or is this currently not possible with metadata-extractor?

@drewnoakes
Copy link
Owner

0x0201 is thumbnail offset, and 0x0202 is thumbnail length. The library should identify these tags property (I've created issue #263).

With these two values, you should be able to extract the thumbnail from the original file. Unfortunately the offset is relative to the beginning of Exif data, not to the beginning of the file.

The library could help with this. Just need to find the right API, and deal with a few edge cases.

Some prior discussion about this happened here:

5371827#commitcomment-20668173

@connyhald
Copy link
Author

Thanks for the quick response and the explanation. Makes sense now. I'll see how I can extract it semi-manual then.

@drewnoakes
Copy link
Owner

#149

@connyhald
Copy link
Author

So it looks like the offset is actually already relativ to the beginning of the file. At least with NEF files.

The following code works for me. Only tested with NEF coming from Nikon D5500. Maybe it is usefull for others as well.

    public byte[] extractJpegFromRaw(InputStream inStream) {

        try {
            Metadata metadata = ImageMetadataReader.readMetadata(inStream);

            ExifSubIFDDirectory directory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);

            int offset = directory.getInt(0x0201);
            int length = directory.getInt(0x0202);

            logger.info("Embedded jpeg offset: " + offset);
            logger.info("Embedded jpeg length: " + length);

            inStream.reset();
            inStream.skip(offset);

            byte[] jpegData = new byte[length];
            inStream.read(jpegData, 0, length);

            return jpegData;

        } catch (IOException | MetadataException | ImageProcessingException e) {
            e.printStackTrace();
            return new byte[0];
        }

    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants