Android——从系统相册读取照片并展示——2个方法
布局:
<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;
}
}