Android——从系统相册读取照片并展示——2个方法

发布时间 2024-01-10 20:50:33作者: 小白龙白龙马

布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

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

        <Button
            android:id="@+id/btn_choose_common"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="普通选择图片"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <Button
            android:id="@+id/btn_choose_register"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="注册相册结果"
            android:textColor="@color/black"
            android:textSize="17sp" />

    </LinearLayout>

    <ImageView
        android:id="@+id/iv_photo"
        android:layout_width="match_parent"
        android:layout_height="360dp" />
</LinearLayout>

 

 

 

 

 

activity:

package com.example.myapplication;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.widget.ImageView;

public class ChoosePhotoActivity extends AppCompatActivity {

    private final static String TAG = "ChoosePhotoActivity";

    private int CHOOSE_CODE = 3; // 只在相册挑选图片的请求码

    private ImageView iv_photo; // 声明一个图像视图对象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_choose_photo);


        iv_photo = findViewById(R.id.iv_photo);

        findViewById(R.id.btn_choose_common).setOnClickListener(v -> {

            // 创建一个内容获取动作的意图(准备跳到系统相册)
            Intent intent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

            intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");

            startActivityForResult(intent, CHOOSE_CODE);

        });



        // 注册一个善后工作的活动结果启动器,获取指定类型的内容
        ActivityResultLauncher launcher = registerForActivityResult(new ActivityResultContracts.GetContent(), uri -> {
            if (uri != null) {

                // 根据指定图片的uri,获得自动缩小后的位图对象
                Bitmap bitmap = BitmapUtil.getAutoZoomImage(this, uri);

                iv_photo.setImageBitmap(bitmap); // 设置图像视图的位图对象
            }
        });



        // 点击按钮时触发活动结果启动器,传入待获取内容的文件类型
        findViewById(R.id.btn_choose_register).setOnClickListener(v -> launcher.launch("image/*"));





    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {

        super.onActivityResult(requestCode, resultCode, intent);

        if (resultCode==RESULT_OK && requestCode==CHOOSE_CODE) { // 从相册回来
            if (intent.getData() != null) {
                Uri uri = intent.getData(); // 获得已选择照片的路径对象
                // 根据指定图片的uri,获得自动缩小后的位图对象
                Bitmap bitmap = BitmapUtil.getAutoZoomImage(this, uri);
                iv_photo.setImageBitmap(bitmap); // 设置图像视图的位图对象
            }
        }
    }

}

 

 

 

 

 

BitmapUtil
package com.example.myapplication;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;

public class BitmapUtil {
    private final static String TAG = "BitmapUtil";

    // 把位图数据保存到指定路径的图片文件
    public static void saveImage(String path, Bitmap bitmap) {
        // 根据指定的文件路径构建文件输出流对象
        try (FileOutputStream fos = new FileOutputStream(path)) {
            // 把位图数据压缩到文件输出流中
            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 把位图数据保存到指定路径的图片文件
    public static void saveImage(String path, ByteBuffer buffer) {
        try (FileOutputStream fos = new FileOutputStream(path)) {
            byte[] data = new byte[buffer.remaining()];
            buffer.get(data);
            fos.write(data, 0, data.length);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 获得旋转角度之后的位图对象
    public static Bitmap getRotateBitmap(Bitmap bitmap, float rotateDegree) {
        Matrix matrix = new Matrix(); // 创建操作图片用的矩阵对象
        matrix.postRotate(rotateDegree); // 执行图片的旋转动作
        // 创建并返回旋转后的位图对象
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                bitmap.getHeight(), matrix, false);
    }

    // 获得比例缩放之后的位图对象
    public static Bitmap getScaleBitmap(Bitmap bitmap, double scaleRatio) {
        Matrix matrix = new Matrix(); // 创建操作图片用的矩阵对象
        matrix.postScale((float)scaleRatio, (float)scaleRatio);
        // 创建并返回缩放后的位图对象
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                bitmap.getHeight(), matrix, false);
    }

    // 获得自动缩小后的位图对象
    public static Bitmap getAutoZoomImage(Context ctx, Uri uri) {
        Log.d(TAG, "getAutoZoomImage uri="+uri.toString());
        Bitmap zoomBitmap = null;

        // 打开指定uri获得输入流对象
        try (InputStream is = ctx.getContentResolver().openInputStream(uri))
        {
            // 从输入流解码得到原始的位图对象
            Bitmap originBitmap = BitmapFactory.decodeStream(is);

            int ratio = originBitmap.getWidth()/2000+1;

            // 获得比例缩放之后的位图对象
            zoomBitmap = getScaleBitmap(originBitmap, 1.0/ratio);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return zoomBitmap;
    }

    // 获得自动缩小后的位图对象
    public static Bitmap getAutoZoomImage(Bitmap origin) {
        int ratio = origin.getWidth()/2000+1;
        // 获得并返回比例缩放之后的位图对象
        return getScaleBitmap(origin, 1.0/ratio);
    }

    // 获得自动缩小后的图片路径
    public static String getAutoZoomPath(Context ctx, Uri uri) {
        Log.d(TAG, "getAutoZoomPath uri="+uri.toString());
        String imagePath = String.format("%s/%s.jpg",
                ctx.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString(),
                DateUtil.getNowDateTime());
        // 打开指定uri获得输入流对象
        try (InputStream is = ctx.getContentResolver().openInputStream(uri)) {
            // 从输入流解码得到原始的位图对象
            Bitmap originBitmap = BitmapFactory.decodeStream(is);
            int ratio = originBitmap.getWidth()/1000+1;
            // 获得比例缩放之后的位图对象
            Bitmap zoomBitmap = getScaleBitmap(originBitmap, 1.0/ratio);
            saveImage(imagePath, zoomBitmap);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return imagePath;
    }

}