at.wada811.utils.CameraUtils.java Source code

Java tutorial

Introduction

Here is the source code for at.wada811.utils.CameraUtils.java

Source

/*
 * Copyright 2013 wada811<at.wada811@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package at.wada811.utils;

import android.annotation.TargetApi;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.media.CamcorderProfile;
import android.os.Build;
import at.wada811.android.library.R;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;

public class CameraUtils {

    private static final boolean DEBUG = false;

    /**
     * ?????
     * 
     * @param context
     * @return
     */
    public static boolean hasFeatureCamera(Context context) {
        boolean hasCamera = false;
        if (PreferenceUtils.contains(context, PackageManager.FEATURE_CAMERA)) {
            hasCamera = PreferenceUtils.getBoolean(context, PackageManager.FEATURE_CAMERA, hasCamera);
        } else {
            PackageManager packageManager = context.getApplicationContext().getPackageManager();
            hasCamera = packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA);
            PreferenceUtils.putBoolean(context, PackageManager.FEATURE_CAMERA, hasCamera);
        }
        return hasCamera;
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public static boolean isCameraDisabled(Context context) {
        if (AndroidUtils.isMoreThanBuildVersion(Build.VERSION_CODES.ICE_CREAM_SANDWICH)) {
            DevicePolicyManager devicePolicyManager = (DevicePolicyManager) context
                    .getSystemService(Context.DEVICE_POLICY_SERVICE);
            return devicePolicyManager.getCameraDisabled(null);
        } else {
            return false;
        }
    }

    /**
     * ?????
     * 
     * @param context
     * @return
     */
    public static boolean hasFeatureAutoFocus(Context context) {
        boolean hasAutoFocus = false;
        if (PreferenceUtils.contains(context, PackageManager.FEATURE_CAMERA_AUTOFOCUS)) {
            hasAutoFocus = PreferenceUtils.getBoolean(context, PackageManager.FEATURE_CAMERA_AUTOFOCUS,
                    hasAutoFocus);
        } else {
            PackageManager packageManager = context.getApplicationContext().getPackageManager();
            hasAutoFocus = packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_AUTOFOCUS);
            PreferenceUtils.putBoolean(context, PackageManager.FEATURE_CAMERA_AUTOFOCUS, hasAutoFocus);
        }
        return hasAutoFocus;
    }

    /**
     * ??
     * 
     * @param nCameraId
     * @return
     */
    public static CameraInfo getCameraInfo(int nCameraId) {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(nCameraId, info);
        return info;
    }

    /**
     * ??????
     * 
     * @param info
     * @return
     */
    public static boolean isBackCamera(CameraInfo info) {
        return info.facing == CameraInfo.CAMERA_FACING_BACK;
    }

    /**
     * ??????
     * 
     * @param activity
     * @param nCameraId
     * @return displayOrientation
     */
    public static int getCameraDisplayOrientation(Context context, CameraInfo info) {
        if (AndroidUtils.isMoreThanBuildVersion(Build.VERSION_CODES.GINGERBREAD)) {
            int degrees = DisplayUtils.getRotationDegrees(context);
            if (DEBUG) {
                LogUtils.v("degrees: " + degrees);
            }
            int displayOrientation;
            if (CameraUtils.isBackCamera(info)) {
                // 
                if (DEBUG) {
                    LogUtils.v(String.valueOf(degrees));
                }
                if (DEBUG) {
                    LogUtils.v(String.valueOf(info.orientation));
                }
                displayOrientation = (360 - degrees + info.orientation) % 360;
                if (DEBUG) {
                    LogUtils.v(String.valueOf(displayOrientation));
                }
                displayOrientation = (360 + displayOrientation) % 360;
                if (DEBUG) {
                    LogUtils.v(String.valueOf(displayOrientation));
                }
            } else {
                // 
                if (DEBUG) {
                    LogUtils.v(String.valueOf(degrees));
                }
                if (DEBUG) {
                    LogUtils.v(String.valueOf(info.orientation));
                }
                displayOrientation = (360 - degrees - info.orientation) % 360;
                if (DEBUG) {
                    LogUtils.v(String.valueOf(displayOrientation));
                }
                displayOrientation = (360 + displayOrientation) % 360;
                if (DEBUG) {
                    LogUtils.v(String.valueOf(displayOrientation));
                }
            }
            return displayOrientation;
        }
        return 90;
    }

    /**
     * ???????
     * 
     * @param cameraId
     * @param displayOrientation
     * @return pictureOrientaion
     */
    public static int getPictureOrientaion(CameraInfo info, int displayOrientation) {
        int pictureOrientaion;
        if (CameraUtils.isBackCamera(info)) {
            pictureOrientaion = displayOrientation;
        } else {
            pictureOrientaion = (360 - displayOrientation) % 360;
        }
        return pictureOrientaion;
    }

    public static Size getPictureSize(Context context, Camera camera) {
        final List<Size> sizes = camera.getParameters().getSupportedPictureSizes();
        final double ASPECT_TOLERANCE = 0.07;
        final boolean isPortrait = DisplayUtils.isPortrait(context);
        final int width = DisplayUtils.getWidth(context);
        final int height = DisplayUtils.getHeight(context);
        if (DEBUG) {
            LogUtils.v("width: " + width);
        }
        if (DEBUG) {
            LogUtils.v("height: " + height);
        }
        final double targetRatio = isPortrait ? (double) height / width : (double) width / height;
        final int targetHeight = isPortrait ? width : height;
        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;
        if (DEBUG) {
            LogUtils.v("targetRatio: " + targetRatio);
        }
        for (Size size : sizes) {
            double pictureRatio = isPortrait ? (double) size.height / size.width
                    : (double) size.width / size.height;
            pictureRatio = (double) size.width / size.height;
            if (DEBUG) {
                LogUtils.v("size.width: " + size.width);
            }
            if (DEBUG) {
                LogUtils.v("size.height: " + size.height);
            }
            if (DEBUG) {
                LogUtils.v("pictureRatio: " + pictureRatio);
            }
            if (Math.abs(pictureRatio - targetRatio) > ASPECT_TOLERANCE) {
                continue;
            }
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        if (DEBUG) {
            LogUtils.v("optimalSize.width: " + optimalSize.width);
        }
        if (DEBUG) {
            LogUtils.v("optimalSize.height: " + optimalSize.height);
        }
        return optimalSize;
    }

    /**
     * ?
     * 
     * @param camera
     * @param pictureSize
     */
    public static void setPictureSize(Camera camera, Size pictureSize) {
        Parameters params = camera.getParameters();
        params.setPictureSize(pictureSize.width, pictureSize.height);
        camera.setParameters(params);
    }

    /**
     * Returns the best preview size
     * 
     * @param context
     * @param camera
     */
    public static Size getOptimalPreviewSize(Context context, Camera camera) {
        final List<Size> sizes = camera.getParameters().getSupportedPreviewSizes();
        final double ASPECT_TOLERANCE = 0.07;
        final boolean isPortrait = DisplayUtils.isPortrait(context);
        final Size pictureSize = camera.getParameters().getPictureSize();
        final int width = pictureSize.width;
        final int height = pictureSize.height;
        if (DEBUG) {
            LogUtils.v("width: " + width);
        }
        if (DEBUG) {
            LogUtils.v("height: " + height);
        }
        final double targetRatio = isPortrait ? (double) height / width : (double) width / height;
        final int targetHeight = isPortrait ? width : height;
        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;
        if (DEBUG) {
            LogUtils.v("targetRatio: " + targetRatio);
        }
        for (Size size : sizes) {
            double previewRatio = isPortrait ? (double) size.height / size.width
                    : (double) size.width / size.height;
            previewRatio = (double) size.width / size.height;
            if (DEBUG) {
                LogUtils.v("size.width: " + size.width);
            }
            if (DEBUG) {
                LogUtils.v("size.height: " + size.height);
            }
            if (DEBUG) {
                LogUtils.v("previewRatio: " + previewRatio);
            }
            if (Math.abs(previewRatio - targetRatio) > ASPECT_TOLERANCE) {
                continue;
            }
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        if (DEBUG) {
            LogUtils.v("optimalSize.width: " + optimalSize.width);
        }
        if (DEBUG) {
            LogUtils.v("optimalSize.height: " + optimalSize.height);
        }
        return optimalSize;
    }

    /**
     * ???
     * 
     * @param camera
     * @param previewSize
     */
    public static void setPreviewSize(Camera camera, Size previewSize) {
        Parameters params = camera.getParameters();
        params.setPreviewSize(previewSize.width, previewSize.height);
        camera.setParameters(params);
    }

    /**
     * ????????
     * 
     * @param context
     * @param camera
     * @return scaledPreviewSize
     */
    public static Size getScaledPreviewSize(Context context, Camera camera) {
        Size previewSize = camera.getParameters().getPreviewSize();
        boolean isPortrait = DisplayUtils.isPortrait(context);
        final int displayWidth = DisplayUtils.getWidth(context);
        final int displayHeight = DisplayUtils.getHeight(context);
        if (DEBUG) {
            LogUtils.v("displayWidth: " + displayWidth);
        }
        if (DEBUG) {
            LogUtils.v("displayHeight: " + displayHeight);
        }
        PreferenceUtils.putInt(context, context.getString(R.string.keyDisplayWidth), displayWidth);
        PreferenceUtils.putInt(context, context.getString(R.string.keyDisplayHeight), displayHeight);
        final int previewWidth = isPortrait ? previewSize.height : previewSize.width;
        final int previewHeight = isPortrait ? previewSize.width : previewSize.height;
        if (DEBUG) {
            LogUtils.v("previewWidth: " + previewWidth);
        }
        if (DEBUG) {
            LogUtils.v("previewHeight: " + previewHeight);
        }
        PreferenceUtils.putInt(context, context.getString(R.string.keyPreviewWidth), previewWidth);
        PreferenceUtils.putInt(context, context.getString(R.string.keyPreviewHeight), previewHeight);
        double displayRatio = displayHeight > displayWidth ? (double) displayHeight / displayWidth
                : (double) displayWidth / displayHeight;
        double previewRatio = previewHeight > previewWidth ? (double) previewHeight / previewWidth
                : (double) previewWidth / previewHeight;
        if (DEBUG) {
            LogUtils.v("displayRatio: " + displayRatio);
        }
        if (DEBUG) {
            LogUtils.v("previewRatio: " + previewRatio);
        }
        PreferenceUtils.putFloat(context, context.getString(R.string.keyDisplayRatio), (float) displayRatio);
        PreferenceUtils.putFloat(context, context.getString(R.string.keyPreviewRatio), (float) previewRatio);
        int scaledChildWidth = displayWidth;
        int scaledChildHeight = displayHeight;
        if (displayRatio <= previewRatio) {
            if (isPortrait) {
                if (DEBUG) {
                    LogUtils.v("Portrait");
                }
                scaledChildWidth = (displayHeight * previewWidth) / previewHeight;
                scaledChildHeight = (scaledChildWidth * previewHeight) / previewWidth;
            } else {
                if (DEBUG) {
                    LogUtils.v("Landscape");
                }
                scaledChildHeight = (displayWidth * previewHeight) / previewWidth;
                scaledChildWidth = (scaledChildHeight * previewWidth) / previewHeight;
            }
        } else {
            if (isPortrait) {
                if (DEBUG) {
                    LogUtils.v("Portrait");
                }
                scaledChildHeight = (displayWidth * previewHeight) / previewWidth;
                scaledChildWidth = (scaledChildHeight * previewWidth) / previewHeight;
            } else {
                if (DEBUG) {
                    LogUtils.v("Landscape");
                }
                scaledChildWidth = (displayHeight * previewWidth) / previewHeight;
                scaledChildHeight = (scaledChildWidth * previewHeight) / previewWidth;
            }
        }
        if (DEBUG) {
            LogUtils.v("scaledChildWidth: " + scaledChildWidth);
        }
        if (DEBUG) {
            LogUtils.v("scaledChildHeight: " + scaledChildHeight);
        }
        PreferenceUtils.putInt(context, context.getString(R.string.keyScaledChildWidth), scaledChildWidth);
        PreferenceUtils.putInt(context, context.getString(R.string.keyScaledChildHeight), scaledChildHeight);
        int scaledWidth = scaledChildWidth;
        int scaledHeight = scaledChildHeight;
        if (displayRatio <= previewRatio) {
            if (isPortrait) {
                if (DEBUG) {
                    LogUtils.v("Portrait");
                }
                scaledHeight = (displayWidth * previewHeight) / previewWidth;
                scaledWidth = (scaledHeight * previewWidth) / previewHeight;
            } else {
                if (DEBUG) {
                    LogUtils.v("Landscape");
                }
                scaledWidth = (displayHeight * previewWidth) / previewHeight;
                scaledHeight = (scaledWidth * previewHeight) / previewWidth;
            }
        } else {
            if (isPortrait) {
                if (DEBUG) {
                    LogUtils.v("Portrait");
                    //                scaledWidth = (displayHeight * previewWidth) / previewHeight;
                    //                scaledHeight = (scaledWidth * previewHeight) / previewWidth;
                }
            } else {
                if (DEBUG) {
                    LogUtils.v("Landscape");
                    //                scaledHeight = (displayWidth * previewHeight) / previewWidth;
                    //                scaledWidth = (scaledHeight * previewWidth) / previewHeight;
                }
            }
        }
        if (DEBUG) {
            LogUtils.v("scaledWidth: " + scaledWidth);
        }
        if (DEBUG) {
            LogUtils.v("scaledHeight: " + scaledHeight);
        }
        PreferenceUtils.putInt(context, context.getString(R.string.keyScaledWidth), scaledWidth);
        PreferenceUtils.putInt(context, context.getString(R.string.keyScaledHeight), scaledHeight);
        return camera.new Size(scaledWidth, scaledHeight);
    }

    /**
     * JSON???
     * 
     * @param params
     * @return
     */
    public static String toJson(Camera.Parameters params) {
        String[] data = params.flatten().split(";");
        JSONObject json = new JSONObject();
        for (String element : data) {
            String[] splits = element.split("=");
            String key = splits[0];
            if (DEBUG) {
                LogUtils.v(key);
            }
            String value = splits.length > 1 ? splits[1] : "";
            if (DEBUG) {
                LogUtils.v(value);
            }
            try {
                json.put(key, value);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return json.toString();
    }

    /**
     * JSON???
     * 
     * @param params
     * @return
     */
    public static String toJson(CamcorderProfile camcorderProfile) {
        JSONObject json = new JSONObject();
        try {
            json.put("audioBitRate: ", camcorderProfile.audioBitRate);
            json.put("audioChannels: ", camcorderProfile.audioChannels);
            json.put("audioCodec: ", camcorderProfile.audioCodec);
            json.put("audioSampleRate: ", camcorderProfile.audioSampleRate);
            json.put("duration: ", camcorderProfile.duration);
            json.put("fileFormat: ", camcorderProfile.fileFormat);
            json.put("quality: ", camcorderProfile.quality);
            json.put("videoBitRate: ", camcorderProfile.videoBitRate);
            json.put("videoCodec: ", camcorderProfile.videoCodec);
            json.put("videoFrameHeight: ", camcorderProfile.videoFrameHeight);
            json.put("videoFrameRate: ", camcorderProfile.videoFrameRate);
            json.put("videoFrameWidth: ", camcorderProfile.videoFrameWidth);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        if (DEBUG) {
            LogUtils.v("camcorderProfile.audioBitRate: " + camcorderProfile.audioBitRate);
            LogUtils.v("camcorderProfile.audioChannels: " + camcorderProfile.audioChannels);
            LogUtils.v("camcorderProfile.audioCodec: " + camcorderProfile.audioCodec);
            LogUtils.v("camcorderProfile.audioSampleRate: " + camcorderProfile.audioSampleRate);
            LogUtils.v("camcorderProfile.duration: " + camcorderProfile.duration);
            LogUtils.v("camcorderProfile.fileFormat: " + camcorderProfile.fileFormat);
            LogUtils.v("camcorderProfile.quality: " + camcorderProfile.quality);
            LogUtils.v("camcorderProfile.videoBitRate: " + camcorderProfile.videoBitRate);
            LogUtils.v("camcorderProfile.videoCodec: " + camcorderProfile.videoCodec);
            LogUtils.v("camcorderProfile.videoFrameHeight: " + camcorderProfile.videoFrameHeight);
            LogUtils.v("camcorderProfile.videoFrameRate: " + camcorderProfile.videoFrameRate);
            LogUtils.v("camcorderProfile.videoFrameWidth: " + camcorderProfile.videoFrameWidth);
        }
        return json.toString();
    }

    /**
     * ??
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static boolean canDisableShutterSound(CameraInfo info) {
        boolean canDisableShutterSound = false;
        if (AndroidUtils.isMoreThanBuildVersion(Build.VERSION_CODES.JELLY_BEAN_MR1)) {
            canDisableShutterSound = info.canDisableShutterSound;
        }
        return canDisableShutterSound;
    }

    /**
     * ???
     */
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public static boolean isFaceDetectionSupported(Context context, Camera camera) {
        boolean isFaceDetectionSupported = false;
        int maxNumDetectedFaces = 0;
        if (AndroidUtils.isMoreThanBuildVersion(Build.VERSION_CODES.ICE_CREAM_SANDWICH)) {
            maxNumDetectedFaces = camera.getParameters().getMaxNumDetectedFaces();
            isFaceDetectionSupported = maxNumDetectedFaces > 0;
        }
        PreferenceUtils.putBoolean(context, context.getString(R.string.keySupportFaceDetection),
                isFaceDetectionSupported);
        PreferenceUtils.putInt(context, context.getString(R.string.keyMaxNumDetectedFaces), maxNumDetectedFaces);
        return isFaceDetectionSupported;
    }

}