1. Nimm jetzt an unserem 2. ADVENT-Gewinnspiel teil - Alle Informationen findest Du hier!

Camera Preview Probleme...

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von DagobertDokate, 06.06.2012.

  1. DagobertDokate, 06.06.2012 #1
    DagobertDokate

    DagobertDokate Threadstarter Android-Lexikon

    Beiträge:
    1,095
    Erhaltene Danke:
    92
    Registriert seit:
    01.07.2010
    Phone:
    Samsung Galaxy Note 4
    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
     

Diese Seite empfehlen