Bootstrap

android 拍照图片保存方法之二

直接利用(Bitmap) extras.get("data")方法获得的图片是系统自动压缩过的缩略图,清晰图不够。

这次介绍的方法是通过uri传递来保存图片。

大概思路如下:

在程序内部创建一个临时文件,利用临时文件的uri传递给响应事件获得原图,并且在一个imageview中显示出来,如果喜欢的话就重新命名保存在公共相册中去。在保存的时候可以提供一定比例压缩一下图片,默认是按30%压缩。

首先在AndroidManifest.xml文件中添加权限并使用FileProvider,选择性地将封装过的Uri共享到外部

<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="com.example.mycamera.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

创建一个资源文件命名为file_paths.xml

<?xml version="1.0" encoding="utf-8"?>


    <paths  xmlns:android="http://schemas.android.com/apk/res/android">
        <external-files-path
            name="my_images"
            path="Pictures" />
    </paths>

然后创建一个获得内部临时文件的uri方法

 private Uri getImageUri() {
  
        String imageFileName = "temp";
        // 获取外部存储的图片目录

        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File imageFile = null;

            imageFile =new File(storageDir +"/"+imageFileName+".jpg");


        // 如果文件创建成功,则返回其URI,否则返回null
        if (imageFile != null) {
            return FileProvider.getUriForFile(this, "com.example.mycamera.fileprovider", imageFile);
        } else {
            return null;
        }


    }

在拍照后通过putExtra(MediaStore.EXTRA_OUTPUT, tempfileuri)

传递图片的uri

   private void takePicture() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            tempfileuri = getImageUri();
            if (tempfileuri != null) {
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempfileuri);
                startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
            } else {
                // 处理URI为null的情况
            }
        }
    }

接着在响应事件中根据uri显示图片

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            // 现在可以使用这个URI,图片已经被保存到这个位置
            //  File file = new File(String.valueOf(tempfileuri));
            try {
                // 使用 ContentResolver 加载图片
                bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), tempfileuri);

                // 将加载的图片显示到 ImageView
                imageView.setImageBitmap(bitmap);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

为拍照按钮和保存按钮绑定响应的方法

  btnCamera.setOnClickListener(v -> {
            if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA)
                    != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA},
                        REQUEST_CAMERA_PERMISSION);
            }
            takePicture();
        });
   btnSave.setOnClickListener(v -> {
            saveImageToGalleryQ(bitmap);
            bitmap = null;
            imageView.setImageBitmap(bitmap);
            photoname.setText("");
            imageView.invalidate();
        });

保存图片方法如下

public void saveImageToGalleryQ(Bitmap image) {
        String mImageFileName = photoname.getText().toString() + "_" + getDateTime();
       int yasuo=100;
       String editTextNumberstring = editTextNumber.getText().toString();
       if(editTextNumberstring.equals(""))
       {
           yasuo=0;
       }else {
           yasuo=Integer.parseInt(editTextNumberstring);
           if(yasuo<=0){
               yasuo=0;
           }else if(yasuo>=100){
               yasuo=100;
           }
       }

        ContentValues values = new ContentValues();
        values.put(MediaStore.MediaColumns.DISPLAY_NAME, mImageFileName);
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        ContentResolver contentResolver = getContentResolver();
        try {
            // 将Bitmap保存到相册
            Uri photouri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            if (photouri != null) {
                // 获取输出流
                android.os.ParcelFileDescriptor parcelFileDescriptor = contentResolver.openFileDescriptor(photouri, "w");
                if (parcelFileDescriptor != null) {
                    java.io.FileOutputStream fileOutputStream = new java.io.FileOutputStream(parcelFileDescriptor.getFileDescriptor());
                    image.compress(Bitmap.CompressFormat.JPEG, 100-yasuo, fileOutputStream);
                    fileOutputStream.close();
                    parcelFileDescriptor.close();
                }
                Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                mediaScanIntent.setData(photouri);
                sendBroadcast(mediaScanIntent);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

;