我可以将从相机拍摄的图像保存到内部存储器中,但是我无法将其加载到仍为空的ImageView中。我已阅读所有相关建议但未找到合适的解决方案。请在下面找到相关代码,任何帮助都会受到很多赞赏,因为我几天都在努力...
清单权限:
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
XML上的ImageView:
<ImageView
android:id="@+id/recipeImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:background="@color/backgroundColorHomeBottomLayout"
android:padding="30dp" />
相关活动:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
if (resultCode == RESULT_OK) {
setPic();
//mImageView.setImageURI(fileUri);
}
else if (resultCode == RESULT_CANCELED) {
/** user cancelled Image capture */
Toast.makeText(this,
"User cancelled image capture", Toast.LENGTH_SHORT)
.show();
} else {
/** failed to capture image */
Toast.makeText(this,
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
}
}
/** Internal memory methods */
private void launchCameraIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
/** Ensure that there's a camera activity to handle the intent */
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
/** Create the File where the photo should go */
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"v3.com.mycookbook5.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
/** return a unique file name for a new photo using a date-time stamp */
private File createImageFile() throws IOException {
/** Create an image file name */
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
/** Save a file: path for use with ACTION_VIEW intents */
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
private void setPic() {
// Get the dimensions of the View
int targetW = mImageView.getWidth();
int targetH = mImageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
mImageView.setImageBitmap(bitmap);
}
日志:
07-03 12:56:07.188 3950-16091/? E/Drive.UninstallOperation: Package still installed v3.com.mycookbook5
07-03 12:56:35.350 19680-19680/v3.com.mycookbook5 E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: file:/storage/emulated/0/Android/data/v3.com.mycookbook5/files/Pictures/JPEG_20160703_125629_-664091716.jpg: open failed: ENOENT (No such file or directory)
07-03 12:56:35.350 19680-19680/v3.com.mycookbook5 E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: file:/storage/emulated/0/Android/data/v3.com.mycookbook5/files/Pictures/JPEG_20160703_125629_-664091716.jpg: open failed: ENOENT (No such file or directory)
答案 0 :(得分:1)
我相信你的问题是因为你没有给图像保存到SD卡所需的时间,因为代码在它完全保存之前就开始寻找它,所以你必须提供一个延迟的处理程序来制作确保图像保存成功,也可以使用以下方式获取图像路径:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
setPic();
}
}, 750);
并从sdcard获取图像:
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "image_name.jpg");
Bitmap bitmap = decodeSampledBitmapFromFile(file.getAbsolutePath(), 1000, 700);
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight)
{
/*
* here you set all of your bmOptions specs
*/
return BitmapFactory.decodeFile(path, bmOptions);
}
答案 1 :(得分:1)
问题解决了。为了帮助他人,以下是它应该如何执行:
将以下代码添加到launchCameraIntent()方法:
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
更改setPic方法如下:
Bitmap bitmap = BitmapFactory.decodeFile(photoFile.getPath());
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(rotatedBitmap, 200, 150 ,false);
mImageView.setImageBitmap(scaledBitmap);
答案 2 :(得分:0)
我想说你可能会得到一个零尺寸的图像,因为它试图将它调整为imageView大小(如果还没有呈现,可能是零大小)。
尝试在没有任何操作的情况下加载图像,并在成功之后 - 更改代码以减少内存消耗,但直到获得最佳结果。
祝你好运。答案 3 :(得分:0)
您意识到您必须从意图中提取额外数据吗? &#39; onActivityResult&#39;将使用结果代码和WITH EXTRA DATA(图像的位图)返回到您的活动,您应该将该数据(以您选择的任何方式)传递给setPic方法。
要获取位图照片,您可以使用下面的代码
if (requestCode == REQUEST_IMAGE_CAPTURE) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
}
答案 4 :(得分:0)
尝试使用marshmallow的代码
Uri imageFileUri = data.getData();
final Bitmap bitmap = getBitmapFromUri(imageFileUri);
private Bitmap getBitmapFromUri(Uri uri) throws IOException {
ParcelFileDescriptor parcelFileDescriptor =
getLocalContext().getContentResolver().openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
return image;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
if (resultCode == RESULT_OK) {
//mImageView.setImageURI(fileUri);
Uri imageFileUri = data.getData();
final Bitmap bitmap = getBitmapFromUri(imageFileUri);
setPic(bitmap);
}
else if (resultCode == RESULT_CANCELED) {
/** user cancelled Image capture */
Toast.makeText(this,
"User cancelled image capture", Toast.LENGTH_SHORT)
.show();
} else {
/** failed to capture image */
Toast.makeText(this,
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
}
}