Camera Preview Probleme...

DagobertDokate

DagobertDokate

Dauergast
137
Guten Abend,

Ich hab mir jetzt mal vorgenommen ein bisschen mit Android zu spielen.

Mein Ziel ist es erstmal die Anzahl der Gesichter aus einer Kamera Preview zu bekommen.

Meine Start-Activity sieht so aus:
Code:
package de.muehlensoft;
 
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.hardware.Camera;
import android.hardware.Camera.Face;
import android.hardware.Camera.FaceDetectionListener;
import android.os.Bundle;
 
public class FaceAppActivity extends Activity implements FaceDetectionListener{
 
    private FaceFragment infoFragment;
    private CameraFragment cameraFragment;
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        FragmentManager fm = getFragmentManager();
        cameraFragment = new CameraFragment();
        infoFragment = new FaceFragment();  
        
        FragmentTransaction ta = fm.beginTransaction();
        ta.add(R.id.camerafragment, cameraFragment);
        ta.add(R.id.infofragment, infoFragment);
        ta.commit();    
 
        
//       cameraFragment.setFaceDetectionListener(this);     <- Fehler, da camera noch null ist
    }
 
    public void onFaceDetection(Face[] faces, Camera camera) {
        infoFragment.setFaceCount(faces.length);
    }
}

Dann hab ich noch das CameraFragment und eine Camera Preview, die weitestgehend von google kommen:
Code:
package de.muehlensoft;
 
import android.app.Fragment;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.FaceDetectionListener;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
 
public class CameraFragment extends Fragment {
 
    private CameraPreview mPreview;
    Camera mCamera;
    int mNumberOfCameras;
    int mCurrentCamera; // Camera ID currently chosen
    int mCameraCurrentlyLocked; // Camera ID that's actually acquired
    
    // The first rear facing camera
    int mDefaultCameraId;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        // Create a container that will hold a SurfaceView for camera previews
        mPreview = new CameraPreview(this.getActivity());
        
        // Find the total number of cameras available
        mNumberOfCameras = Camera.getNumberOfCameras();
 
        // Find the ID of the rear-facing ("default") camera
        CameraInfo cameraInfo = new CameraInfo();
        for (int i = 0; i < mNumberOfCameras; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
                mCurrentCamera = mDefaultCameraId = i;
            }
        }
        setHasOptionsMenu(mNumberOfCameras > 1);
    }
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return mPreview;
    }
 
    @Override
    public void onResume() {
        super.onResume();
 
        // Use mCurrentCamera to select the camera desired to safely restore
        // the fragment after the camera has been changed
        mCamera = Camera.open(mCurrentCamera);
        mCameraCurrentlyLocked = mCurrentCamera;
        mPreview.setCamera(mCamera);
    }
 
    @Override
    public void onPause() {
        super.onPause();
 
        // Because the Camera object is a shared resource, it's very
        // important to release it when the activity is paused.
        if (mCamera != null) {
            mPreview.setCamera(null);
            mCamera.release();
            mCamera = null;
        }
    }
    
    public void setFaceDetectionListener(FaceDetectionListener l){
        mPreview.setFaceDetectionListener(l);
    }
}
Code:
package de.muehlensoft;
 
import java.io.IOException;
import java.util.List;
 
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.FaceDetectionListener;
import android.hardware.Camera.Size;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
 
    /**
     * A simple wrapper around a Camera and a SurfaceView that renders a centered
     * preview of the Camera to the surface. We need to center the SurfaceView
     * because not all devices have cameras that support preview sizes at the same
     * aspect ratio as the device's display.
     */
    public class CameraPreview extends SurfaceView  implements SurfaceHolder.Callback {
        private final String TAG = "Preview";
 
        SurfaceHolder mHolder;
        Size mPreviewSize;
        List<Size> mSupportedPreviewSizes;
        Camera mCamera;
        boolean mSurfaceCreated = false;
        
        private FaceDetectionListener mFaceListener;
 
        CameraPreview(Context context) {
            super(context);
 
            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
 
        public void setCamera(Camera camera) {
            mCamera = camera;
            if (mCamera != null) {
                mSupportedPreviewSizes = mCamera.getParameters()
                        .getSupportedPreviewSizes();
                if (mSurfaceCreated)
                    requestLayout();
            }
        }
 
        public void switchCamera(Camera camera) {
            setCamera(camera);
            try {
                camera.setPreviewDisplay(mHolder);
            } catch (IOException exception) {
                Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
            }
        }
 
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // We purposely disregard child measurements because act as a
            // wrapper to a SurfaceView that centers the camera preview instead
            // of stretching it.
            final int width = resolveSize(getSuggestedMinimumWidth(),
                    widthMeasureSpec);
            final int height = resolveSize(getSuggestedMinimumHeight(),
                    heightMeasureSpec);
            setMeasuredDimension(width, height);
 
            if (mSupportedPreviewSizes != null) {
                mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width,
                        height);
            }
 
            if (mCamera != null) {
                Camera.Parameters parameters = mCamera.getParameters();
                parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
 
                mCamera.setParameters(parameters);
            }
        }
 
        public void surfaceCreated(SurfaceHolder holder) {
            // The Surface has been created, acquire the camera and tell it where
            // to draw.
            try {
                if (mCamera != null) {
                    mCamera.setPreviewDisplay(holder);
                    if(mFaceListener != null)
                        mCamera.setFaceDetectionListener(mFaceListener);
                }
            } catch (IOException exception) {
                Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
            }
            if (mPreviewSize == null)
                requestLayout();
            mSurfaceCreated = true;
        }
 
        public void surfaceDestroyed(SurfaceHolder holder) {
            // Surface will be destroyed when we return, so stop the preview.
            if (mCamera != null) {
                mCamera.stopPreview();
            }
        }
 
        private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
            final double ASPECT_TOLERANCE = 0.1;
            double targetRatio = (double) w / h;
            if (sizes == null)
                return null;
 
            Size optimalSize = null;
            double minDiff = Double.MAX_VALUE;
 
            int targetHeight = h;
 
            // Try to find an size match aspect ratio and size
            for (Size size : sizes) {
                double ratio = (double) size.width / size.height;
                if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                    continue;
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
 
            // Cannot find the one match the aspect ratio, ignore the requirement
            if (optimalSize == null) {
                minDiff = Double.MAX_VALUE;
                for (Size size : sizes) {
                    if (Math.abs(size.height - targetHeight) < minDiff) {
                        optimalSize = size;
                        minDiff = Math.abs(size.height - targetHeight);
                    }
                }
            }
            return optimalSize;
        }
 
        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            // Now that the size is known, set up the camera parameters and begin
            // the preview.
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
            requestLayout();
 
            mCamera.setParameters(parameters);
            mCamera.startPreview();
            if(mFaceListener != null)
                mCamera.setFaceDetectionListener(mFaceListener);
        }
        
        public void setFaceDetectionListener(FaceDetectionListener l){
            mFaceListener = l;
            if(mCamera != null){
                mCamera.setFaceDetectionListener(mFaceListener);
            }
        }
}

Jetzt ist meine Frage, wann (und wo überall) muss ich den FaceDetectionListener regestrieren?
Desweiteren bleibt die Preview hängen, wenn ich das Display aus machen und wieder an mache, also es wird nicht weiter das Camera Bild gezeigt wird. Was ist da noch falsch?

mfg. Dagobert
 

Ähnliche Themen

S
Antworten
4
Aufrufe
954
Sempervivum
S
R
Antworten
3
Aufrufe
1.571
Ritartet
R
B
Antworten
6
Aufrufe
1.016
jogimuc
J
Zurück
Oben Unten