上一篇
安卓处理图片入门问题
- 行业动态
- 2025-04-22
- 4
安卓处理图片基础流程
权限处理
安卓6.0及以上系统需要动态申请存储权限:
// 检查权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1); } // 处理权限回调 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == 1) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限授予成功 } else { // 权限被拒绝 } } }
读取本地图片
通过ContentResolver获取图片:
// 从相册选择图片 Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, REQUEST_CODE); // 处理返回结果 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) { Uri uri = data.getData(); Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri); // 显示图片 imageView.setImageBitmap(bitmap); } }
图片来源 | Uri类型 | 处理方式 |
---|---|---|
系统相册 | content:// | 使用MediaStore解析 |
文件管理器 | file:// | 直接通过File类读取 |
网络图片 | http:// | 需先下载到本地再处理 |
显示图片到ImageView
// 基础显示 imageView.setImageBitmap(bitmap); // 带缩放显示(保持宽高比) imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
图片压缩处理
防止OOM(Out Of Memory)的采样率压缩:
public static Bitmap decodeSampledBitmap(String filePath, int reqWidth, int reqHeight) { // 第一阶段:获取图片尺寸 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, options); // 计算采样率 options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); options.inJustDecodeBounds = false; // 第二阶段:生成目标Bitmap return BitmapFactory.decodeFile(filePath, options); } private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { int height = options.outHeight; int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { int halfHeight = height / 2; int halfWidth = width / 2; while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize = 2; } } return inSampleSize; }
图片裁剪功能实现
调用系统裁剪工具:
// 启动裁剪Intent Intent cropIntent = new Intent("com.android.camera.action.CROP"); cropIntent.setDataAndType(uri, "image/"); cropIntent.putExtra("crop", true); cropIntent.putExtra("aspectX", 1); // X方向比例 cropIntent.putExtra("aspectY", 1); // Y方向比例 cropIntent.putExtra("outputX", 300); // 输出宽度 cropIntent.putExtra("outputY", 300); // 输出高度 cropIntent.putExtra("return-data", true); // 是否返回数据 startActivityForResult(cropIntent, CROP_REQUEST_CODE);
常见问题解决方案
问题现象 | 解决方案 |
---|---|
加载大图时应用崩溃(OOM) | 使用inSampleSize 进行采样率压缩,或启用BitmapFactory.Options.inBitmap 复用内存 |
图片旋转方向不正确 | 通过ExifInterface 读取图片旋转信息,使用Matrix 进行矫正 |
图片显示变形 | 设置ImageView 的scaleType 为CENTER_CROP 或FIT_CENTER |
相关问题与解答
Q1:如何处理相机拍摄的照片?
A1:通过FileProvider
生成临时文件路径,使用MediaStore.ACTION_IMAGE_CAPTURE
启动相机Intent:
// 创建文件路径 File file = new File(getExternalFilesDir(null), "photo.jpg"); Uri photoUri = FileProvider.getUriForFile(this, "com.example.fileprovider", file); // 启动相机 Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); startActivityForResult(captureIntent, CAMERA_REQUEST_CODE);
Q2:如何将处理后的图片保存到相册?
A2:通过MediaStore.Images.Media.insertImage()
方法插入到系统图库:
// 保存Bitmap到相册 ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath()); getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); // 或直接调用系统广播刷新图库 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));