Bild mit der Kamera abspeichern

programmierer12

Bekanntes Mitglied
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
 
Zuletzt bearbeitet:
Also erstmal meine CameraView :
Java:
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
Java:
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
 
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
 
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
Code:
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
 
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:
Java:
	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.
 
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).
 
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
 
Poste doch vielleicht mal deine Routine, mit der du aus dem Byte-Array das Bitmap erstellst, oder soll ich in meine Glasskugel schauen???
 
Java:
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.
 
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.
 
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
Java:
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?
 

Neue Themen


Zurück
Oben