使用相机拍照会生成一个看起来像 Android 10 上的缩略图的图像文件

Taking a photo with camera results in an image file that looks like a thumbnail on Android 10

提问人:DevAct 提问时间:1/29/2020 最后编辑:DevAct 更新时间:2/3/2020 访问量:71

问:

我有一个用 Java 编写的 Android 应用程序,它使用相机应用程序拍照,然后将其保存为文件。在 Android KitKat 和 Lollipop 上一切正常,但在 Android 10 (Q) 上,保存的文件看起来更像是缩略图而不是大尺寸图片。

为了拍照,我按照 Android 开发者网站的说明进行操作:https://developer.android.com/training/camera/photobasics

启动意图的代码:

private void captureImage() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    Uri uri;

    File photoFile = null;

    try {
        photoFile = createImageFile();
    } catch (IOException ex) {
        // Error occurred while creating the File
    }

    if (photoFile == null) {
        return;
    }

    uri = FileProvider.getUriForFile(this, this.getApplicationContext().getPackageName() + ".provider", photoFile);

    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        intent.addFlags(FLAG_GRANT_WRITE_URI_PERMISSION);
        intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
    } else {
        List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo resolveInfo : resInfoList) {
            String packageName = resolveInfo.activityInfo.packageName;
            grantUriPermission(packageName, uri, FLAG_GRANT_WRITE_URI_PERMISSION | FLAG_GRANT_READ_URI_PERMISSION);
        }
    }

    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, CAMERA_REQUEST_CODE);
    }
}

而我解码图像的代码如下:

public static Bitmap decodeSampledBitmapFromFile(String path, int imgWidth, int imgHeight) {

    Log.e("test image", "debut decodeSampledBitmapFromFile");
    //First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(path, options);

    // Calculate inSampleSize, Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    Log.e("test image", "imgHeight =" + imgHeight + ", imgWidth =" + imgWidth);
    Log.e("test image", "height =" + height + ", width =" + width);

    options.inPreferredConfig = Bitmap.Config.RGB_565;
    int inSampleSize = 1;

    if (height > imgHeight) {
        inSampleSize = Math.round((float) height / (float) imgHeight);
    }

    Log.e("test", "inSampleSize =" + inSampleSize);
    int expectedWidth = width / inSampleSize;
    Log.e("test", "expectedWidth =" + expectedWidth);
    if (expectedWidth > imgWidth) {
        //if(Math.round((float)width / (float)reqWidth) > inSampleSize) // If bigger SampSize..
        inSampleSize = Math.round((float) width / (float) imgWidth);
    }
    Log.e("test", "inSampleSize =" + inSampleSize);
    options.inSampleSize = inSampleSize;

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;

    Log.e("test image", "fin decodeSampledBitmapFromFile");

    return BitmapFactory.decodeFile(path, options);
}

那么调用上述方法的代码如下:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Résultat de la capture de la photo
    if (requestCode == CAMERA_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            Bitmap imageBitmap1 = null;
            // File file = new File(Environment.getExternalStorageDirectory() + File.separator + "image.jpg");
            File file = new File(currentPhotoPath);
            Matrix matrix = null;
            try {

                ExifInterface exif = new ExifInterface(file.getPath());
                int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
                int rotationInDegrees = exifToDegrees(rotation);
                matrix = new Matrix();
                if (rotation != 0f) {matrix.preRotate(rotationInDegrees);}
                if(rotationInDegrees == 90){
                    imageBitmap1 = Utils.decodeSampledBitmapFromFile(file.getAbsolutePath(), 500, 800);
                }else{
                    imageBitmap1 = Utils.decodeSampledBitmapFromFile(file.getAbsolutePath(), 800, 500);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            imageBitmap = Bitmap.createBitmap(imageBitmap1, 0, 0, imageBitmap1.getWidth(), imageBitmap1.getHeight(), matrix, true);

            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            imageBitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream);

            inputPhoto = stream.toByteArray();

KitKat 上的日志:imgHeight = 500,imgWidth = 800,height = 3264,width = 2448,inSampleSize = 7,expectedWidth = 349,inSampleSize = 7

Q 上的日志:imgHeight = 800,imgWidth = 500,height = 3376,width = 5984,inSampleSize = 4,expectedWidth = 1496,inSampleSize = 12

Android 图像 相机

评论

0赞 DevAct 1/30/2020
实际上,这段代码是由其他人编写的,我被要求维护它,但我是 Java 和 Android 的新手。我认为图像被解码以将其调整为更小的尺寸(500 x 800),但我不完全确定。是的,我可以开始打开相机并拍照的意图。
0赞 blackapps 1/30/2020
因此,您让相机将图片保存在文件中,然后调整该文件中的图像大小并再次保存。现在请说出图像的原始分辨率和最终分辨率。
0赞 DevAct 1/30/2020
我添加了这段代码来启动意图。
0赞 DevAct 1/31/2020
在 Android KitKat 上,原始图像尺寸为 2448 x 3264,并调整为 612 x 816,而在 Android Q 上,原始图像尺寸为 3376 x 5984,调整为 281 x 498,因此 decodeSampledBitmapFromFile 方法中一定存在错误。
0赞 blackapps 1/31/2020
inSampleSize 决定了图像的大小。根据文档,它以 2 的幂。那么 kitkat 和 q 的值是什么?比较它们。你记录了很多值。将这些值的计算记录放在您的帖子中。对于 kitkat,然后是 q。

答: 暂无答案