I want to take pictures and load them into an imageview, so that I can switch through the pictures. The picture paths are saved in a database, which is refered to my Projects. So when I load pictures into a project and reopen the project, the pictures are still visible because they are stored in the database.
My problem is, that I always run into an OutOfMemoryException with only 3 pictures. I tried to reduce the inSampleSize to a low value continusoly. But even with a inSampleSize of 15, the maximum amount of pictures can be 3.
I measured the allocated size of the bitmaps with getAllocationByteCount( )
for the different inSampleSizes:
- 15980544 Byte = 15 MB (inSample 1) || 998784 Byte = 0.95 MB (inSample 4)
- 249696 Byte = 0.23 MB (inSample 15)||27744 Byte = 0.02 MB (insample 30)
Because of the pictures are rotated (90° anticlockwise) I rotate them with matrix.postRotate(90)
and with the matrix I create a new Bitmap. I delete the old bitmap with bitmap.recyle( )
. The size of the new bitmap is 499392 Byte = 0.47 MB
First I start a Camera 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++;
}
In this method I call the method createImageFile( )
in order to create an Imagefile:
// 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;
}
The picture will be shown in the onActivityResult( )
method:
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();
}
What shall I do to avoid the OutOfMemoryException in this case?