You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用android-crop库裁剪图片后,如何在onActivityResult中转为Bitmap?

Android裁剪图片转Bitmap实现方案

刚好我之前用过这个裁剪库,给你补全并优化这段处理裁剪后图片转Bitmap的代码,直接上可运行的实现方案:

完整代码实现

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent result) {
    super.onActivityResult(requestCode, resultCode, result);
    
    // 处理图片选择完成的回调,启动裁剪
    if (requestCode == Crop.REQUEST_PICK && resultCode == RESULT_OK) {
        beginCrop(result.getData());
    } 
    // 处理裁剪完成的回调,转换为Bitmap
    else if (requestCode == Crop.REQUEST_CROP) {
        handleCrop(resultCode, result);
    }
}

// 初始化裁剪配置并启动裁剪界面
private void beginCrop(Uri source) {
    // 裁剪后的图片保存到缓存目录,避免占用公共存储空间
    Uri destination = Uri.fromFile(new File(getCacheDir(), "cropped_temp.jpg"));
    // 这里可以根据需求设置裁剪比例,比如asSquare()是正方形裁剪,也可以用asRatio(16,9)等
    Crop.of(source, destination).asSquare().start(this);
}

// 处理裁剪结果,转换为Bitmap
private void handleCrop(int resultCode, Intent result) {
    if (resultCode == RESULT_OK) {
        // 通过库提供的方法获取裁剪后的图片Uri
        Uri croppedUri = Crop.getOutput(result);
        if (croppedUri != null) {
            // 将Uri转换为Bitmap,同时做内存优化
            Bitmap croppedBitmap = convertUriToBitmap(croppedUri);
            if (croppedBitmap != null) {
                // 这里就可以使用Bitmap做后续操作了,比如设置到ImageView
                // imageView.setImageBitmap(croppedBitmap);
            } else {
                Toast.makeText(this, "图片转换失败", Toast.LENGTH_SHORT).show();
            }
        }
    } else if (resultCode == Crop.RESULT_ERROR) {
        // 处理裁剪过程中的错误
        Exception error = Crop.getError(result);
        Toast.makeText(this, "裁剪失败:" + error.getMessage(), Toast.LENGTH_SHORT).show();
    }
}

// 将Uri转换为Bitmap,并做内存优化避免OOM
private Bitmap convertUriToBitmap(Uri uri) {
    try {
        BitmapFactory.Options options = new BitmapFactory.Options();
        // 先只读取图片尺寸,不加载到内存
        options.inJustDecodeBounds = true;
        InputStream inputStream = getContentResolver().openInputStream(uri);
        BitmapFactory.decodeStream(inputStream, null, options);
        inputStream.close();

        // 根据目标尺寸计算采样率,这里设置目标宽高为800px,你可以根据需求调整
        int targetWidth = 800;
        int targetHeight = 800;
        int sampleSize = calculateSampleSize(options, targetWidth, targetHeight);

        // 开始加载图片到内存
        options.inJustDecodeBounds = false;
        options.inSampleSize = sampleSize;
        options.inPreferredConfig = Bitmap.Config.RGB_565; // 用RGB_565代替ARGB_8888,减少一半内存占用

        inputStream = getContentResolver().openInputStream(uri);
        Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);
        inputStream.close();
        return bitmap;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

// 计算合适的采样率,避免加载大图导致内存溢出
private int calculateSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    final int height = options.outHeight;
    final int width = options.outWidth;
    int sampleSize = 1;

    if (height > reqHeight || width > reqWidth) {
        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // 找到最大的采样率,使得采样后的图片尺寸不小于目标尺寸
        while ((halfHeight / sampleSize) >= reqHeight && (halfWidth / sampleSize) >= reqWidth) {
            sampleSize *= 2;
        }
    }
    return sampleSize;
}

关键要点说明

  • 裁剪结果获取:使用Crop.getOutput(result)直接获取裁剪后的图片Uri,这是该库提供的便捷方法,比自己从Intent中解析更可靠
  • 内存优化:通过BitmapFactory.Options先读取图片尺寸,计算采样率后再加载图片,同时使用RGB_565配置,有效避免大图导致的内存溢出(OOM)问题
  • 错误处理:不要忽略Crop.RESULT_ERROR的情况,这里可以捕获裁剪过程中的异常并提示用户
  • 存储选择:裁剪后的图片保存到应用缓存目录(getCacheDir()),不需要申请外部存储权限,更符合Android权限规范

内容的提问来源于stack exchange,提问作者BoboGoooool

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:40:28