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

Android相机拍照返回低质量图片,如何获取高清原图?

解决拍照获取高清原图的方案

这个问题我之前踩过坑!用data.getExtras().get("data")确实只能拿到缩略图——系统为了性能优化,默认只会返回小尺寸预览图,想要高清原图,核心是让相机直接把原图保存到你指定的路径,而不是依赖Intent返回的缩略图。下面是适配大部分Android版本的完整解决方案:

1. 先准备原图的存储路径

首先要创建一个安全的文件路径来存放拍照后的原图,推荐用公共图片目录或应用私有目录,这里以公共目录为例(注意权限适配):

// 获取系统公共图片目录
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
// 创建自定义子目录,方便区分你的App图片
File appCameraDir = new File(storageDir, "MyCameraAlbum");
if (!appCameraDir.exists()) {
    appCameraDir.mkdirs();
}
// 生成唯一文件名,避免重复
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
// 创建临时文件
File imageFile = null;
try {
    imageFile = File.createTempFile(imageFileName, ".jpg", appCameraDir);
} catch (IOException e) {
    e.printStackTrace();
}
// 保存文件路径和Uri,后续要用到(建议把这两个变量设为Fragment的成员变量)
String photoAbsolutePath = imageFile.getAbsolutePath();
// Android7.0及以上必须用FileProvider获取Uri,避免FileUriExposedException
Uri photoUri = FileProvider.getUriForFile(getContext(), "com.your.package.name.fileprovider", imageFile);

注意:Android7.0+需要配置FileProvider,步骤见文末注意事项。

2. 修改拍照Intent,指定原图保存位置

把原来的拍照Intent修改为指定MediaStore.EXTRA_OUTPUT,告诉相机把原图直接存到我们刚才创建的Uri:

img22a1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // 先检查有没有相机App能处理这个Intent
        if (takePhotoIntent.resolveActivity(getContext().getPackageManager()) != null) {
            // 传入我们准备好的Uri,让相机把原图存在这里
            takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
            startActivityForResult(takePhotoIntent, CAMERA_01);
        }
    }
});

3. 在onActivityResult中读取原图

现在data.getExtras()不会返回图片数据了,我们直接从之前保存的文件路径读取高清原图:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == CAMERA_01) {
        if (resultCode == Activity.RESULT_OK) {
            // 从指定路径读取原图Bitmap
            Bitmap originalBitmap = BitmapFactory.decodeFile(photoAbsolutePath);
            
            // 这里继续你原来的Base64转换和全局变量存储逻辑
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            originalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, output);
            byte[] byte_arr = output.toByteArray();
            ((SiteProgress) getActivity().getApplication()).seti22a1(Base64.encodeToString(byte_arr, Base64.DEFAULT));
            
            // 更新ImageView显示原图
            BitmapDrawable ob = new BitmapDrawable(getResources(), originalBitmap);
            img22a1.setBackgroundDrawable(ob);
        } else if (resultCode == Activity.RESULT_CANCELED) {
            // 用户取消拍照的处理逻辑
        }
    }
}

4. 优化保存到相册的代码

原来的保存方式在高版本Android可能出现权限问题,推荐用MediaStore插入图片,确保系统相册能正确识别:

// 假设你已经有decodedString(Base64解码后的字节数组)和namefile(文件名数组)
for(int i=0; i < namefile.length; i++){
    Bitmap bitmap = BitmapFactory.decodeByteArray(decodedString[i], 0, decodedString[i].length);
    
    // 用MediaStore插入图片到系统相册
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.DISPLAY_NAME, namefile[i].getName());
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
    // Android10及以上需要设置RELATIVE_PATH,无需WRITE_EXTERNAL_STORAGE权限
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/MyCameraAlbum");
    } else {
        values.put(MediaStore.Images.Media.DATA, namefile[i].getAbsolutePath());
    }
    
    ContentResolver resolver = getActivity().getContentResolver();
    Uri insertUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    if (insertUri != null) {
        try (OutputStream outputStream = resolver.openOutputStream(insertUri)) {
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

关键注意事项

  • 权限处理:
    • Android6.0+需要动态申请CAMERA权限;Android10以下还需要WRITE_EXTERNAL_STORAGE权限。
    • Android10及以上使用MediaStore插入图片无需WRITE_EXTERNAL_STORAGE权限。
  • FileProvider配置:
    在AndroidManifest.xml中添加Provider配置:
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="com.your.package.name.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-path name="public_images" path="Pictures" />
    </paths>
    
  • 避免内存溢出:如果原图尺寸很大,直接解码可能导致OOM,建议用BitmapFactory.Options做采样压缩:
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 2; // 宽高都缩为原来的1/2,根据需求调整
    Bitmap compressedBitmap = BitmapFactory.decodeFile(photoAbsolutePath, options);
    

这样修改后,你就能获取到高清的原图,保存到相册的图片质量也会恢复正常啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:03:34