无法使用android相机拍摄两次
Posted
技术标签:
【中文标题】无法使用android相机拍摄两次【英文标题】:Cannot capture two times using android camera 【发布时间】:2016-02-07 03:22:54 【问题描述】:我跟随this 旋转捕获的图像。但我得到了错误。
我的代码
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)
if (requestCode == 1)
//h=0;
File f = new File(Environment.getExternalStorageDirectory().toString());
for (File temp : f.listFiles())
if (temp.getName().equals("temp.jpg"))
f = temp;
File photo = new File(Environment.getExternalStorageDirectory(), "temp.jpg");
//pic = photo;
break;
try
Bitmap bitmap;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inJustDecodeBounds = false;
bitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
bitmapOptions.inDither = true;
bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(), bitmapOptions);
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(f.getAbsolutePath(), opts);
ExifInterface exif = new ExifInterface(f.getAbsolutePath());
String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;
int rotationAngle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;
Matrix matrix = new Matrix();
matrix.setRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bitmapOptions.outWidth, bitmapOptions.outHeight, matrix, true);
Global.img = bitmap;
b.setImageBitmap(bitmap);
String path = android.os.Environment.getExternalStorageDirectory() + File.separator + "Phoenix" + File.separator + "default";
//p = path;
f.delete();
OutputStream outFile = null;
File file = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg");
try
outFile = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, outFile);
//pic=file;
outFile.flush();
outFile.close();
catch (FileNotFoundException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
catch (Exception e)
e.printStackTrace();
catch (Exception e)
e.printStackTrace();
else if (requestCode == 2)
Uri selectedImage = data.getData();
// h=1;
//imgui = selectedImage;
String[] filePath = MediaStore.Images.Media.DATA;
Cursor c = getContentResolver().query(selectedImage, filePath, null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
Bitmap thumbnail = (BitmapFactory.decodeFile(picturePath));
Log.w("path of image ******", picturePath + "");
b.setImageBitmap(thumbnail);
else
finish();
LogCat 错误
Process: com.example.project.project, PID: 13045
java.lang.OutOfMemoryError
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:928)
at android.graphics.Bitmap.createBitmap(Bitmap.java:901)
at android.graphics.Bitmap.createBitmap(Bitmap.java:833)
at com.example.project.project.ImageFitScreen.onActivityResult(ImageFitScreen.java:236)
at android.app.Activity.dispatchActivityResult(Activity.java:5643)
这是第 236 行
Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bitmapOptions.outWidth, bitmapOptions.outHeight, matrix, true);
我该如何解决这个问题?我从 SO 中找到了很多解决方案,但我仍然不知道如何解决它。有人可以帮我解决这个问题吗?任何帮助都会非常感谢!
【问题讨论】:
【参考方案1】:你应该让更少的bitmap
在memory
中。 Recycle bitmap
当你永远不需要它们时。setImageBitmap
是坏的。在文件系统中存储 bitmap
后,只需使用 glide
或 Universal-Image-Loader
加载它。
【讨论】:
【参考方案2】:我猜你的应用程序是内存密集型的,你的相机照片至少应该有 1280x720 的大小。我修改了您的代码以创建一个名为
的函数decodeBitmap
private Bitmap decodeBitmap(String filePath, int reqWidth, int reqHeight, int scale) throws IOException, Exception
if (scale > 3)
throw new Exception("scale size cannot be greater than 3");
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
bmOptions.inSampleSize = scale + Math.min(photoW / reqWidth, photoH / reqHeight);
bmOptions.inJustDecodeBounds = false;
try
Bitmap bm = BitmapFactory.decodeFile(filePath, bmOptions);
ExifInterface exif = new ExifInterface(filePath);
String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;
int rotationAngle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;
Matrix matrix = new Matrix();
matrix.setRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
return Bitmap.createBitmap(bm, 0, 0, photoW, photoH, matrix, true);
catch (OutOfMemoryError exception)
exception.printStackTrace();
return decodeBitmap(filePath, reqWidth, reqHeight, scale + 1);
onActivityResult
try
mImageView.setImageBitmap(decodeBitmap(mCurrentPhotoPath,1024,1024,0));
catch (Exception e)
e.printStackTrace();
让我警告您,此功能通过降低一些图像质量来工作。希望对你有帮助...
【讨论】:
如果我不旋转捕获的图像,它可以让我一次又一次地捕获而不会崩溃。添加旋转功能后,它只会崩溃。为什么会这样? 你可以在here看到我的原帖 在添加旋转代码后,您在内存中保存了 2 个 Bitmap 实例,并且单个相机图像超出了 android 的内存可以容纳的容量(尤其是分辨率更高的较新照片)。这就是为什么您的应用在添加轮换代码后崩溃的原因..【参考方案3】:尝试以这种方式拍摄最多 6 次相机图像。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
// if the result is capturing Image
// int count = 1, countsix = 6;
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE)
if (resultCode == this.RESULT_OK)
Log.e("in the On Activity Result", ":::: " + count);
if (count != countFix)
Log.e("in the From Camera if con ", "Count Increment :: "
+ count);
count++;
if (count == 1)
first = mediaFile.toString();
cameraAndGalaryPicture();
Log.e("in the Count ", "::: 1 " + first);
// getBitmapFromURL(first);
int targetW = 450;
int targetH = 800;
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(first, 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
// imgHome.setImageBitmap(bitmap);
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor << 1;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(first,
bmOptions);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] img1 = stream.toByteArray();
String timeStamp = new SimpleDateFormat(
"yyyyMMdd_HHmmss", Locale.getDefault())
.format(new Date());
Parseimagecam1 = new ParseFile("IMG_" + timeStamp
+ ".jpg", img1);
Parseimagecam1.saveInBackground();
parseFileCamera.add(0, Parseimagecam1);
image_Photo1.setImageBitmap(bitmap);
StorePath = first + "," + second + "," + thrid + ","
+ four + "," + five + "," + six;
else if (count == 2)
second = mediaFile.toString();
cameraAndGalaryPicture();
Log.e("in the Count ", "::: 2 " + second);
// getBitmapFromURL(second);
int targetW = 450;
int targetH = 800;
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(second, 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 << 1;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(second,
bmOptions);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] img2 = stream.toByteArray();
String timeStamp = new SimpleDateFormat(
"yyyyMMdd_HHmmss", Locale.getDefault())
.format(new Date());
Parseimagecam2 = new ParseFile("IMG_" + timeStamp
+ ".jpg", img2);
Parseimagecam2.saveInBackground();
parseFileCamera.add(1, Parseimagecam2);
Log.e("PARSE IMAGE CAMERA 2", ":::: : "
+ Parseimagecam2);
StorePath = first + "," + second + "," + thrid + ","
+ four + "," + five + "," + six;
else if (count == 3)
thrid = mediaFile.toString();
cameraAndGalaryPicture();
Log.e("in the Count ", "::: 3 " + thrid);
int targetW = 450;
int targetH = 800;
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(thrid, 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 << 1;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(thrid,
bmOptions);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] img3 = stream.toByteArray();
String timeStamp = new SimpleDateFormat(
"yyyyMMdd_HHmmss", Locale.getDefault())
.format(new Date());
Parseimagecam3 = new ParseFile("IMG_" + timeStamp
+ ".jpg", img3);
Parseimagecam3.saveInBackground();
// parseFileCamera.add(2, Parseimagecam3);
StorePath = first + "," + second + "," + thrid + ","
+ four + "," + five + "," + six;
else if (count == 4)
four = mediaFile.toString();
cameraAndGalaryPicture();
Log.e("in the Count ", "::: 4 " + four);
int targetW = 450;
int targetH = 800;
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(four, 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 << 1;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(four,
bmOptions);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] img4 = stream.toByteArray();
String timeStamp = new SimpleDateFormat(
"yyyyMMdd_HHmmss", Locale.getDefault())
.format(new Date());
Parseimagecam4 = new ParseFile("IMG_" + timeStamp
+ ".jpg", img4);
Parseimagecam4.saveInBackground();
// parseFileCamera.add(3, Parseimagecam4);
StorePath = first + "," + second + "," + thrid + ","
+ four + "," + five + "," + six;
else if (count == 5)
five = mediaFile.toString();
cameraAndGalaryPicture();
Log.e("in the Count ", "::: 5 " + five);
int targetW = 450;
int targetH = 800;
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(five, 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 << 1;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(five,
bmOptions);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] img5 = stream.toByteArray();
String timeStamp = new SimpleDateFormat(
"yyyyMMdd_HHmmss", Locale.getDefault())
.format(new Date());
Parseimagecam5 = new ParseFile("IMG_", img5);
// Parseimagecam5.saveInBackground();
parseFileCamera.add(4, Parseimagecam5);
StorePath = first + "," + second + "," + thrid + ","
+ four + "," + five + "," + six;
else if (count == 6)
six = mediaFile.toString();
// cameraAndGalaryPicture();
Log.e("in the Count ", "::: 6 " + six);
int targetW = 450;
int targetH = 800;
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(six, 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 << 1;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory
.decodeFile(six, bmOptions);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] img6 = stream.toByteArray();
String timeStamp = new SimpleDateFormat(
"yyyyMMdd_HHmmss", Locale.getDefault())
.format(new Date());
Parseimagecam6 = new ParseFile("IMG_" + timeStamp
+ ".jpg", img6);
Parseimagecam6.saveInBackground();
parseFileCamera.add(5, Parseimagecam6);
StorePath = first + "," + second + "," + thrid + ","
+ four + "," + five + "," + six;
Log.e("Store Path ", ":: : " + StorePath);
Log.e("parseFileCamera",
":: : Size " + parseFileCamera.toString());
Log.e("Boolean Value Chaeck", ":: : Tru or fls "
+ ImageCamera);
for (int i = 0; i < parseFileCamera.size(); i++)
ParseFile image = (ParseFile) parseFileCamera.get(i);
Log.e("in the for loop ", ":::: " + image.getUrl());
else
else if (resultCode == this.RESULT_CANCELED)
// user cancelled Image capture
Toast.makeText(getApplicationContext(),
"User cancelled image capture", Toast.LENGTH_SHORT)
.show();
else
// failed to capture image
Toast.makeText(getApplicationContext(),
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
cameraAndGalaryPicture() 这是打开相机捕获方法的方法。 countFix 这个变量为其 Fix 6。 parseFileCamera 这是解析数组。 Parseimagecam5 这是解析文件对象
我在解析数据库中使用它。 你也将使用字节数组其他明智的位图数组来存储更多图像。
【讨论】:
以上是关于无法使用android相机拍摄两次的主要内容,如果未能解决你的问题,请参考以下文章
无法创建支持android 4.0 及更高版本的surfaceview 相机应用。