Android 拍照以及相册中选择(适配高版本)————上传多张照片之压缩处理、在线预览可伸缩放大(二)

在这里插入图片描述

______ Introduction ______
前言

       上一篇文章刚给大家总结完,关于上传头像的功能。此文章所述 主要是关于上传头像的具体流程以及如何对照片做裁剪处理,回调给控件显示;当然重中之重适配了Android高版本,有兴趣的大家可以去看一下:

       Android 拍照以及相册中选择(适配高版本)————上传头像并裁剪(一)

       本篇将从另一个开发场景,给大家带来关于上传多张照片的需求。

       记得之前拿华为的测试机拍出来的一张照片,就要十几M。在图片量过大的情况下,必须要对图片做压缩处理,减少内存损耗,也尽量避免占用内存;每当图片过大,或是多张图片一起上传的时候总会造成oom

       接下来,通过本篇让我们一起来实现,多张图片上传并做压缩处理之后,可以实现在线预览以及伸缩放大等功能

______ Animation Effect ______
效果

实测android 8、android 9、android 11、android 13、鸿蒙系统均有效;
手机机型分别为OPPO、华为、VIVO手机、小米、小米平板。

  1. VIVO android 13

  1. 华为 鸿蒙系统2.0.1

______ Function ______
功能

  1. 动态申请拍照,读,写权限
  2. 自定义弹出框
  3. 调用系统相机拍照
    3.1 调用系统相机申请拍照权限回调
    3.2 拍照完成回调
    3.3 对图片做压缩处理
  4. 自动获取sdk权限
    4.1 访问相册完成回调
    4.2 对图片做压缩处理
  5. 可在线预览照片
______ Concrete Realization ______
具体实现

(1)动态申请权限

	public static String[] permission = {
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA};

	AppUtils.requestPermission(permission);
    
	@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            //调用系统相机申请拍照权限回调
            case CAMERA_PERMISSIONS_REQUEST_CODE: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    if (AppUtils.hasSdcard()) {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                            imageUri = FileProvider.getUriForFile(MainActivity.this, "com.harry.takepicture.provider", cardImage);
                        } else {
                            imageUri = Uri.fromFile(cardImage);
                        }

                        PhotoUtils.takePicture(this, imageUri, CODE_CAMERA_CARD_REQUEST);
                    } else {
                        ToastUtils.showShort(this, "设备没有SD卡!");
                    }
                } else {
                    ToastUtils.showShort(this, "请允许打开相机!!");
                }
                break;
            }
        }
    }
   public class AppUtils {

    /**
     * 申请权限
     *
     * @param permission
     */
    public static void requestPermission(String[] permission) {
        BaseActivity.requestRunTimePermission(permission, new PermissionListener() {
            @Override
            public void onGranted() {
                Log.e("tb", "所有权限授权成功");
            }

            @Override
            public void onGranted(List<String> grantedPermission) {
                Log.e("tb", "授权成功集合权限---" + grantedPermission);
            }

            @Override
            public void onDenied(List<String> deniedPermission) {
                Log.e("tb", "授权失败集合权限---" + deniedPermission);
            }
        });
    }
}

(2)自定义弹出框

本篇主要内容为Camera相关,忽略…

(3.1)调用系统相机拍照

	/**
     * 拍照
     *
     * @param
     */
    private void takePhoto() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
                ToastUtils.showShort(this, "您已经拒绝过一次");
            }
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE}, CAMERA_PERMISSIONS_REQUEST_CODE);
        } else {//有权限直接调用系统相机拍照
            if (AppUtils.hasSdcard()) {
                cardImage = new File(Environment.getExternalStorageDirectory().getPath(), System.currentTimeMillis() + ".jpg");

                //通过FileProvider创建一个content类型的Uri
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    imageUri = FileProvider.getUriForFile(this, "com.harry.takepicture.provider", cardImage);
                } else {
                    imageUri = Uri.fromFile(cardImage);
                }

                PhotoUtils.takePicture(this, imageUri, CODE_CAMERA_CARD_REQUEST);
            } else {
                ToastUtils.showShort(this, "设备没有SD卡!");
            }
        }
    }

(3.2)处理拍照回调

 /**
     * 执行回调
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            fileCropUri = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg");
            switch (requestCode) {
                //拍照完成回调
                case CODE_CAMERA_CARD_REQUEST:
                    cropImageUri = Uri.fromFile(fileCropUri);
                    String img = cardImage.getAbsolutePath();
                    //img就是压缩后的图片
                    String imgPic = BitmapUtil.compressImageUpload(img);
                    Log.e("tb", "paths----------" + imgPic);

                    urlimg.add(0, imgPic);

                    if (null != imgPic) {
                        showPic(imgPic);
                    }
                    break;               
                default:
            }
        }
    }

(3.3)对图片做压缩处理

BitmapUtil.compressImageUpload(img);
/**
 * @author 拉莫帅
 * @date 2021/9/9
 * @address
 * @Desc BitmapUtil
 */
public class BitmapUtil {

    /**
     * 质量压缩方法
     *
     * @param image
     * @return
     */
    private static Bitmap compressImage(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        int options = 100;
        while (baos.toByteArray().length / 1024 > 100) {
            baos.reset();
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);
            options -= 10;
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
        return bitmap;
    }

    /**
     * 图片按比例大小压缩方法(根据路径获取图片并压缩)
     *
     * @param srcPath
     * @return
     */
    private static Bitmap getImage(String srcPath) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空

        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
        float hh = 800f;// 这里设置高度为800f
        float ww = 480f;// 这里设置宽度为480f
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;// 设置缩放比例
        // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
        return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
    }

    /**
     * 将压缩的bitmap保存到SDCard卡临时文件夹,用于上传
     *
     * @param filename
     * @param bit
     * @return
     */
    private static String saveMyBitmap(String filename, Bitmap bit) {
        String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/laopai/";
        String filePath = baseDir + filename;
        File dir = new File(baseDir);
        if (!dir.exists()) {
            dir.mkdir();
        }

        File f = new File(filePath);
        try {
            f.createNewFile();
            FileOutputStream fOut = null;
            fOut = new FileOutputStream(f);
            bit.compress(Bitmap.CompressFormat.PNG, 100, fOut);
            fOut.flush();
            fOut.close();
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        return filePath;
    }

    /**
     * 压缩上传路径
     *
     * @param path
     * @return
     */
    public static String compressImageUpload(String path) {
        String filename = path.substring(path.lastIndexOf("/") + 1);
        Bitmap image = getImage(path);
        return saveMyBitmap(filename, image);
    }


    /**
     * 清除缓存文件
     */
    public static void deleteCacheFile() {
        File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/laopai/");
        RecursionDeleteFile(file);
    }

    /**
     * 递归删除
     */
    private static void RecursionDeleteFile(File file) {
        if (file.isFile()) {
            file.delete();
            return;
        }
        if (file.isDirectory()) {
            File[] childFile = file.listFiles();
            if (childFile == null || childFile.length == 0) {
                file.delete();
                return;
            }
            for (File f : childFile) {
                RecursionDeleteFile(f);
            }
            file.delete();
        }
    }
}

(4)自动获取SDK权限

	/**
     * 自动获取sdk权限
     */
    private void autoObtainStoragePermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSIONS_REQUEST_CODE);
        } else {
            PhotoUtils.openPic(this, CODE_GALLERY_CARD_REQUEST);
        }
    }

(4.1)访问相册完成回调

 /**
     * 执行回调
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            fileCropUri = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg");
            switch (requestCode) {
                //访问相册完成回调
                case CODE_GALLERY_CARD_REQUEST:
                    if (AppUtils.hasSdcard()) {
                        cropImageUri = Uri.fromFile(fileCropUri);
                        String path = GetPathFromUri.getPath(this, data.getData());
                        //imgPath就是压缩后的图片
                        String imgPath = BitmapUtil.compressImageUpload(path);
                        Log.e("tb", "paths----------" + imgPath);
                        urlimg.add(0, imgPath);

                        if (null != imgPath) {
                            showPic(imgPath);
                        }
                    } else {
                        ToastUtils.showShort(this, "设备没有SD卡!");
                    }
                    break;
                default:
            }
        }
    }

(4.2)对图片做压缩处理 —> (3.3)

BitmapUtil.compressImageUpload(path);

(5)可在线预览照片

	// 显示图片
	List<String> pic = new ArrayList<>();
	
	/**
     * 展示
     *
     * @param imgPic
     */
    private void showPic(String imgPic) {
        pic.add(0, imgPic);
        picAdapter.notifyDataSetChanged();
    }
    // 进入预览界面
 	Intent intent = new Intent(MainActivity.this, ShowImgActivity.class);
 	intent.putExtra("image_path", pic.get(position));
 	startActivity(intent);

对于预览图片,单点/多点触摸来进行图片缩放
采用的是开源PhotoView控件

implementation 'com.github.chrisbanes:PhotoView:1.2.6'

此项目个人采用的是jar的方式,依赖方式至上。

______ Full Implementation ______
完整实现

/**
 * @author 拉莫帅
 * @date 2023/4/01
 * @address
 * @Desc TakePicture 上传多张照片并压缩处理
 */
public class MainActivity extends BaseActivity implements View.OnClickListener {
    public static String[] permission = {
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA};

    private RecyclerView recycle;
    private Intent intent;
    private View view;
    private List<String> pic; // 显示图片
    private List<String> urlimg; // 上传图片路径

    private Uri cropImageUri;
    private File cardImage;
    private File fileCropUri;//裁剪的照片
    private Uri imageUri;//拍照所得到的图像的保存路径
    private static final int CAMERA_PERMISSIONS_REQUEST_CODE = 0x03;
    private static final int STORAGE_PERMISSIONS_REQUEST_CODE = 0x04;

    private static final int CODE_GALLERY_CARD_REQUEST = 0xa5;
    private static final int CODE_CAMERA_CARD_REQUEST = 0xa6;
    private PicAdapter picAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStatusBg(1);
        AppUtils.requestPermission(permission);

        initView();
        initData();
    }

    @Override
    protected View addContentLayout() {
        view = getLayoutInflater().inflate(R.layout.activity_main, contentLayout, false);
        return view;
    }

    private void initView() {
        recycle = findViewById(R.id.recycle);

        // 初始化数据
        urlimg = new ArrayList<>();
        pic = new ArrayList<>();
        pic.add(this.getResources().getResourceName(R.drawable.add_pic_icon));
    }

    private void initData() {
        // 初始化适配器
        picAdapter = new PicAdapter(this, pic);
        recycle.setLayoutManager(new GridLayoutManager(this, 3));
        recycle.setAdapter(picAdapter);
        //添加ItemDecoration,item之间的间隔
        int leftRight = AppUtils.dip2px(15, this);
        int topBottom = AppUtils.dip2px(15, this);
        recycle.addItemDecoration(new SpacesItemDecoration(leftRight, topBottom));
        picAdapter.setOnItemClickListener(new PicAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                if (pic.size() > 2 && pic.get(position).equals(MainActivity.this.getResources().getResourceName(R.drawable.add_pic_icon))) {
                    ToastUtils.showShort(MainActivity.this, "最多只能上传2张图片");
                } else {
                    if (pic.get(position).equals(MainActivity.this.getResources().getResourceName(R.drawable.add_pic_icon))) {
                        select();
                    } else {
                        intent = new Intent(MainActivity.this, ShowImgActivity.class);
                        intent.putExtra("image_path", pic.get(position));
                        startActivity(intent);
                    }
                }
            }
        });

        picAdapter.setOnClickDelete(new PicAdapter.OnClickDelete() {
            @Override
            public void myClickDelete(int pos) {
                if (pic.get(pos).equals(MainActivity.this.getResources().getResourceName(R.drawable.add_pic_icon))) {
                    return;
                }
                if (pic.size() > 0) {
                    pic.remove(pos);
                    picAdapter.notifyDataSetChanged();
                }
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.userinfo_iv_head:
                select();
                break;
            case R.id.rl_head_camera:
                takePhoto();
                AppUtils.dismiss();
                break;
            case R.id.rl_head_photo:
                autoObtainStoragePermission();
                AppUtils.dismiss();
                break;
            case R.id.rl_head_cancel:
                AppUtils.dismiss();
                break;
        }
    }

    private void select() {
        AppUtils.selectPhoto(MainActivity.this, R.layout.dialog_head, R.layout.activity_main, this);
    }

    /**
     * 拍照
     *
     * @param
     */
    private void takePhoto() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
                ToastUtils.showShort(this, "您已经拒绝过一次");
            }
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE}, CAMERA_PERMISSIONS_REQUEST_CODE);
        } else {//有权限直接调用系统相机拍照
            if (AppUtils.hasSdcard()) {
                cardImage = new File(Environment.getExternalStorageDirectory().getPath(), System.currentTimeMillis() + ".jpg");

                //通过FileProvider创建一个content类型的Uri
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    imageUri = FileProvider.getUriForFile(this, "com.harry.takepicture.provider", cardImage);
                } else {
                    imageUri = Uri.fromFile(cardImage);
                }

                PhotoUtils.takePicture(this, imageUri, CODE_CAMERA_CARD_REQUEST);
            } else {
                ToastUtils.showShort(this, "设备没有SD卡!");
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            //调用系统相机申请拍照权限回调
            case CAMERA_PERMISSIONS_REQUEST_CODE: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    if (AppUtils.hasSdcard()) {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                            imageUri = FileProvider.getUriForFile(MainActivity.this, "com.harry.takepicture.provider", cardImage);
                        } else {
                            imageUri = Uri.fromFile(cardImage);
                        }

                        PhotoUtils.takePicture(this, imageUri, CODE_CAMERA_CARD_REQUEST);
                    } else {
                        ToastUtils.showShort(this, "设备没有SD卡!");
                    }
                } else {
                    ToastUtils.showShort(this, "请允许打开相机!!");
                }
                break;
            }
        }
    }

    /**
     * 自动获取sdk权限
     */
    private void autoObtainStoragePermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSIONS_REQUEST_CODE);
        } else {
            PhotoUtils.openPic(this, CODE_GALLERY_CARD_REQUEST);
        }
    }

    /**
     * 执行回调
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            fileCropUri = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg");
            switch (requestCode) {
                //拍照完成回调
                case CODE_CAMERA_CARD_REQUEST:
                    cropImageUri = Uri.fromFile(fileCropUri);
                    String img = cardImage.getAbsolutePath();
                    //img就是压缩后的图片
                    String imgPic = BitmapUtil.compressImageUpload(img);
                    Log.e("tb", "paths----------" + imgPic);

                    urlimg.add(0, imgPic);

                    if (null != imgPic) {
                        showPic(imgPic);
                    }
                    break;
                //访问相册完成回调
                case CODE_GALLERY_CARD_REQUEST:
                    if (AppUtils.hasSdcard()) {
                        cropImageUri = Uri.fromFile(fileCropUri);
                        String path = GetPathFromUri.getPath(this, data.getData());
                        //imgPath就是压缩后的图片
                        String imgPath = BitmapUtil.compressImageUpload(path);
                        Log.e("tb", "paths----------" + imgPath);
                        urlimg.add(0, imgPath);

                        if (null != imgPath) {
                            showPic(imgPath);
                        }
                    } else {
                        ToastUtils.showShort(this, "设备没有SD卡!");
                    }
                    break;
                default:
            }
        }
    }

    /**
     * 展示
     *
     * @param imgPic
     */
    private void showPic(String imgPic) {
        pic.add(0, imgPic);
        picAdapter.notifyDataSetChanged();
    }
}
/**
 * @author 拉莫帅 
 * @date 2023/4/01
 * @address
 * @Desc PicAdapter适配器
 */
public class PicAdapter extends RecyclerView.Adapter<PicAdapter.MyViewHolder> {

    private Context context;
    private OnItemClickListener onItemClickListener;
    private OnClickDelete onClickDelete;
    private List<String> ml;

    public PicAdapter(Context ctx, List<String> ml) {
        this.context = ctx;
        this.ml = ml;
    }

    public interface OnItemClickListener{
        void onItemClick(View view, int position);
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemClickListener = onItemClickListener;
    }

    public interface OnClickDelete{
        void myClickDelete(int pos);
    }
    public void setOnClickDelete(OnClickDelete onClickDelete) {
        this.onClickDelete = onClickDelete;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        MyViewHolder holder = new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_photo, parent, false));
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder holder, int position) {

        if(ml.get(position).equals(context.getResources().getResourceName(R.drawable.add_pic_icon))){
            ImageUtils.ImageIntDefault(context,context.getResources().getDrawable(R.drawable.add_pic_icon),holder.iv_image);
        }else{
            ImageUtils.ImageDefault(context,ml.get(position),holder.iv_image);
        }

        if(onItemClickListener!=null){
            holder.iv_image.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = holder.getLayoutPosition();
                    onItemClickListener.onItemClick(holder.iv_image, position);
                }
            });
        }

        if(onClickDelete!=null){
            holder.iv_delete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Log.e("tb","身份证删除-----------------------------------");
                    int position = holder.getLayoutPosition();
                    onClickDelete.myClickDelete(position);
                }
            });
        }
    }

    @Override
    public int getItemCount() {
        return (ml.size() == 0 || ml == null) ? 0 : ml.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        private ImageView iv_image,iv_delete;

        public MyViewHolder(View itemView) {
            super(itemView);
            iv_image = itemView.findViewById(R.id.iv_image);
            iv_delete = itemView.findViewById(R.id.iv_delete);
        }
    }
}

item_photo.xml:

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

    <ImageView
        android:scaleType="centerCrop"
        android:id="@+id/iv_image"
        android:src="@drawable/add_pic_icon"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ImageView
        android:scaleType="fitXY"
        android:layout_gravity="right"
        android:id="@+id/iv_delete"
        android:layout_width="30dp"
        android:layout_height="28dp"
        android:src="@drawable/delete_icon" />

</FrameLayout>
/**
 * @author 拉莫帅
 * @date 2023/4/01
 * @address
 * @Desc 预览照片
 */
public class ShowImgActivity extends BaseActivity {

    private View view;
    private TextView title;
    private PhotoView iv_show;
    private String image_path;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStatusBg(1);

        title = findViewById(R.id.title);
        title.setText("预览照片");
        iv_show = findViewById(R.id.iv_show);
        image_path = getIntent().getStringExtra("image_path");
        ImageUtils.ImageDefault(this, image_path, iv_show);
    }

    @Override
    protected View addContentLayout() {
        view = getLayoutInflater().inflate(R.layout.activity_show_img, contentLayout, false);
        return view;
    }
}

activity_show_img.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:background="@color/white">

    <uk.co.senab.photoview.PhotoView
        android:id="@+id/iv_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />
</RelativeLayout>
______ Ending ______
结尾

关于Camera系列文章到这里就已经结束了!
节后赶紧来给大家更新了,本来五一之前就应该把连载篇,分享给大家。
基本上,关于相机也就这些东西;这里把它分享给大家,欢迎大家共同学习、留言探讨!

最后的最后,大家想要完整版的源代码,欢迎来start !
完整版源码下载地址:Android + <调用相机拍照 & 选择相册> + 数码相机

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
以下是一个简单的vue2 vant附件上传公用组件,包含附件预览和图片上传以及图片预览功能,同时也适配了iOS系统,并对图片进行了压缩。 ``` <template> <div> <van-uploader v-model="files" :after-read="afterRead" :before-delete="beforeDelete" :max-count="maxCount" :show-upload="showUpload" :preview-cover="previewCover" :preview-full-image="previewFullImage" :preview-image="previewImage" :deletable="deletable" :upload-icon="uploadIcon" :delete-icon="deleteIcon" :disabled="disabled" :capture="capture" :accept="accept" :compress="compress" :max-size="maxSize" > <template v-slot:upload> <img src="上传图标路径" alt="上传附件" /> </template> </van-uploader> <van-image-preview v-model="previewVisible" :images="previewImages" /> </div> </template> <script> import { Toast } from "vant"; export default { name: "FileUploader", props: { value: { type: Array, default: () => [] }, maxCount: { type: Number, default: 10 }, showUpload: { type: Boolean, default: true }, previewCover: { type: Boolean, default: false }, previewFullImage: { type: Boolean, default: true }, previewImage: { type: Boolean, default: true }, deletable: { type: Boolean, default: true }, uploadIcon: { type: String, default: "photograph" }, deleteIcon: { type: String, default: "delete" }, disabled: { type: Boolean, default: false }, capture: { type: String, default: "camera" }, accept: { type: String, default: "image/*" }, compress: { type: Object, default: () => ({ quality: 0.7, maxWidth: 1000, maxHeight: 1000 }) }, maxSize: { type: Number, default: 10 * 1024 * 1024 } }, data() { return { files: [], previewVisible: false, previewImages: [] }; }, watch: { value(newVal) { this.files = newVal; }, files(newVal) { this.$emit("input", newVal); } }, methods: { afterRead(file) { if (file.type.indexOf("image") === 0) { this.compressImage(file.file) .then(data => { this.files.push({ url: URL.createObjectURL(data), file: data }); }) .catch(() => { Toast("图片压缩失败,请重新选择"); }); } else { this.files.push(file); } }, beforeDelete(file, files) { return new Promise(resolve => { if (file.type.indexOf("image") === 0) { URL.revokeObjectURL(file.url); } resolve(); }); }, compressImage(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = event => { const img = new Image(); img.src = event.target.result; img.onload = () => { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); const { width, height } = this.compressImageSize( img.width, img.height ); canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0, width, height); canvas.toBlob( blob => { resolve(blob); }, "image/jpeg", this.compress.quality ); }; img.onerror = () => { reject(); }; }; }); }, compressImageSize(width, height) { const maxWidth = this.compress.maxWidth; const maxHeight = this.compress.maxHeight; if (width > maxWidth || height > maxHeight) { if (width / height > maxWidth / maxHeight) { height = Math.round((height * maxWidth) / width); width = maxWidth; } else { width = Math.round((width * maxHeight) / height); height = maxHeight; } } return { width, height }; } } }; </script> ``` 在使用该组件时,可以通过v-model绑定组件的值,例如: ``` <file-uploader v-model="attachments" /> ``` 其,attachments是一个数组,用于存储上传的附件。在上传图片时,会对图片进行压缩,并且支持iOS系统,同时也支持附件预览和图片预览功能。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值