Camera2拍照(备忘)

首先上布局代码:

<?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"
    android:layout_marginLeft="@dimen/fab_margin"
    android:layout_marginRight="@dimen/fab_margin"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:fitsSystemWindows="true">

    <TextureView
        android:id="@+id/tv_textview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="3" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

        <ImageView
            android:id="@+id/iv_Thumbnail"
            android:layout_width="50dp"
            android:layout_height="70dp"
            android:layout_alignParentLeft="true"
            android:background="@drawable/bg_border"
            android:visibility="gone" />
        <ImageView
            android:id="@+id/iv_Thumbnail2"
            android:layout_width="50dp"
            android:layout_height="70dp"
            android:layout_toRightOf="@id/iv_Thumbnail"
            android:layout_alignTop="@id/iv_Thumbnail"
            android:layout_marginLeft="5dp"
            android:visibility="gone" />
        <ImageView
            android:id="@+id/iv_Thumbnail3"
            android:layout_width="50dp"
            android:layout_height="70dp"
            android:layout_toRightOf="@id/iv_Thumbnail2"
            android:layout_alignTop="@id/iv_Thumbnail2"
            android:layout_marginLeft="5dp"
            android:visibility="gone" />

        <Button
            android:id="@+id/btn_takepic"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:text="拍照" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/finishAndback"
            android:layout_below="@id/btn_takepic"
            android:layout_alignParentRight="true"
            />
    </RelativeLayout>
</LinearLayout>

Activity代码

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.AudioAttributes;
import android.media.Image;
import android.media.ImageReader;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import cn.com.zifar.Utility.ConstHelper;

import static cn.com.zifar.mobileforpatrol.R.id.iv_Thumbnail;

public class MyCameraActivity extends MyBaseActivity{
    TextureView mTextureView;
    ImageView mThumbnail;
    Button mButton;
    Handler mHandler,childHandler;
    ImageReader mImageReader;
    CaptureRequest.Builder mPreViewBuidler;
    CameraCaptureSession mCameraSession;
    CameraCharacteristics mCameraCharacteristics;
    Ringtone ringtone;
    private Size mPreViewSize;
    private CameraDevice CameraDevice;
    private CameraManager manager;
    private String cameraid;
    private Context context;
    private List<Bitmap> MypicList;
    private List<ImageView> MyImgList;

    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();

    ///为了使照片竖直显示
    static {
        ORIENTATIONS.append(Surface.ROTATION_0, 90);
        ORIENTATIONS.append(Surface.ROTATION_90, 0);
        ORIENTATIONS.append(Surface.ROTATION_180, 270);
        ORIENTATIONS.append(Surface.ROTATION_270, 180);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_camera);
        InitMyActivity();
        InitTools();
        context=this;
        MypicList=new ArrayList<>();
        FindView();
    }

    /**
     * 显示图片
     */
    private void ShowImg(){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if((MypicList!=null &&MypicList.size()>0) && (MyImgList!=null && MyImgList.size()>0))
                    for(int i=0;i<MyImgList.size();i++){
                        android.widget.ImageView img=MyImgList.get(i);
                        if(i>=MypicList.size()){
                            img.setVisibility(View.GONE);
                            break;
                        }
                        Bitmap bitmap=MypicList.get(i);
                        if(bitmap!=null){
                            img.setImageBitmap(bitmap);
                            img.setVisibility(View.VISIBLE);
                        }
                    }
            }
        });
    }

    /**
     * 删除图片
     * @param imageView
     */
    private void DelImg(ImageView imageView){
        int id=imageView.getId();
        int index=0;
        switch(id){
            case R.id.iv_Thumbnail:
                index=0;
                break;
            case R.id.iv_Thumbnail2:
                index=1;
                break;
            case R.id.iv_Thumbnail3:
                index=2;
                break;
        }
        Drawable drawable = imageView.getDrawable();
        if (drawable != null && drawable instanceof BitmapDrawable){
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            Bitmap bitmap = bitmapDrawable.getBitmap();
            if (bitmap != null && !bitmap.isRecycled()) {
                bitmap.recycle();
            }
            MypicList.set(index,null);
        }
        ClearNullBitmap();
        //imageView.setWillNotDraw(true);
        ShowImg();
    }

    private void ClearNullBitmap(){
        List<Bitmap> nlist=new ArrayList<>();
        if(MypicList!=null){
            for(Bitmap bitmap:MypicList){
                if(bitmap==null)continue;
                nlist.add(bitmap);
            }
        }
        MypicList=nlist;
    }

    private final  class ImageViewClickListener implements ImageView.OnLongClickListener{
        @Override
        public boolean onLongClick(View v) {
            DelImg((ImageView) v);
            return true;
        }
    }

    private void FindView(){
        mTextureView = (TextureView) findViewById(R.id.tv_textview);
        mButton = (Button) findViewById(R.id.btn_takepic);
        MyImgList=new ArrayList<>();
        ImageView mThumbnail = (ImageView) findViewById(iv_Thumbnail);
        mThumbnail.setOnLongClickListener(new ImageViewClickListener());
        MyImgList.add(mThumbnail);
        ImageView iv_Thumbnail2=(ImageView)findViewById(R.id.iv_Thumbnail2);
        iv_Thumbnail2.setOnLongClickListener(new ImageViewClickListener());
        MyImgList.add(iv_Thumbnail2);
        ImageView iv_Thumbnail3=(ImageView)findViewById(R.id.iv_Thumbnail3);
        iv_Thumbnail3.setOnLongClickListener(new ImageViewClickListener());
        MyImgList.add(iv_Thumbnail3);
        ShowImg();

        //初始化相机布局
        mTextureView.setSurfaceTextureListener(mSurfacetextlistener);
        //初始化拍照的声音
        ringtone = RingtoneManager.getRingtone(MyCameraActivity.this, Uri.parse("file:///system/media/audio/ui/camera_click.ogg"));
        AudioAttributes.Builder attr = new AudioAttributes.Builder();
        attr.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION);
        ringtone.setAudioAttributes(attr.build());
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(MypicList.size()>=3){
                    Toast.makeText(context,R.string.morethanmax,Toast.LENGTH_SHORT).show();
                    return;
                }
                shootSound();
                try {
                    if(CameraDevice==null)return;
                    final CaptureRequest.Builder captureRequestBuilder;
                    captureRequestBuilder = CameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
                    // 将imageReader的surface作为CaptureRequest.Builder的目标
                    captureRequestBuilder.addTarget(mImageReader.getSurface());
                    // 自动对焦
                    captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                    // 自动曝光
                    captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
                    // 获取手机方向
                    int rotation = getWindowManager().getDefaultDisplay().getRotation();
                    // 根据设备方向计算设置照片的方向
                    captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
                    //拍照
                    CaptureRequest mCaptureRequest = captureRequestBuilder.build();
                    mCameraSession.capture(mCaptureRequest, null, childHandler);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    protected void onDestroy() {
        if(CameraDevice!=null){
            CameraDevice.close();
            CameraDevice=null;
        }
        super.onDestroy();
    }


    /**
     * 播放系统的拍照的声音
     */
    public void shootSound() {
        ringtone.stop();
        ringtone.play();
    }

    //打开相机时候的监听器,通过他可以得到相机实例,这个实例可以创建请求建造者
    private CameraDevice.StateCallback cameraOpenCallBack = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(CameraDevice cameraDevice) {
            CameraDevice=cameraDevice;
            Log.d(ConstHelper.TagName, "相机已经打开");
            try {
                mPreViewBuidler = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                SurfaceTexture texture = mTextureView.getSurfaceTexture();
                texture.setDefaultBufferSize(mPreViewSize.getWidth(), mPreViewSize.getHeight());

                Surface surface = new Surface(texture);
                mPreViewBuidler.addTarget(surface);

                cameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()), mSessionStateCallBack, childHandler);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onDisconnected(CameraDevice cameraDevice) {
            Log.d(ConstHelper.TagName, "相机连接断开");
        }

        @Override
        public void onError(CameraDevice cameraDevice, int i) {
            Log.d(ConstHelper.TagName, "相机打开失败");
        }
    };

    //相机会话的监听器,通过他得到mCameraSession对象,这个对象可以用来发送预览和拍照请求
    private CameraCaptureSession.StateCallback mSessionStateCallBack = new CameraCaptureSession.StateCallback() {
        @Override
        public void onConfigured(CameraCaptureSession cameraCaptureSession) {
            try {
                mCameraSession = cameraCaptureSession;
                mCameraSession.setRepeatingRequest(mPreViewBuidler.build(), mCaptureCallBack, childHandler);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {

        }
    };

    private CameraCaptureSession.CaptureCallback mCaptureCallBack=new CameraCaptureSession.CaptureCallback() {
        @Override
        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
            super.onCaptureCompleted(session, request, result);

        }

        @Override
        public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult) {
            super.onCaptureProgressed(session, request, partialResult);
        }
    };

    private TextureView.SurfaceTextureListener mSurfacetextlistener=new TextureView.SurfaceTextureListener(){
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            HandlerThread thread = new HandlerThread("Ceamera3");
            thread.start();
            mHandler = new Handler(getMainLooper());
            childHandler=new Handler(thread.getLooper());
            manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
            cameraid = CameraCharacteristics.LENS_FACING_FRONT + "";
            try {
                mCameraCharacteristics = manager.getCameraCharacteristics(cameraid);
                StreamConfigurationMap map = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                Size largest = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), new CompareSizeByArea());
                mPreViewSize = map.getOutputSizes(SurfaceTexture.class)[0];
                mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(), ImageFormat.JPEG, 5);
                mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
                    @Override
                    public void onImageAvailable(final ImageReader reader) {
                        try{
                            Image image = reader.acquireNextImage();
                            ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                            byte[] bytes = new byte[buffer.remaining()];
                            buffer.get(bytes);//由缓冲区存入字节数组
                            Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                            if(bitmap!=null)
                            {
                                MypicList.add(bitmap);
                                ShowImg();
                            }
                            image.close();
                        }catch (Exception ex){
                            ex.printStackTrace();
                        }
                    }
                }, mHandler);
                if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(MyCameraActivity.this,new String[]{Manifest.permission.CAMERA},PackageManager.PERMISSION_GRANTED);
                }
                manager.openCamera(cameraid, cameraOpenCallBack, mHandler);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            if(CameraDevice!=null){
                CameraDevice.close();
                CameraDevice=null;
            }
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {

        }
    };

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值