# Bild mit der Kamera abspeichern



## programmierer12 (12. Jul 2014)

Hallo zusammen,
seit einiger Zeit versuche ich ein Bild mit der Kamera zu machen und zu speichern und das innerhalb der App. Ich bin schon so weit, dass ein Vorschaubild angezeigt wird, doch wenn ich den Code um die Funktion erweitern will dass ich auch etwas speichern kann stürzt mir die app dauernd ab. Was kann man den da machen?

programmierer12


----------



## themrdomi (13. Jul 2014)

Poste doch mal den Code, dann kann man dir vielleicht helfen.


----------



## programmierer12 (13. Jul 2014)

Also erstmal meine CameraView :

```
import java.io.IOException;

import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraView extends SurfaceView implements SurfaceHolder.Callback {

	SurfaceHolder surfaceHolder;
	Camera camera;

	public CameraView(Context context, AttributeSet attrs) {
		super(context, attrs);
		surfaceHolder = getHolder();
		surfaceHolder.addCallback(this);
		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}

	public CameraView(Context context) {
		super(context);
		surfaceHolder = getHolder();
		surfaceHolder.addCallback(this);
		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}

	public void surfaceCreated(SurfaceHolder holder) {
		camera = Camera.open();
		camera.setDisplayOrientation(90);
		try {
			camera.setPreviewDisplay(holder);
		} catch (IOException exception) {
			camera.release();
			camera = null;
		}
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		camera.stopPreview();
		camera.release();
		camera = null;
	}

	public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
		try {
			Camera.Parameters parameters = camera.getParameters();
			parameters.setPreviewSize(w, h);
			camera.setParameters(parameters);
		} catch (Exception e) {
			Log.w("CameraView", "Exception: " , e);
		}
		camera.startPreview();
	}
	
	public void setOneShotPreviewCallback(PreviewCallback callback) {
		if(camera!=null) {
			camera.setOneShotPreviewCallback(callback);
		}
	}

}
```

Und dann noch die activityMain

```
package de.dietz.app.cleaner;

import java.io.File;
import java.io.IOException;

import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;


public class MainActivity extends ActionBarActivity implements OnClickListener, PreviewCallback{
	
	File fotofile;
	byte[] foto;
	CameraView camera;
	Button btn_fotospeichern;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn_cameraView = (Button) findViewById(R.id.btn_foto);
        btn_cameraView.setOnClickListener(this);
        
    }

	@Override
	public void onClick(View v) {
		
		setContentView(R.layout.activity_foto);
		camera = (CameraView) findViewById(R.id.cameraView);
		btn_fotospeichern = (Button) findViewById(R.id.btn_fotospeichern);
		btn_fotospeichern.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {

				oneShot();
							}
		});
		
	}
	
	//Extra Methode wegen this Parameter sonst Verweis auf OnClickListenr!
	public void oneShot(){
		
		camera.setOneShotPreviewCallback(this);
		
	}

	@Override
	public void onPreviewFrame(byte[] data, Camera camera) {

		
		
	}

}
```
Also soweit funktioniert das ganze ja noch doch wenn ich weiter machen will um das Bild zu speichern dann gibt es irgendwo ein Problem.
Es kann ja auch sein dass das abspeichern das Problem war.

MFG
programmierer12


----------



## programmierer12 (14. Jul 2014)

Wenn ich das jetzt richtig verstanden habe löst setOneShotPreviewCallback aus dass das Array data mit dem aktuellen Bild der Vorschau gefüllt wird? Also kann es nur am abspeichern liegen aber kann mir Mal jemand erklären wo und wie ich das machen soll in meinem Code? 

MFG 
programmierer12


----------



## programmierer12 (15. Jul 2014)

Kann mir denn keiner sagen ob ich mir das richtig gedacht habe und wie ich weiter machen muss?!

programmierer12


----------



## dzim (15. Jul 2014)

Schau mal, ob du hier fündig wirst:
http://www.java-forum.org/mobile-geraete/160983-geschossenes-foto-anderem-ordner-speichern.html
oder im dazugehörigen Follow-Up:
http://www.java-forum.org/mobile-ge...ilder-telefonspeicher-galeriedarstellung.html


----------



## programmierer12 (15. Jul 2014)

Diesen Thread habe ich mir schon durchgelesen.
Das Problem ist ja, dass ich das ganze NICHT von der Android-Kamera machen lassen will, sondern als view eingebaut in meiner App. Nun bin ich aber noch nicht sicher ob das mit dem 
	
	
	
	





```
setOneShotPreviewCallback
```
 so richtig ist und ob ich die Funktion dieser Methode richtig verstanden habe. Mein zweites Problem ist das abspeichern des Byte-Arrays als Bild (jpg oder png), wie könnte ich das denn manchen?

MFG
programmierer12


----------



## dzim (16. Jul 2014)

Da ich noch nichts mit dem SurfaceView gemacht hab, kann ich dir im Moment dazu nichts sagen.
Mit den Bilddaten kannst du dann folgendes machen:

```
public static byte[] getByteArray(Bitmap bitmap) {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		bitmap.compress(CompressFormat.JPEG, 50, bos);
		return bos.toByteArray();
	}
	
	public static Bitmap getBitmap(byte[] bitmap) {
		return BitmapFactory.decodeByteArray(bitmap, 0, bitmap.length);
	}
	
	public static Bitmap getBitmapFromFile(File file) {
		BitmapFactory.Options bmOptions = new BitmapFactory.Options();
		bmOptions.inJustDecodeBounds = false;
		bmOptions.inSampleSize = 8;
		bmOptions.inPurgeable = true;
		return BitmapFactory.decodeFile(file.getAbsolutePath(), bmOptions);
	}
```
Die zweite macht aus den Daten ein Bitmap, die erste komprimiert ein Bitmap. Du könntest es miteinander verbinden, denke ich.


----------



## programmierer12 (17. Jul 2014)

Ja das ist mir schon klar aber sobald ich aus meinem Array ein Bitmap erstelle ist dieses immer null woran kann das liegen.

MFG
programmierer12


----------



## dzim (17. Jul 2014)

Vielleicht, dass dein Byte-Array keine brauchbaren Daten enthält?


----------



## programmierer12 (17. Jul 2014)

Das kann sein aber woran soll das denn liegen wenn ich mein ByteArray direkt von der Kamera kriege?

MFG
programmierer12


----------



## dzim (17. Jul 2014)

"Das kann sein", klingt danach, als hättest du es noch nicht überprüft. Mach das bitte mal zuerst.


----------



## programmierer12 (18. Jul 2014)

Ich habe es noch nicht überprüft weil ich auch nicht weiß wie man überprüfen soll ob das Array ein richtiges Bild ist 

MFG
programmierer12


----------



## dzim (18. Jul 2014)

Du Debugst es. Wenn du Eclipse nutzt startest du es nicht oben über den Run-Knopf, sondern über den daneben - mit dem Käfer - dem Bug - drauf. Am besten dazu das ganze (was du sicher bereits machst) auf einem echten Gerät machen (schneller!). Damit du daraus etwas gewinnst, würdest du im Code-Editor wo du das Bilddaten-Byte-Array bekommst einen Breakpoint setzen, dann hält deine Anwendung an dieser Stelle an und du kannst überprüfen, was der Wert des Arrays ist.
Belies' dich dazu bitte kurz im Netz, denn das "wie debugge ich meine Android-Anwendung" würde jetzt den Rahmen sprengen. Erst recht, wenn du nicht Eclipse, sondern Android Studio verwendest (denn dann hätte ich eh keine Ahnung, wie es dort umgesetzt ist).


----------



## programmierer12 (18. Jul 2014)

Ich bin das ganze jetzt mal durchgegangen wie du das gesagt hast! In der Methode in der das Bitmap erstellt wird hat das Byte-Array noch einen Wert das Bitmap das erstellt wurde jedoch ist null!

MFG
programmierer12


----------



## dzim (18. Jul 2014)

Poste doch vielleicht mal deine Routine, mit der du aus dem Byte-Array das Bitmap erstellst, oder soll ich in meine Glasskugel schauen???


----------



## programmierer12 (18. Jul 2014)

```
public static Bitmap getBitmap(byte[] bitmap) {
    	Bitmap bmp = BitmapFactory.decodeByteArray(bitmap, 0, bitmap.length, new BitmapFactory.Options());
    	return bmp;
    }
```

Das ist die Methode mit der ich das mache.


----------



## dzim (18. Jul 2014)

lass mal die Options weg, ich weiss es zwar nicht, aber vielleicht musst du da irgendwas definieren und nicht nur einfach eine neue  Instanz übergeben.
Eventuell aber müssen die Daten auch noch erst irgendwie "formatiert" werden. Aber da ich bisher nur den CameraIntent verwendent habe, das Bild im Telefonspeicher landete und von mir hinterher wieder ausgelesen wurde, bin ich sonst am Ende meines Lateins.


----------



## dzim (18. Jul 2014)

eventuell musst du vorher noch einen call an *#setPreviewFormat(int)*:
Camera.PreviewCallback | Android Developers
via
Camera | Android Developers

#edit: ich denke du musst in den Options dann entsprechend angeben, welches Bildformat da angekommen ist!


----------



## programmierer12 (18. Jul 2014)

wo soll das format denn ankommen? und wie soll ich das format rauskriegen?


----------



## dzim (18. Jul 2014)

steht in einem der beiden Links drin, die ich dir geschickt hab


----------



## programmierer12 (18. Jul 2014)

Danke für den Hinweis aber ich finde trotzdem nichts. Und außerdem ist mein Anfängerenglisch nicht soo gut um das genau zu verstehen.


----------



## dzim (18. Jul 2014)

Also ich übersetz das jetzt nicht für dich... Wenn du ein Entwickler sein möchtest, wirst du dich zwangsläufig auch mit English auseinander setzen müssen!
Hier ( Camera.PreviewCallback | Android Developers ) wurde auf die *#setPreviewFormat(int)* verwiesen ( Camera.Parameters | Android Developers ). Du musst also in der Camera entsprechende Parameter (siehe den Klassen, mit gleichen Namen) übergeben. Dabei liefert dir die Methode *#getSupportedPreviewFormats()* die verfügbaren Codes, ( Camera.Parameters | Android Developers ).
Einge kurze(! eine Minute oder so!) Recherche führte mich zur ImageFormat-Klasse ( ImageFormat | Android Developers ).

Das alles heisst jetzt was? Wenn du deine Camera initialisierst, gibst du ihr am besten ein paar Parameter mit. Setzt dann zum Beispiel das Forma via

```
Camera c = ...;
Parameter param = c.getParameter(); // oder so ähnlich
param.setPreviewFormat(ImageFormat.JPEG);
c.setParameter(param);
```

Ob das dein Problem löst? Keine Ahnung, aber wie gesagt: Ich habe damit noch nichts gemacht und werde jetzt auch aufhören, mit dir Rätselraten zu spielen, oder für dich zu recherchieren.
Ich denke, da draussen wird es genügend Tutorials und Ideen (z.B. auf StackOverflow) geben und du wirst dich damit abfinden müssen, das English die sprache der Wahl bei der Entwicklung ist. Ok?


----------



## programmierer12 (18. Jul 2014)

Ja schon gut aber noch eine frage wo muss ich das jetzt machen in der Klasse meines CameraViews?


----------

