从Android的字节数组中读取EXIF数据 [英] Reading EXIF data from byte array in android

查看:377
本文介绍了从Android的字节数组中读取EXIF数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从摄像机输出的字节数组数据读取EXIF数据。我知道我可以使用exifInterface文件中读取EXIF数据。但是,这需要我的字节数组数据写入文件,读取EXIF数据,然后删除该文件。我想读的EXIF数据,而不必首先写入文件。

I would like to read EXIF data from byte array data output from the camera. I know I can read EXIF data from a file using exifInterface. But this would require me to write the byte array data to file, read the EXIF data, and then delete the file. I would like to read the EXIF data without first having to write to file.

有没有人有什么想法?

推荐答案

相机应​​用包括EXIF类,它可以做到这一点:

The Camera app includes an EXIF class which can do this:

<一个href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android-apps/4.1.1_r1/com/android/camera/Exif.java">http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android-apps/4.1.1_r1/com/android/camera/Exif.java

在code是不错的,短的,所以我在这里重现它的情况下链接中断。请注意,它不处理的镜像的方向,但你可以看到它是pretty的微不足道的改变。

The code is nice and short, so I've reproduced it here in case that link breaks. Note that it doesn't handle the mirrored orientations, but you can see that it is pretty trivial to change.

import android.util.Log;

public class Exif {
    private static final String TAG = "CameraExif";

    // Returns the degrees in clockwise. Values are 0, 90, 180, or 270.
    public static int getOrientation(byte[] jpeg) {
        if (jpeg == null) {
            return 0;
        }

        int offset = 0;
        int length = 0;

        // ISO/IEC 10918-1:1993(E)
        while (offset + 3 < jpeg.length && (jpeg[offset++] & 0xFF) == 0xFF) {
            int marker = jpeg[offset] & 0xFF;

            // Check if the marker is a padding.
            if (marker == 0xFF) {
                continue;
            }
            offset++;

            // Check if the marker is SOI or TEM.
            if (marker == 0xD8 || marker == 0x01) {
                continue;
            }
            // Check if the marker is EOI or SOS.
            if (marker == 0xD9 || marker == 0xDA) {
                break;
            }

            // Get the length and check if it is reasonable.
            length = pack(jpeg, offset, 2, false);
            if (length < 2 || offset + length > jpeg.length) {
                Log.e(TAG, "Invalid length");
                return 0;
            }

            // Break if the marker is EXIF in APP1.
            if (marker == 0xE1 && length >= 8 &&
                    pack(jpeg, offset + 2, 4, false) == 0x45786966 &&
                    pack(jpeg, offset + 6, 2, false) == 0) {
                offset += 8;
                length -= 8;
                break;
            }

            // Skip other markers.
            offset += length;
            length = 0;
        }

        // JEITA CP-3451 Exif Version 2.2
        if (length > 8) {
            // Identify the byte order.
            int tag = pack(jpeg, offset, 4, false);
            if (tag != 0x49492A00 && tag != 0x4D4D002A) {
                Log.e(TAG, "Invalid byte order");
                return 0;
            }
            boolean littleEndian = (tag == 0x49492A00);

            // Get the offset and check if it is reasonable.
            int count = pack(jpeg, offset + 4, 4, littleEndian) + 2;
            if (count < 10 || count > length) {
                Log.e(TAG, "Invalid offset");
                return 0;
            }
            offset += count;
            length -= count;

            // Get the count and go through all the elements.
            count = pack(jpeg, offset - 2, 2, littleEndian);
            while (count-- > 0 && length >= 12) {
                // Get the tag and check if it is orientation.
                tag = pack(jpeg, offset, 2, littleEndian);
                if (tag == 0x0112) {
                    // We do not really care about type and count, do we?
                    int orientation = pack(jpeg, offset + 8, 2, littleEndian);
                    switch (orientation) {
                        case 1:
                            return 0;
                        case 3:
                            return 180;
                        case 6:
                            return 90;
                        case 8:
                            return 270;
                    }
                    Log.i(TAG, "Unsupported orientation");
                    return 0;
                }
                offset += 12;
                length -= 12;
            }
        }

        Log.i(TAG, "Orientation not found");
        return 0;
    }

    private static int pack(byte[] bytes, int offset, int length,
            boolean littleEndian) {
        int step = 1;
        if (littleEndian) {
            offset += length - 1;
            step = -1;
        }

        int value = 0;
        while (length-- > 0) {
            value = (value << 8) | (bytes[offset] & 0xFF);
            offset += step;
        }
        return value;
    }
}

顺便说一句,我的的建议每一位Android开发者下载源所有的股票应用程序,以及GoogleIO应用程序。他们是满好看的code /黑客,谷歌已经写避开弱点Android的。

By the way, I highly recommend every Android developer downloads the source for all the stock apps, and the GoogleIO app. They're full of nice code/hacks that Google have written to get around weaknesses in Android.

这篇关于从Android的字节数组中读取EXIF数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆