Android 在 CircleImageView 中显示从相机捕获的图像
Android display captured image from Camera in CircleImageView
我在论坛中搜索了类似的问题,但没有找到适合我的代码的正确答案。
我有一个 activity,用户可以在其中选择(从对话框中)是从图库上传照片还是用相机拍摄。我想在 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();
}
}
}
正如我已经说过的,它适用于图库中的图像,但不适用于捕获的图像。
谢谢您的帮助
P.S。对不起,如果我的英语不好
编辑:我尝试修改代码,但还是不行
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();
}
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);
}
}
如果它对其他人有用,我找到了这段代码并且它有效:
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);
我在论坛中搜索了类似的问题,但没有找到适合我的代码的正确答案。 我有一个 activity,用户可以在其中选择(从对话框中)是从图库上传照片还是用相机拍摄。我想在 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();
}
}
}
正如我已经说过的,它适用于图库中的图像,但不适用于捕获的图像。 谢谢您的帮助 P.S。对不起,如果我的英语不好
编辑:我尝试修改代码,但还是不行
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();
}
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);
}
}
如果它对其他人有用,我找到了这段代码并且它有效:
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);