当前位置:首页 > 行业动态 > 正文

安卓处理图片入门问题

安卓处理图片基础流程

权限处理

安卓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进行矫正
图片显示变形 设置ImageViewscaleTypeCENTER_CROPFIT_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)));
0