Android之使用Camera拍照

在Android开发中我们常常用到拍照或者是录视频这两个功能:

  • 一种是通过intent
  • 另一种是使用camera

    下边就是使用camera实现拍照的demo介绍


  • CameraPreview – 照片预览
    通常我们在使用照相机时,我们会对拍照的图像进行预览,这个预览界面使用surfaceview来实现,代码如下:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback, Camera.AutoFocusCallback {
    private SurfaceHolder mHolder;
    private Camera mCamera;
    private Context context;
    private static final String TAG = CameraPreview.class.getSimpleName();

    public CameraPreview(Context context) {
        super(context);
        this.context = context;
        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            // 0: 启动后置摄像头,1:启动前置摄像头
            mCamera = Camera.open(0);

            setCameraParameters(mCamera);
            setCameraDisplayOrientation((Activity) context, 0, mCamera);
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

/**
 *销毁视图时,释放内存
 */
    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }

        Log.d("Dennis", "surfaceDestroyed() is called");
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null) {
            // preview surface does not exist
            return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e) {
            // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            setCameraParameters(mCamera);
            requestLayout();
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e) {
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }

    public void setCameraParameters(Camera camera) {
        Camera.Parameters mCameraParameters = mCamera.getParameters();
        // 通常会默认在50Hz 如果设置60Hz会有水波纹
        mCameraParameters.setAntibanding(Camera.Parameters.ANTIBANDING_AUTO);
        boolean autoExposureLockSupported = mCameraParameters.isAutoExposureLockSupported();
        if (autoExposureLockSupported) {
            mCameraParameters.setAutoExposureLock(true);
        }
        // 设置闪光灯
        mCameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
        // 设置颜色效果
        mCameraParameters.setColorEffect(Camera.Parameters.EFFECT_NONE);
        // 设置自动白平衡锁定状态
        mCameraParameters.setAutoWhiteBalanceLock(mCameraParameters.getAutoWhiteBalanceLock());
        // 设置曝光补偿指数
        // mCameraParameters.setExposureCompensation(1);
        mCameraParameters.setPreviewSize(1920, 1080);
        mCamera.setParameters(mCameraParameters);
    }

    public void takePicture(Camera.PictureCallback imageCallback) {
        mCamera.takePicture(null, null, imageCallback);
    }

    /**
     * 设置预览视图的方向 如果不设置的话,拍的照片方向不是我们看到的方向,通过这个方法,我们在旋转手机是,预览视图的方向也跟着旋转.
     *
     * @param activity
     * @param cameraId
     * @param camera
     */
    public void setCameraDisplayOrientation(Activity activity,
                                            int cameraId, android.hardware.Camera camera) {
        android.hardware.Camera.CameraInfo info =
                new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        camera.setDisplayOrientation(result);
    }

    @Override
    public void onAutoFocus(boolean success, Camera camera) {

    }
}
  • FileUtil–File工具类,实现数据的保存
public class FileUtils {
   /**
     * 判断内存卡是否存在
     * @return
     */
    public static boolean SDCardIsAvailable() {
        String state = Environment.getExternalStorageState();
        return state.equals(Environment.MEDIA_MOUNTED);
    }
   /**
     * 获取图片存储路径
     * @return
     */
    public static File getFilePath() {
        if (!SDCardIsAvailable()) {
            throw new RuntimeException("the sdcard is error,please check sdcard and try again");
        }
        //get the mobile Pictures directory
        File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        //get the current time
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        Log.i("picPath", picDir.getPath() + File.separator + timeStamp);
        return new File(picDir.getPath() + File.separator + "IMAGE_" + timeStamp + ".jpg");
    }
   /**
     * 将数据一.jpg格式保存到指定的路径中
     * @param data
     * @param file
     */
    public static void saveData2Pic(byte data[], File file) {
        if (null == file || data == null) {
            Log.d("sava picture is failed", "FileUtil.class--saveData2Pic");
            return;
        }
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            fos.write(data);
            fos.flush();
            Log.i("save pic is successful", file.getAbsolutePath());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null == fos) {
                return;
            }
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  • MainActivity
public class MainActivity extends Activity implements View.OnClickListener, Camera.PictureCallback {

    private Button btOk;
    private FrameLayout frameLayout;
    private CameraPreview cameraPreview;

    private static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btOk = (Button) findViewById(R.id.take_picture);
        frameLayout = (FrameLayout) findViewById(R.id.camera_content);
        cameraPreview = new CameraPreview(this);
        frameLayout.addView(cameraPreview);
        btOk.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        btOk.setEnabled(false);

        // get an image from the camera
        cameraPreview.takePicture(this);
    }

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        File picFile = FileUtils.getFilePath();
        if (picFile == null) {
            Log.d(TAG, "Error creating media file, check storage permissions: ");
            return;
        }
        FileUtils.saveData2Pic(data, picFile);
        // Restart the preview and re-enable the shutter button so that we can take another picture
        camera.startPreview();
        //See if need to enable or not
        btOk.setEnabled(true);
    }

}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/camera_content"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"></FrameLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp">

        <Button
            android:id="@+id/take_picture"
            android:layout_width="80dip"
            android:layout_height="match_parent" />
    </LinearLayout>
</LinearLayout>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值