我想拍照并将它们加载到 ImageView 中,以便我可以切换图片。图片路径保存在数据库中,引用我的项目。所以当我将图片加载到项目中并重新打开项目时,图片仍然可见,因为它们存储在数据库中。
我的问题是,我总是遇到只有 3 张图片的 OutOfMemoryException。我试图将 inSampleSize 连续减小到一个低值。但即使将 inSampleSize 设置为 15,图片的最大数量也可以是 3。
我使用 getAllocationByteCount( )
为不同的 inSampleSizes 测量了位图的分配大小:
- 15980544 字节 = 15 MB(示例 1)|| 998784 字节 = 0.95 MB(示例 4)
- 249696 字节 = 0.23 MB(样本 15)||27744 字节 = 0.02 MB(样本 30)
因为图片旋转了(逆时针旋转 90°),所以我使用 matrix.postRotate(90)
旋转它们,并使用矩阵创建一个新的位图。我用 bitmap.recyle( )
删除旧位图。新位图的大小为 499392 Byte = 0.47 MB
首先我启动一个相机 Intent :
// capturePicture( ) soll die Kamera starten und ein neues Bild soll gemacht werden können
private void capturePicture() {
// erstelle einen neuen Intent, damit sich die Kamera öffnet
// mit MediaStore.ACTION_IMAGE_CAPTURE wird angewiesen die Kamera zu starten
CameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Sicherstellen, dass auf dem Handy eine Kamera installiert ist
if (CameraIntent.resolveActivity(getPackageManager()) != null) {
photoFile = null;
try {
// rufe die Methode createImageFile( ) auf, damit die Aufnahme in eine Datei gespeichert werden kann
photoFile = createImageFile();
} catch (IOException ex) {
// wenn das Erstellen des Bildes fehlschlug
Toast.makeText(thisActivity,"Bilddatei konnte nicht erstellt werden",
Toast.LENGTH_LONG).show();
}
// wenn es eine Datei gibt, soll diese in der ImageView angezeigt werden
if (photoFile != null) {
CameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
// rufe die onActivityForResult( ) Methode mit einer ID auf, um das Bild in der ImageView anzeigen zu können
this.savePicture(photoFile.getAbsolutePath(), photoFile.getName());
startActivityForResult(CameraIntent, REQUEST_TAKE_PHOTO);
//bitmap.recycle();
//System.gc();
this.reloadPicDB();
}
} else {
// TODO: auf den Play Store mit einer Kamera App verweisen
Toast.makeText(thisActivity,"Sie haben leider keine Kamera installiert", Toast.LENGTH_SHORT).show();
}
photoCount++;
}
在这个方法中,我调用方法 createImageFile( )
来创建一个图像文件:
// erstellt eine Datei nachdem ein Foto gemacht wurde und gibt diese zurück
private File createImageFile() throws IOException {
// TODO: Sinnvollen Dateinamen für die Bilddateien geben
//String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmmss").format(new Date());
imageFileName = "JPEGNEU";
// TODO: überlegen, wohin die Bilddateien gespeichert werden sollen
//File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File pictureStorageDir = new File("/sdcard/neu/");
// In der Datei pictureImage werden der Name, Endung und Verzeichnis gespeichert
File pictureImage = File.createTempFile(imageFileName, /* prefix */
".jpg", /* suffix */
pictureStorageDir /* directory */
);
// ermittle den absoluten Pfad der Bilddatei und speichere diesen in den String PhotoPath
PhotoPath = pictureImage.getAbsolutePath();
// gebe die Bilddatei zurück, damit dieses in der Methode capturePicture weiter verwendet werden kann
return pictureImage;
}
图片会显示在onActivityResult( )
方法中:
if(requestCode == REQUEST_TAKE_PHOTO){
ImageView beispiel = (ImageView) findViewById(R.id.beispiel);
BitmapFactory.Options options1 = new BitmapFactory.Options();
options1.inSampleSize = 15; //1/12 des Bildes zu laden
options1.inPreferredConfig = Config.ARGB_4444;
Bitmap image = BitmapFactory.decodeFile(PhotoPath, options1);
Log.d("Speicherausgabe", "Speicherausgabe0.1 " + image.getAllocationByteCount());
Matrix matrix = new Matrix();
matrix.postRotate(90);
bitmap = Bitmap.createBitmap(image, 0, 0, image.getWidth() , image.getHeight(), matrix, true);
image.recycle();
System.gc();
if(zaehlerRequestPhoto == 0){
beispiel.setImageBitmap(bitmap);
} else {
beispiel.setImageBitmap(bitmap);
Log.d("Speicherausgabe", "Speicherausgabe3 " + bitmap.getAllocationByteCount());
//System.gc();
}
在这种情况下,我应该怎么做才能避免 OutOfMemoryException?
最佳答案
当您的应用程序资源超过可用堆内存时,通常会发生内存不足异常。特别是位图使用了更多的内存,并且在达到最大内存并且垃圾收集器开始工作之前它的缓存不会被清除。所以请使用 LruCache 来避免内存不足异常,或者简单地使用库 Universal Image Loader available 从这里。 <强> https://github.com/nostra13/Android-Universal-Image-Loader
关于android - 加载图片出现OutOfMemoryException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24487145/