Android Camera 基础学习

之前写过:调用摄像头拍照,拿到缩略图,本地图,裁剪 ,在低版本上能运行,7.0+就不行了,需要适配FileProvider。

1,调用隐式Intent 启动系统相机

 private static final int REQ_IMAGE = 1024 ;
 Intent intentCapturePic = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (intentCapturePic.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(intentCapturePic,REQ_IMAGE);
        }

通过resolveActivity判断有木有对应的Activity做个安全保护。

2,获取拍照的缩略图

  系统通过Intent 把一个很小的图片(Bitmap )在onActivityResult 函数中返回,在Extras 以key "data"返回。

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQ_IMAGE:
                if (resultCode == RESULT_OK) {
                    Bundle bundle = data.getExtras();
                    Bitmap bitmap = (Bitmap) bundle.get("data");
                    imageView.setImageBitmap(bitmap);
                }
                break;
        }
    }

其实这个图片很小,并不能满足需求。

3,获取系统相机原图

  通过系统拍照保存到本地文件,需要申请

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

权限:

  if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
        {
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},0);
        }

在7.0+ 的设备上还要适配FileProvider ,关于FileProvider :Android 7.0 行为变更 通过FileProvider在应用间共享文件吧

file_paths:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path
        name="files"
        path="" />

    <cache-path
        name="cache"
        path="" />

    <external-path
        name="external"
        path="" />

    <external-files-path
        name="external_file_path"
        path="" />
    <external-cache-path
        name="external_cache_path"
        path="" />

</paths>

manifest 配置:

   <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.***.android7.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

启动相机:

 public void startCameraOriginal(View view)
    {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        //Uri fileUri = FileProvider.getUriForFile(this, "com.dhl.android7.fileprovider", new File(imagePath));
        String filename = new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.CHINA)
                .format(new Date()) + ".png";
        File file = new File(Environment.getExternalStorageDirectory(), filename);
        imagePath = file.getAbsolutePath();
        Uri fileUri = null ;
        if (Build.VERSION.SDK_INT >= 24) {
             fileUri = FileProvider.getUriForFile(this, "com.***.android7.fileprovider", file);
        }else
        {
            fileUri = Uri.fromFile(new File(imagePath));
        }

        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        startActivityForResult(intent,REQ_IMAGE_ORIGINAL);
    }

onActivity 拿回图片:

 case REQ_IMAGE_ORIGINAL :
                if(resultCode == RESULT_OK)
                {
                    //ssetPictureDegreeZero(imagePath,1);
                  // Glide.with(this).load(imagePath).transform(new RotateTransformation(this,90)).into(imageView);


                    //String photopath = imagePath;
                    Bitmap bmp = BitmapFactory.decodeFile(imagePath);
                    //小米拍照后旋转处理
                    Matrix matrix = new Matrix();
                    matrix.postRotate(readPictureDegree(imagePath));//90
                    bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
                    FileOutputStream fOut;
                    try {
                        fOut = new FileOutputStream(imagePath);
                        //不压缩
                        bmp.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
                        fOut.flush();
                        fOut.close();

                    } catch (FileNotFoundException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    FileInputStream fis = null;
                    try
                    {
                        fis = new FileInputStream(imagePath);
                        Bitmap bitmap = BitmapFactory.decodeStream(fis);
                        imageView.setImageBitmap(bitmap);

                        //添加到系统相册
                        Intent intent = new Intent(
                                Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                        intent.setData(Uri.fromFile(new File(imagePath)));
                        sendBroadcast(intent);

                    }catch (Exception e)
                    {
                        e.printStackTrace();
                    }finally {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
                break;
这里小米拍照的图片是旋转的,所以用到 Android 效率开发之图片旋转处理,如果用Glide加载则不用特殊处理,会帮你处理好图片。最后用到 Android 效率开发之图片保存到图库

这样就可以拿到系统原图尺寸了。

4,自定义自己的相机

 最起码需要一个SurfaceView 布局文件如下

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.dhl.camerademo.CustomCameraActivity">

    <SurfaceView
        android:id="@+id/surface_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ImageView
        android:id="@+id/image_capture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:text="拍照"
        android:onClick="captureCamera"
        />

</RelativeLayout>

 这里surfaceView 用来预览相机,ImageView用来展示拍照完成的图片。

自定义自己的相机需要相应的权限:

 <uses-permission android:name="android.permission.CAMERA"/>

获取Camera:

 /**
     * 获取Camera
     * @return
     */
    private Camera getCamera()
    {
        Camera camera ;

        try
        {
            camera = Camera.open();
        }catch (Exception e)
        {
            camera = null ;
            e.printStackTrace();
        }
        return camera ;
    }

释放相机资源:

 /**
     * 释放相机资源
     */
    private void releaseCamera()
    {
       // getCamera().release();
        if(mCamera != null)
        {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null ;
        }
    }

设置预览:

/**
     * 设置预览
     * @param camera
     * @param surfaceHolder
     */
    private void setStartPreview(Camera camera,SurfaceHolder surfaceHolder)
    {
        try {
            camera.setPreviewDisplay(surfaceHolder);
            camera.setDisplayOrientation(90);
            camera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

拍照参数:

 /**
     * 获取照片
     * @param view
     */
    public  void captureCamera(View view)
    {
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPictureFormat(ImageFormat.JPEG);
        //是否原图
        parameters.setJpegQuality(100);

        //获取支持的尺寸
        List<Camera.Size> list = parameters.getSupportedPictureSizes();
        Camera.Size size = list.get(0);
        parameters.setPictureSize(size.width, size.height);
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        mCamera.setParameters(parameters);
       // parameters.setPictureSize(2592, 1296);

        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                if(success)
                {
                    mCamera.takePicture(null,null,pictureCallback);
                }
            }
        });

    }

拍完照片回调处理图片:

 private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date());
            String imageFileName = "JPEG_" + timeStamp + "_";
            File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
            File image   = null;
            try {
                 image = File.createTempFile(
                        imageFileName,  /* prefix */
                        ".jpg",         /* suffix */
                        storageDir      /* directory */
                );
            } catch (IOException e) {
                e.printStackTrace();
            }
          //  File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/temp.jpg");
            try {
                FileOutputStream fileOutputStream = new FileOutputStream(image);
                fileOutputStream.write(data);
                fileOutputStream.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            surfaceView.setVisibility(View.GONE);
            image_capture.setVisibility(View.VISIBLE);
            //添加到系统相册

            Glide.with(CustomCameraActivity.this).load(image.getPath()).into(image_capture);
        }
    };

全部代码:


/**
 * 自定义相机
 */
public class CustomCameraActivity extends AppCompatActivity implements SurfaceHolder.Callback {


    private Camera mCamera ;
    private SurfaceView surfaceView ;
    private SurfaceHolder surfaceHolder ;
    private ImageView image_capture ;

    private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date());
            String imageFileName = "JPEG_" + timeStamp + "_";
            File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
            File image   = null;
            try {
                 image = File.createTempFile(
                        imageFileName,  /* prefix */
                        ".jpg",         /* suffix */
                        storageDir      /* directory */
                );
            } catch (IOException e) {
                e.printStackTrace();
            }
          //  File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/temp.jpg");
            try {
                FileOutputStream fileOutputStream = new FileOutputStream(image);
                fileOutputStream.write(data);
                fileOutputStream.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            surfaceView.setVisibility(View.GONE);
            image_capture.setVisibility(View.VISIBLE);
            //添加到系统相册

            Glide.with(CustomCameraActivity.this).load(image.getPath()).into(image_capture);
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_camera);
        surfaceView = (SurfaceView)findViewById(R.id.surface_view);
        image_capture = (ImageView)findViewById(R.id.image_capture);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCamera.autoFocus(null);
            }
        });
    }

    /**
     * 获取照片
     * @param view
     */
    public  void captureCamera(View view)
    {
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPictureFormat(ImageFormat.JPEG);
        //是否原图
        parameters.setJpegQuality(100);

        //获取支持的尺寸
        List<Camera.Size> list = parameters.getSupportedPictureSizes();
        Camera.Size size = list.get(0);
        parameters.setPictureSize(size.width, size.height);
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        mCamera.setParameters(parameters);
       // parameters.setPictureSize(2592, 1296);

        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                if(success)
                {
                    mCamera.takePicture(null,null,pictureCallback);
                }
            }
        });

    }

    @Override
    protected void onResume() {
        super.onResume();
        if(mCamera == null)
        {
            mCamera = getCamera();
          /*  if(surfaceHolder != null)
            {
                setStartPreview(mCamera,surfaceHolder);
            }*/
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseCamera();
    }

    /**
     * 获取Camera
     * @return
     */
    private Camera getCamera()
    {
        Camera camera ;

        try
        {
            camera = Camera.open();
        }catch (Exception e)
        {
            camera = null ;
            e.printStackTrace();
        }
        return camera ;
    }

    /**
     * 设置预览
     * @param camera
     * @param surfaceHolder
     */
    private void setStartPreview(Camera camera,SurfaceHolder surfaceHolder)
    {
        try {
            camera.setPreviewDisplay(surfaceHolder);
            camera.setDisplayOrientation(90);
            camera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 释放相机资源
     */
    private void releaseCamera()
    {
       // getCamera().release();
        if(mCamera != null)
        {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null ;
        }
    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        setStartPreview(mCamera,surfaceHolder);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        setStartPreview(mCamera,surfaceHolder);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        releaseCamera();
    }
}

这就简单实现了自定义相机。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值