安卓开发-自定义照相机界面

此项目是总结了其他三位大佬的代码后写出来的,在此首先感谢三位大佬:

自定义照相机编写方法:https://blog.csdn.net/shan286/article/details/53189034
解决照相机拍的照片像素低的方法:https://blog.csdn.net/w6718189/article/details/104501618?utm_medium=distribute.pc_relevant.none-task-blog-title-2&spm=1001.2101.3001.4242
浏览图片放大缩小方法:https://blog.csdn.net/lpcrazyboy/article/details/80777112

话不多说,先上图片

1.主界面

2.点击系统组件拍照按钮后跳转的界面

3.点击拍照按钮后的界面

4.点击确定按钮后(我的设备里确定按钮就是那个√),返回首页并展示选择拍摄图片的界面

5.点击自定义组件拍照按钮后的界面

6.点击中间的拍照按钮后进入的照片预览界面

7.点击使用图片后返回主页面并展示图片

下面开始贴代码:

MainAcitivity:

package com.mobile.takephotodemo;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity extends AppCompatActivity {
    private Button btn_takephoto_amn, btn_takephotocam_amn;
    private ImageView iv_photo_ato;
    private int REQUEST_CODE = 1;
    public static final int REQUEST_CODE_READ = 3;
    public static final int REQUEST_CODE_WRITE = 2;
    private String mFilePath;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();//代码初始化
        setClick();//设置点击方法
        getInfo();//获取其他界面传递过来的信息
    }

    /**
     * 获取其他界面传递过来的信息
     */
    private void getInfo() {
        try {
            String path = getIntent().getStringExtra("picpath");//通过值"picpath"得到照片路径
            FileInputStream fis = new FileInputStream(path);//通过path把照片读到文件输入流中
            Bitmap bitmap = BitmapFactory.decodeStream(fis);//将输入流解码为bitmap
            Matrix matrix = new Matrix();//新建一个矩阵对象
            matrix.setRotate(90);//矩阵旋转操作让照片可以正对着你。但是还存在一个左右对称的问题
//新建位图,第2个参数至第5个参数表示位图的大小,matrix中是旋转后的位图信息,并使bitmap变量指向新的位图对象
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            iv_photo_ato.setImageBitmap(bitmap);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置点击方法
     */
    private void setClick() {
        btn_takephoto_amn.setOnClickListener(new MainActivityClick());
        btn_takephotocam_amn.setOnClickListener(new MainActivityClick());
    }

    /**
     * 代码初始化
     */
    private void initView() {
        iv_photo_ato = findViewById(R.id.iv_photo_ato);//展示拍照图片的控件
        btn_takephoto_amn = findViewById(R.id.btn_takephoto_amn);//调用系统组件拍照
        btn_takephotocam_amn = findViewById(R.id.btn_takephotocam_amn);//调用自定义组件拍照
    }

    /**
     * 设置点击方法
     */
    private class MainActivityClick implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_takephoto_amn://拍照按钮的点击方法
//                    Toast.makeText(MainActivity.this, "拍照按钮", Toast.LENGTH_SHORT).show();
                    checkPermissions();//获取用户权限
                    break;
                case R.id.btn_takephotocam_amn://进入自定义拍照界面
                    checkotherPermissions();//获取用户权限
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 自定义拍照界面获取权限
     */
    private void checkotherPermissions() {
        boolean canWrite = isWriteStoragePermissionGranted();//获取写的权限
//        Log.d(TAG, " canWrite :" + canWrite);
        if (canWrite) {
            boolean canRead = isReadStoragePermissionGranted();//获取读的权限
//            Log.d(TAG, " canRead :" + canRead);
            if (canRead) {
//                Log.d(TAG, " Now you are ready to access camera :");
                startActivity(new Intent(MainActivity.this, Customcamera.class));
            }
        }

    }

    /**
     * 获取用户权限
     */
    private void checkPermissions() {
        boolean canWrite = isWriteStoragePermissionGranted();//获取写的权限
//        Log.d(TAG, " canWrite :" + canWrite);
        if (canWrite) {
            boolean canRead = isReadStoragePermissionGranted();//获取读的权限
//            Log.d(TAG, " canRead :" + canRead);
            if (canRead) {
//                Log.d(TAG, " Now you are ready to access camera :");
                callCamera();
            }
        }
    }


    /**
     * 打开照相机
     */
    private void callCamera() {
        mFilePath = Environment.getExternalStorageDirectory().getPath();
        // 保存图片的文件名
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss");// HH:mm:ss
        //获取当前时间
        Date date = new Date(System.currentTimeMillis());
        mFilePath = mFilePath + "/" + simpleDateFormat.format(date) + "mytest.jpg";
        Uri mUri = Uri.fromFile(new File(mFilePath));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            UserTypeMore7((new File(mFilePath)).getAbsolutePath());//使用另一种方法调用摄像头
        } else {
            Intent intent = new Intent();
            intent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);//设置图片保存路径
            intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(intent, REQUEST_CODE);
        }

    }

    /**
     * 使用另一种方法调用摄像头
     *
     * @param absolutePath
     */
    private void UserTypeMore7(String absolutePath) {
        Uri mCameraTempUri;
        try {
            ContentValues values = new ContentValues(1);
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg");
            values.put(MediaStore.Images.Media.DATA, absolutePath);
            mCameraTempUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            if (mCameraTempUri != null) {
                intent.putExtra(MediaStore.EXTRA_OUTPUT, mCameraTempUri);
                intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
            }
            intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//设置照片的横竖样式
            startActivityForResult(intent, REQUEST_CODE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private boolean isReadStoragePermissionGranted() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(Manifest.permission.CAMERA)
                    == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_READ);
                return false;
            }
        } else { //permission is automatically granted on sdk<23 upon installation
            return true;
        }
    }

    private boolean isWriteStoragePermissionGranted() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    == PackageManager.PERMISSION_GRANTED) {
//                Log.v(TAG, "Permission is granted2 write");
                return true;
            } else {
//                Log.v(TAG, "Permission is revoked write ");
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, REQUEST_CODE_WRITE);
                return false;
            }
        } else { //permission is automatically granted on sdk<23 upon installation
//            Log.v(TAG, "Permission is granted write");
            return true;
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE) {//照相机方法返回的数据
            if (resultCode == Activity.RESULT_OK) {//照相机返回成功
                FileInputStream is = null;
                try {
                    // 获取输入流
                    is = new FileInputStream(mFilePath);
                    if (null == is) {//判空操作
                        return;

                    }
                    // 把流解析成bitmap,此时就得到了清晰的原图
                    BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
                    bitmapOptions.inSampleSize = 5;  //压缩为原来的5分之一
                    Bitmap bitmap = BitmapFactory.decodeStream(is, null, bitmapOptions);
                    iv_photo_ato.setImageBitmap(bitmap);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                Toast.makeText(MainActivity.this, "用户取消了拍照功能", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

 

activity_main.xml

<?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=".MainActivity">

    <ImageView
        android:id="@+id/iv_photo_ato"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"
        android:scaleType="fitXY" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:gravity="center_horizontal"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_takephoto_amn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="20dp"
            android:text="系统组件拍照" />
        <Button
            android:id="@+id/btn_takephotocam_amn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="20dp"
            android:layout_marginLeft="20dp"
            android:text="自定义组件拍照" />
    </LinearLayout>

</RelativeLayout>

Customcamera.java 

package com.mobile.takephotodemo;

import android.content.Intent;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Environment;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author Jay
 * @date 2020/12/2
 * File description.
 */
public class Customcamera extends AppCompatActivity implements SurfaceHolder.Callback {
    private Camera mCamera;
    private SurfaceView mPreview;
    private SurfaceHolder mHolder;
    private int cameraId = 0;//声明cameraId属性,ID为1调用前置摄像头,为0调用后置摄像头。此处因有特殊需要故调用前置摄像头
    private Button btn_cancel_aca, btn_ok_aca, btn_photo_aca;
    //定义照片保存并显示的方法
    private Camera.PictureCallback mpictureCallback = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            String mFilePath = Environment.getExternalStorageDirectory().getPath();
            // 保存图片的文件名
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss");// HH:mm:ss
            //获取当前时间
            Date date = new Date(System.currentTimeMillis());
            mFilePath = mFilePath + "/" + simpleDateFormat.format(date) + "mytest.jpg";
            File tempfile = new File(mFilePath);//新建一个文件对象tempfile,并保存在某路径中
            try {
                FileOutputStream fos = new FileOutputStream(tempfile);
                fos.write(data);//将照片放入文件中
                fos.close();//关闭文件
                Intent intent = new Intent(Customcamera.this, CameraReaultActivity.class);//新建信使对象
                intent.putExtra("picpath", mFilePath);//打包文件给信使
                startActivity(intent);//打开新的activity,即打开展示照片的布局界面
                Customcamera.this.finish();//关闭现有界面
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cautomcamera);
        initView();//代码初始化
        setClick();//设置点击方法
        mHolder = mPreview.getHolder();
        mHolder.addCallback(this);

    }

    /**
     * 设置点击方法
     */
    private void setClick() {
        mPreview.setOnClickListener(new CustomcameraClick());
        btn_cancel_aca.setOnClickListener(new CustomcameraClick());
        btn_ok_aca.setOnClickListener(new CustomcameraClick());
        btn_photo_aca.setOnClickListener(new CustomcameraClick());
    }

    /**
     * 代码初始化
     */
    private void initView() {
        mPreview = findViewById(R.id.preview);//初始化预览界面
        btn_cancel_aca = findViewById(R.id.btn_cancel_aca);//取消按钮
        btn_ok_aca = findViewById(R.id.btn_ok_aca);//确定按钮
        btn_photo_aca = findViewById(R.id.btn_photo_aca);//拍照按钮
    }

    //定义“拍照”方法
    public void takePhoto() {
        //配置如下:
        Camera.Parameters parameters = mCamera.getParameters();// 获取相机参数集
        List<Camera.Size> SupportedPreviewSizes =
                parameters.getSupportedPreviewSizes();// 获取支持预览照片的尺寸
        Camera.Size previewSize = SupportedPreviewSizes.get(0);// 从List取出Size
        parameters.setPreviewSize(previewSize.width, previewSize.height);//
        //  设置预览照片的大小
        List<Camera.Size> supportedPictureSizes =
                parameters.getSupportedPictureSizes();// 获取支持保存图片的尺寸
        Camera.Size pictureSize = supportedPictureSizes.get(0);// 从List取出Size
        parameters.setPictureSize(pictureSize.width, pictureSize.height);//
        // 设置照片的大小
        mCamera.setParameters(parameters);

        //摄像头聚焦
        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                if (success) {
                    mCamera.takePicture(null, null, mpictureCallback);
                }
            }
        });

    }

    //activity生命周期在onResume是界面应是显示状态
    @Override
    protected void onResume() {
        super.onResume();
        if (mCamera == null) {//如果此时摄像头值仍为空
            mCamera = getCamera();//则通过getCamera()方法开启摄像头
            if (mHolder != null) {
                setStartPreview(mCamera, mHolder);//开启预览界面
            }
        }
    }

    //activity暂停的时候释放摄像头
    @Override
    protected void onPause() {
        super.onPause();
        releaseCamera();
    }

    //onResume()中提到的开启摄像头的方法
    private Camera getCamera() {
        Camera camera;//声明局部变量camera
        try {
            camera = Camera.open(cameraId);
        }//根据cameraId的设置打开前置摄像头
        catch (Exception e) {
            camera = null;
            e.printStackTrace();
        }
        return camera;
    }

    //开启预览界面
    private void setStartPreview(Camera camera, SurfaceHolder holder) {
        try {
            camera.setPreviewDisplay(holder);
            camera.setDisplayOrientation(90);//如果没有这行你看到的预览界面就会是水平的
            camera.startPreview();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //定义释放摄像头的方法
    private void releaseCamera() {
        if (mCamera != null) {//如果摄像头还未释放,则执行下面代码
            mCamera.stopPreview();//1.首先停止预览
            mCamera.setPreviewCallback(null);//2.预览返回值为null
            mCamera.release(); //3.释放摄像头
            mCamera = null;//4.摄像头对象值为null
        }
    }

    //定义新建预览界面的方法
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        setStartPreview(mCamera, mHolder);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        mCamera.stopPreview();//如果预览界面改变,则首先停止预览界面
        setStartPreview(mCamera, mHolder);//调整再重新打开预览界面
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        releaseCamera();//预览界面销毁则释放相机
    }

    private class CustomcameraClick implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.preview://点击预览界面聚焦
                    mCamera.autoFocus(null);
                    break;
                case R.id.btn_cancel_aca://取消按钮
                    finish();
                    break;
                case R.id.btn_ok_aca:
                    Toast.makeText(Customcamera.this, "确定按钮", Toast.LENGTH_SHORT).show();
                    break;
                case R.id.btn_photo_aca://拍照按钮
                    takePhoto();
                    break;
                default:
                    break;
            }
        }
    }
}

activity_customcarmea.xml

<?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:background="#ffffff"
    android:orientation="vertical">

    <!-- 显示预览图形 -->

    <SurfaceView
        android:id="@+id/preview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_cancel_aca"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="取消"
            android:layout_weight="1"
            />

        <Button
            android:id="@+id/btn_photo_aca"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="拍照"
            android:layout_weight="1"
            />

        <Button
            android:id="@+id/btn_ok_aca"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="确定"
            android:layout_weight="1"
            />
    </LinearLayout>

</LinearLayout>

 CameraReaultActivity.java

package com.mobile.takephotodemo;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

/**
 * @author Jay
 * @date 2020/12/2
 * File description.
 * 显示照相机结果的界面
 */
public class CameraReaultActivity extends AppCompatActivity {
    private Button btn_again_act, btn_userphoto_act;
    private ImageView iv_photo_act;
    private String mFilePath = "";
    // 縮放控制
    private Matrix matrix = new Matrix();
    private Matrix savedMatrix = new Matrix();

    // 不同状态的表示:
    private static final int NONE = 0;
    private static final int DRAG = 1;
    private static final int ZOOM = 2;
    private int mode = NONE;

    // 定义第一个按下的点,两只接触点的重点,以及出事的两指按下的距离:
    private PointF startPoint = new PointF();
    private PointF midPoint = new PointF();
    private float oriDis = 1f;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cameraresult);
        initView();//代码初始化
        getInfo();//获取上一个界面传递过来的信息
        setClick();//设置点击方法
    }

    /**
     * 设置点击方法
     */
    private void setClick() {
        btn_again_act.setOnClickListener(new CameraResultClick());
        btn_userphoto_act.setOnClickListener(new CameraResultClick());
        iv_photo_act.setOnTouchListener(new PhotoClick());//设置图片的点击方法
    }

    /**
     * 获取上一个界面传递过来的信息
     */
    private void getInfo() {
        mFilePath = getIntent().getStringExtra("picpath");//通过值"picpath"得到照片路径
        try {
            FileInputStream fis = new FileInputStream(mFilePath);//通过path把照片读到文件输入流中
            Bitmap bitmap = BitmapFactory.decodeStream(fis);//将输入流解码为bitmap
            Matrix matrix = new Matrix();//新建一个矩阵对象
            matrix.setRotate(90);//矩阵旋转操作让照片可以正对着你。但是还存在一个左右对称的问题
//新建位图,第2个参数至第5个参数表示位图的大小,matrix中是旋转后的位图信息,并使bitmap变量指向新的位图对象
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            iv_photo_act.setImageBitmap(bitmap);

            fixPhotoShowError();//修复图片一开始焦距不正常的问题
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 修复一开始焦距不正常的问题,里面的数据可以随意调试
     */
    private void fixPhotoShowError() {
        Matrix photomatrix=new Matrix();
        photomatrix.postScale(Float.parseFloat("0.4"),Float.parseFloat("0.4"));
        iv_photo_act.setImageMatrix(photomatrix);
    }

    /**
     * 代码初始化
     */
    private void initView() {
        btn_again_act = findViewById(R.id.btn_again_act);//重拍按钮
        btn_userphoto_act = findViewById(R.id.btn_userphoto_act);//使用按钮
        iv_photo_act = findViewById(R.id.iv_photo_act);//展示图片的控件
    }

    /**
     * 设置点击方法
     */
    private class CameraResultClick implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_again_act://重拍
                    startActivity(new Intent(CameraReaultActivity.this, Customcamera.class));
                    finish();
                    break;
                case R.id.btn_userphoto_act://使用照片
                    startActivity(new Intent(CameraReaultActivity.this, MainActivity.class).putExtra("picpath", mFilePath));
                    finish();
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 图片的点击方法
     */
    private class PhotoClick implements View.OnTouchListener {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            ImageView view = (ImageView) v;
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                // 单指
                case MotionEvent.ACTION_DOWN:
                    matrix.set(view.getImageMatrix());
                    savedMatrix.set(matrix);
                    startPoint.set(event.getX(), event.getY());
                    mode = DRAG;
                    break;
                // 双指
                case MotionEvent.ACTION_POINTER_DOWN:
                    oriDis = distance(event);
                    if (oriDis > 10f) {
                        savedMatrix.set(matrix);
                        midPoint = middle(event);
                        mode = ZOOM;
                    }
                    break;
                // 手指放开
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_POINTER_UP:
                    mode = NONE;
                    break;
                // 单指滑动事件
                case MotionEvent.ACTION_MOVE:
                    if (mode == DRAG) {
                        // 是一个手指拖动
                        matrix.set(savedMatrix);
                        matrix.postTranslate(event.getX() - startPoint.x, event.getY() - startPoint.y);
                    } else if (mode == ZOOM) {
                        // 两个手指滑动
                        float newDist = distance(event);
                        if (newDist > 10f) {
                            matrix.set(savedMatrix);
                            float scale = newDist / oriDis;
                            matrix.postScale(scale, scale, midPoint.x, midPoint.y);
                        }
                    }
                    break;
            }
            // 设置ImageView的Matrix
            view.setImageMatrix(matrix);
            return true;//返回值修改为true
        }
    }


    // 计算两个触摸点之间的距离
    private float distance(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return Float.valueOf(String.valueOf(Math.sqrt(x * x + y * y)));
    }

    // 计算两个触摸点的中点
    private PointF middle(MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        return new PointF(x / 2, y / 2);
    }
}

 activity_cameraresult.xml

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

    <ImageView
        android:id="@+id/iv_photo_act"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="matrix" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true">

        <Button
            android:id="@+id/btn_again_act"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:text="重拍" />

        <Button
            android:id="@+id/btn_userphoto_act"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="20dp"
            android:text="使用照片" />
    </RelativeLayout>

</RelativeLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mobile.takephotodemo">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="com.mobileiron.CONFIG_PERMISSION" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <!-- <uses-permission android:name="com.mobileiron.CONFIG_PERMISSION" /> -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".Customcamera" />
        <activity android:name=".CameraReaultActivity" />
    </application>

</manifest>

直接把这些文件放入代码中就可以运行,当然,如果想直接看效果,下面是demo的下载地址:

浏览图片界面无放大缩小图片功能demo地址:https://download.csdn.net/download/u010802275/13219030

浏览图片界面可以放大缩小图片demo地址:https://download.csdn.net/download/u010802275/13244538

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐