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

Android Studio调用相机获取Bitmap时出现画质丢失问题

问题原因

你通过result.getData().getExtras().get("data")获取的Bitmap是相机返回的缩略图,不是拍摄的完整分辨率原图,所以不管怎么调整压缩格式或质量,画质都无法提升——因为源数据本身就是低分辨率的。

解决方案

让相机直接将完整分辨率的原图保存到你指定的Uri,而非返回缩略图,之后从该Uri读取原图来生成哈希值。以下是具体实现步骤:

1. 配置文件提供者(适配Android 7+)

在AndroidManifest.xml中注册FileProvider,用于安全地共享文件Uri:

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

在res/xml目录下创建file_paths.xml,定义文件共享路径:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="camera_images" path="Pictures" />
</paths>

2. 创建临时文件Uri

编写方法生成临时文件的Uri,用于相机保存原图:

private Uri createTempImageUri() {
    File storageDir = getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    try {
        // 创建临时JPG文件
        File tempImage = File.createTempFile(
                "CAM_" + System.currentTimeMillis(),
                ".jpg",
                storageDir
        );
        // 通过FileProvider生成Uri
        return FileProvider.getUriForFile(
                getContext(),
                getContext().getPackageName() + ".fileprovider",
                tempImage
        );
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

3. 调整相机调用逻辑

修改Intent和回调,让相机保存原图到指定Uri,并读取原图处理:

// 生成临时Uri
Uri imageUri = createTempImageUri();
if (imageUri == null) {
    Toast.makeText(getContext(), "无法创建临时存储路径", Toast.LENGTH_SHORT).show();
    return;
}

// 构建相机Intent,指定输出Uri
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

// 启动相机
launcherForCamera.launch(cameraIntent);

// 注册结果回调
launcherForCamera = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        result -> {
            if (result.getResultCode() == RESULT_OK) {
                try {
                    // 方式1:读取完整分辨率Bitmap(如果需要Bitmap处理)
                    Bitmap originalBitmap = MediaStore.Images.Media.getBitmap(
                            getContext().getContentResolver(),
                            imageUri
                    );
                    // 在这里用originalBitmap生成哈希值

                    // 方式2:直接读取文件流(更节省内存,推荐用于生成哈希)
                    // InputStream imageStream = getContext().getContentResolver().openInputStream(imageUri);
                    // 用imageStream生成哈希值

                    // 生成哈希后删除临时文件(可选,因为存在应用私有目录,卸载会自动清除)
                    File tempFile = new File(getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES), imageUri.getLastPathSegment());
                    if (tempFile.exists()) {
                        tempFile.delete();
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                    Toast.makeText(getContext(), "读取原图失败", Toast.LENGTH_SHORT).show();
                }
            }
        }
);

4. 权限说明

  • Android 6.0+:需要动态申请CAMERA权限。
  • Android 10+:无需申请外部存储权限,因为临时文件存在应用私有目录,系统自动授权访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 20:13:10