How to get Camera RAW metadata info programmatical

2019-05-27 07:12发布

问题:

I have an app, which sets the hardware parameters of the Camera programmatically.

However, as I've been told, and have come to observe, not all chipsets support all parameters.

For example, the Nexus 4 (Qualcomm) has sharpness, and sharpness-max parameters, the Galaxy Note II 3g doesn't have any.

Hence, when I set sharpness parameter, the Nexus responds well, but the Galaxy force closes:

java.lang.RuntimeException: setParameters failed
at android.hardware.Camera.native_setParameters(Native Method)
at android.hardware.Camera.setParameters(Camera.java:1452)

My question is, how can I get the RAW info programmatically? I need to get the parameters, their values, and whether they exist or not.

I wish to get the RAW-Metadata parameters, as like this: database

回答1:

Alright, thought this would be a fun bit of practice. So, Android does not give a public API into this information. Why? I have no idea. Looks like you can do a Camera.Parameters#get(String) to check for any particular parameter that you're interested in, but lets say you're greedy and want the whole list to yourself. In that case, we can dive in using Reflection, but be aware that there is a strong possibility that this will not work on all versions of Android or may break in future versions. With that said, here's how you do it:

private static Map<String, String> getFullCameraParameters (Camera cam) {
    Map<String, String> result = new HashMap<String, String>(64);
    final String TAG = "CameraParametersRetrieval";

    try {
        Class camClass = cam.getClass();

        //Internally, Android goes into native code to retrieve this String of values
        Method getNativeParams = camClass.getDeclaredMethod("native_getParameters");
        getNativeParams.setAccessible(true);

        //Boom. Here's the raw String from the hardware
        String rawParamsStr = (String) getNativeParams.invoke(cam);

        //But let's do better. Here's what Android uses to parse the
        //String into a usable Map -- a simple ';' StringSplitter, followed
        //by splitting on '='
        //
        //Taken from Camera.Parameters unflatten() method
        TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(';');
        splitter.setString(rawParamsStr);

        for (String kv : splitter) {
            int pos = kv.indexOf('=');
            if (pos == -1) {
                continue;
            }
            String k = kv.substring(0, pos);
            String v = kv.substring(pos + 1);
            result.put(k, v);
        }

        //And voila, you have a map of ALL supported parameters
        return result;
    } catch (NoSuchMethodException ex) {
        Log.e(TAG, ex.toString());
    } catch (IllegalAccessException ex) {
        Log.e(TAG, ex.toString());
    } catch (InvocationTargetException ex) {
        Log.e(TAG, ex.toString());
    }

    //If there was any error, just return an empty Map
    Log.e(TAG, "Unable to retrieve parameters from Camera.");
    return result;
}