【问题标题】:Android display captured image from Camera in CircleImageViewAndroid 在 CircleImageView 中显示从相机捕获的图像
【发布时间】:2020-11-08 21:09:37
【问题描述】:

我在论坛中搜索了类似的问题,但没有找到我的代码的正确答案。 我有一个活动,用户可以选择(从对话框中)是从画廊上传照片还是用相机拍摄。我想在 CircularImageView 中显示用户选择的照片。我能够为从画廊中挑选的图像做到这一点,但不幸的是,如果我用相机拍摄它就不起作用。 这是CircularImageView的布局代码:

<de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/photo"
            android:layout_width="160dp"
            android:layout_height="160dp"
            android:layout_marginTop="20dp"
            android:layout_gravity="center"
            android:layout_centerInParent="true"
            android:src="@mipmap/add_profile_photo_round"
            app:civ_border_width="0dp"
            app:civ_border_color="#000000" />

这是Java代码:

TextView take_photo = (TextView) dialog.findViewById(R.id.take_photo);
...
take_photo.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.M)
            @Override
            public void onClick(View v) {
                takePhotoFromCamera();
                dialog.dismiss();
            }
        });
pick_gallery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                choosePhotoFromGallary();
                dialog.dismiss();
            }
        });

    }
    public void choosePhotoFromGallary() {
        Intent galleryIntent = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

        startActivityForResult(galleryIntent, GALLERY);
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    private void takePhotoFromCamera() {
        if (checkSelfPermission(Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.CAMERA},
                    MY_CAMERA_REQUEST_CODE);
        }
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == this.RESULT_CANCELED) {
            return;
        }
        if (requestCode == GALLERY) {
            if (data != null) {
                Uri contentURI = data.getData();
                try {
                    Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI);
                    image.setImageBitmap(bitmap);

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        } else if (requestCode == MY_CAMERA_REQUEST_CODE) {
            try {
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 8;

                final Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(),
                        options);

                image.setImageBitmap(bitmap);
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
        }
    }

正如我已经说过的,它适用于图库中的图像,但不适用于捕获的图像。 谢谢您的帮助 附言对不起,如果我的英语不好

编辑:我试图修改代码,但它仍然不起作用

else if (requestCode == MY_CAMERA_REQUEST_CODE) {
            try {
                ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(fileUri, "r");
                assert parcelFileDescriptor != null;
                FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
                Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
                parcelFileDescriptor.close();
                image.setImageBitmap(bitmap);
            } catch (NullPointerException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

第二次修改:我用过这段代码,但还是不行:

                ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(Objects.requireNonNull(data.getData()), "r");
                assert parcelFileDescriptor != null;
                FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
                Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
                parcelFileDescriptor.close();
                image.setImageBitmap(bitmap);
            } catch (NullPointerException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } 

【问题讨论】:

  • 你试过我的答案了吗?如果您这样做并且有效,请接受它。
  • 谢谢,我试过了,但它不起作用,我编辑了我的帖子以显示我正在使用的新代码,但它仍然不起作用。
  • 我已经编辑了我的答案。看看.. 你应该使用data.getData 而不是fileUri。我测试了它并且它正在工作。我在你编辑后编辑了我的答案。
  • 是的,我已经使用 data.getData() 而不是 fileUri 编辑了帖子,但它仍然无法正常工作...您对其进行了测试并且它正在工作...?可能我的代码中还有另一个错误
  • 现在我不在家,但是我运行它,我用相机拍照时什么都没有显示。稍后我会检查是否有错误,但我想我已经检查过并且没有。感谢您的帮助。

标签: java android image camera gallery


【解决方案1】:

fileUri.getPath() 不应该被使用,你不知道Uri 是否指向一个文件。将您的位图更改为以下内容

ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(data.getData(), "r"); 
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor); 
parcelFileDescriptor.close();
image.setImageBitmap(bitmap);

编辑:

我认为从长远来看,最好的解决方案是使用图像缓存库。原因是,您可能会遇到OutOfMemoryException,而且它会为您处理一切。我会推荐Picasso

首先实现它,将以下内容添加到您的应用级build.gradle

implementation 'com.squareup.picasso:picasso:2.71828'

然后将您的onActivityResult 更改为以下内容:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == this.RESULT_CANCELED) {
        return;
    }
    if (requestCode == GALLERY || requestCode == MY_CAMERA_REQUEST_CODE) {
        Picasso.get().load(data.getData()).fit().centerCrop()
            .placeholder(R.drawable.user_placeholder) // You can add a placeholder while the image loads
            .error(R.drawable.user_placeholder_error) // You can add an image for when there's an error loading image from Gallery
            .into(image);
    } 
}

【讨论】:

  • 如果您使用的是2.71828 版本,则不会发生这种情况。请尝试使缓存无效并重新启动,方法是转到File-Invalidate Caches / Restart。这应该可以解决它
  • 我试过了,但是如果我从图库上传图片会显示 R.drawable.user_placeholder_error,从相机拍照会显示 R.drawable.user_placeholder
【解决方案2】:

如果它对其他人有用,我找到了这段代码并且它有效:

Bitmap bmp = (Bitmap) data.getExtras().get("data");
            ByteArrayOutputStream stream = new ByteArrayOutputStream();

            bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
            byte[] byteArray = stream.toByteArray();

            // convert byte array to Bitmap

            Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0,
                    byteArray.length);
            encodedString = Base64.encodeToString(byteArray, 0);
            image.setImageBitmap(bitmap);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 2012-10-30
    • 2011-08-24
    • 2011-09-03
    • 2019-07-09
    相关资源
    最近更新 更多