Zoom In & Out Custom Camera - Null Pointer Excepti

2019-02-19 04:50发布

问题:

I am trying to Implement Zoom In & Out functionality in my Custom Camera.

    NullPointerException: zoomControls.setVisibility(View.GONE);

I am using this : Zoom Control in Camera is not working in Android

PreviewSurface.java:-

 public class PreviewSurface extends SurfaceView implements
    SurfaceHolder.Callback {

        public static final String LOG_TAG = "CameraPreview";
        private SurfaceHolder mSurfaceHolder;
        SurfaceView mSurfaceView;
        private Camera mCamera;
        Camera.Parameters params ;
        int currentZoomLevel = 0, maxZoomLevel = 0;
        // Constructor that obtains context and camera
        @SuppressWarnings("deprecation")
        public PreviewSurface(Context context, Camera camera) {
            super(context);
            this.mCamera = camera;
            mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
            this.mSurfaceHolder = this.getHolder();
            this.mSurfaceHolder.addCallback(this);
            this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            this.mSurfaceHolder.setFixedSize(100, 100);
        }

        @Override
        public void surfaceCreated(SurfaceHolder surfaceHolder) {
            try {
                mCamera.setPreviewDisplay(surfaceHolder);
                mCamera.startPreview();
            } catch (IOException e) {
                // left blank for now
            }
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
            mCamera.stopPreview();
            mCamera.release();
        }

        @Override
        public void surfaceChanged(SurfaceHolder surfaceHolder, int format,
                int width, int height) {

            ZoomControls zoomControls = (ZoomControls) findViewById(R.id.CAMERA_ZOOM_CONTROLS);
            params = mCamera.getParameters();


                if (params.isZoomSupported() && params.isSmoothZoomSupported()) {
                    //most phones
                    maxZoomLevel = params.getMaxZoom();

                    zoomControls.setIsZoomInEnabled(true);
                    zoomControls.setIsZoomOutEnabled(true);

                    zoomControls.setOnZoomInClickListener(new OnClickListener() {
                        public void onClick(View v) {
                            if (currentZoomLevel < maxZoomLevel) {
                                currentZoomLevel++;
                                mCamera.startSmoothZoom(currentZoomLevel);

                            }
                        }
                    });

                    zoomControls.setOnZoomOutClickListener(new OnClickListener() {
                        public void onClick(View v) {
                            if (currentZoomLevel > 0) {
                                currentZoomLevel--;
                                mCamera.startSmoothZoom(currentZoomLevel);
                            }
                        }
                    });
                } else if (params.isZoomSupported() && !params.isSmoothZoomSupported()){
                    //stupid HTC phones
                    maxZoomLevel = params.getMaxZoom();

                    zoomControls.setIsZoomInEnabled(true);
                    zoomControls.setIsZoomOutEnabled(true);

                    zoomControls.setOnZoomInClickListener(new OnClickListener() {
                        public void onClick(View v) {
                            if (currentZoomLevel < maxZoomLevel) {
                                currentZoomLevel++;
                                params.setZoom(currentZoomLevel);
                                mCamera.setParameters(params);

                            }
                        }
                    });

                    zoomControls.setOnZoomOutClickListener(new OnClickListener() {
                        public void onClick(View v) {
                            if (currentZoomLevel > 0) {
                                currentZoomLevel--;
                                params.setZoom(currentZoomLevel);
                                mCamera.setParameters(params);
                            }
                        }
                    });
                }else{
                    //no zoom on phone
                    zoomControls.setVisibility(View.GONE);
                }

                // start preview with new settings
                try {
                    mCamera.setDisplayOrientation(90);
                    mCamera.setPreviewDisplay(surfaceHolder);
                    mCamera.startPreview();
                } catch (Exception e) {
                // intentionally left blank for a test
            }
        }

    }

activity_camera.xml:-

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

<FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_toLeftOf="@+id/btnView" />

<SurfaceView
    android:id="@+id/surfaceView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<ZoomControls
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@+id/camera_preview"
    android:layout_centerInParent="true"
    android:id="@+id/CAMERA_ZOOM_CONTROLS" />

<TextView
    android:id="@+id/title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_marginTop="18dp"
    android:layout_toRightOf="@+id/camera_preview"
    android:maxLines="1"
    android:visibility="gone"
    android:textAppearance="?android:attr/textAppearanceSmall" />

<Button
    android:id="@+id/btnSettings"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/btnView"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="50dp"
    android:background="@drawable/settings" />

<Button
    android:id="@+id/btnView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:layout_marginTop="50dp"
    android:background="@drawable/gallery" />

<Button
    android:id="@+id/btnCapture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_toRightOf="@+id/camera_preview"
    android:background="@drawable/capture" />

</RelativeLayout>

CameraLauncherActivity.java:-

  public class CameraLauncherActivity extends Activity  {

    private Camera mCamera;
    private PreviewSurface mCameraPreview;
    @Override
    public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_camera);
         mCamera = getCameraInstance();

         mCameraPreview = new PreviewSurface(this, mCamera);
         FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
         preview.addView(mCameraPreview);
    }

private Camera getCameraInstance() {
        Camera camera = null;
        Log.d(CameraLauncherActivity.LOG_TAG, "getCameraInstance()Camera:: " + camera);
        try {
            camera = Camera.open(0);
            Log.d(CameraLauncherActivity.LOG_TAG, "getCameraInstance()open:: " + camera);
        } catch (Exception e) {
            // cannot get camera or does not exist
        }
        return camera;
    }

    PictureCallback mPicture = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            File pictureFile = getOutputMediaFile();
            camera.startPreview();
            if (pictureFile == null) {
                return;
            }
            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();
            } catch (FileNotFoundException e) {

            } catch (IOException e) {
            }
        }
    };

    static File getOutputMediaFile() {

   // folder name
    mediaStorageDir = new File(Environment                               .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "/MyImages/");

 if (!mediaStorageDir.exists()) {
     if (!mediaStorageDir.mkdirs()) {
    Log.d("App", "failed to create directory");                  
      }
    }

    /* yyyy-MM-dd'T'HH:mm:ss.SSSZ */
     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

     File mediaFile;

     // file name
    mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");

        return mediaFile;
    }

Logcat:-

11-28 01:52:43.179: E/AndroidRuntime(2135): FATAL EXCEPTION: main
11-28 01:52:43.179: E/AndroidRuntime(2135): java.lang.NullPointerException
11-28 01:52:43.179: E/AndroidRuntime(2135):     at app.pd.PreviewSurface.surfaceChanged(PreviewSurface.java:113)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.view.SurfaceView.updateWindow(SurfaceView.java:582)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.view.SurfaceView.access$000(SurfaceView.java:86)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:175)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:833)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1860)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.view.Choreographer.doCallbacks(Choreographer.java:562)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.view.Choreographer.doFrame(Choreographer.java:532)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.os.Handler.handleCallback(Handler.java:730)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.os.Handler.dispatchMessage(Handler.java:92)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.os.Looper.loop(Looper.java:137)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at android.app.ActivityThread.main(ActivityThread.java:5103)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at java.lang.reflect.Method.invokeNative(Native Method)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at java.lang.reflect.Method.invoke(Method.java:525)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-28 01:52:43.179: E/AndroidRuntime(2135):     at dalvik.system.NativeStart.main(Native Method)

回答1:

In your code, params isn't ever initialized, thus its value is always null. This will result in a NullPointerException if you try to use a method on the null object. Perhaps in your constructor you should initialize it with the following:

params = mCamera.getParameters();


回答2:

try this code :

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub 

        switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
            mode = NONE;
            Log.d(TAG, "mode=NONE");
            break;
        case MotionEvent.ACTION_MOVE:
            if (mode == ZOOM) {
                    float newDist = spacing(event);

                    double zoomDist = newDist-oldDist;

                    if(zoomDist > 0){
                        if(zoomDist > 50 && zoomDist <= 200){

                            if (curZoomLevel < mZoomMax && gestureZoom == 0) {
                                gestureZoom ++;
                                GestureZoomIn();
                            }

                        }else if(zoomDist > 200 && zoomDist <= 300){


                            if (curZoomLevel < mZoomMax && gestureZoom == 1) {

                                gestureZoom ++;
                                GestureZoomIn();
                            }
                        }else if(zoomDist > 300 && zoomDist <= 400){

                            if (curZoomLevel < mZoomMax && gestureZoom == 2) {

                                gestureZoom++;
                                GestureZoomIn();
                            }
            break;
        }

        view.setImageMatrix(matrix);
        return true;
    }


 private void GestureZoomIn(){
       if (mParameters.isZoomSupported()){
            mZoomMax = mParameters.getMaxZoom();
            if (zoom_text_value<mZoomMax) {
                zoom_text_value++;
                curZoomLevel++;
                zoom_float=zoom_float+0.5;
                onZoomValueChanged(curZoomLevel);

private void GestureZoomOut(){
       if (mParameters.isZoomSupported()){

            if (0<zoom_text_value) {
                zoom_text_value--;
                curZoomLevel--;
                zoom_float=zoom_float-0.5;
                onZoomValueChanged(curZoomLevel);

this might be help you.