自定义相机应用程序旋转到前视图,但不会返回到后视图

时间:2015-07-28 11:53:07

标签: java android android-studio camera

正如标题所说,这是我的问题。

我的相机成功进入前置摄像头,但点击第二个按钮后,它不会改变回到后视图并保持前视图。

CameraActivity.java:

package mano.whatever;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Picture;
import android.graphics.RectF;
import android.hardware.Camera;
import android.media.Image;
import android.net.Uri;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;
import android.os.AsyncTask;

import com.google.android.gms.identity.intents.AddressConstants;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


public class CameraActivity extends Activity {

    private Camera.Size mSize = null;
    private Camera mCamera = null;
    private CameraView mCameraView=null;
    private SurfaceView mPreview;
    private SurfaceHolder mSurfaceHolder;
    Camera.PictureCallback jpegCallback;
    final int CAMERA_CAPTURE = 1;
    private Camera.PictureCallback mPictureCallback;
    boolean isFront;
    int camBackId = Camera.CameraInfo.CAMERA_FACING_BACK;
    int camFrontId = Camera.CameraInfo.CAMERA_FACING_FRONT;


    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_camera);

        if (mCamera == null){
            initCamera(0);
        }

        //btn to close the application
        ImageView imgClose = (ImageView) findViewById(R.id.left_button);
        imgClose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                toThanksActivity();
            }
        });

       ImageView photo = (ImageView) findViewById(R.id.photo_button);
        photo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mCamera.autoFocus(new Camera.AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean b, Camera camera) {
                        mCamera.takePicture(shutterCall, PictureCallback, mPicture);

                    }
                });
            }
        });

       ImageView rotate = (ImageView) findViewById(R.id.rotate_camera);
        rotate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                rotateCamera();
            }
        });
    }


   public void rotateCamera() {
       boolean isFront = false;
       int CamId = 0;
       CamId = Camera.getNumberOfCameras();

       int cameraId = Camera.CameraInfo.CAMERA_FACING_BACK;

       Camera.CameraInfo currentCamInfo = new Camera.CameraInfo();


       if (mCamera != null) {
           mCamera.stopPreview();
           mCamera.release();
           mCamera = null;
       }

       if (currentCamInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK){
           initCamera(1);
       }
       else{
           initCamera(0);
       }


   }

    public void initCamera(int potato){

        mCamera = Camera.open(potato);//you can use open(int) to use different cameras

        FrameLayout camera_view = (FrameLayout) findViewById(R.id.camera_view);
        camera_view.removeView(mCameraView);

        if (mCamera != null) {
            mCameraView = new CameraView(this, mCamera);//create a SurfaceView to show camera data
            camera_view.addView(mCameraView);//add the SurfaceView to the layout
        }
    }

    public void toThanksActivity() {
        mCamera.stopPreview();
        mCamera.release();
        finish();
    }

    public void toCaptureImage() {
        mCamera.takePicture(shutterCall, PictureCallback, mPicture);
    }

    Camera.ShutterCallback shutterCall = new Camera.ShutterCallback() {
        @Override
        public void onShutter() {

        }
    };

    Camera.PictureCallback PictureCallback = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] bytes, Camera camera) {

        }
    };

    Camera.PictureCallback mPicture = new Camera.PictureCallback() {
        @Override
    public void onPictureTaken(byte[] data, Camera camera) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
            String date = dateFormat.format(new Date());
            String photoFile = "Picture_" + date + ".jpg";
            File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "Camera");
            String filename = mediaStorageDir.getPath() + File.separator + photoFile;
            File pictureFile = new File(filename);

            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.flush();
                fos.close();


                ByteArrayOutputStream stream = new ByteArrayOutputStream();

                Bitmap bm = BitmapFactory.decodeFile(filename);
                Matrix matrix = new Matrix();
                matrix.postRotate(90);
                Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
                FileOutputStream fos2 = new FileOutputStream(pictureFile);
                rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);

                byte[] byteArray = stream.toByteArray();




                mCamera.stopPreview();
                mCamera.release();

                Intent intent = new Intent();
                intent.putExtra("image", byteArray);
                setResult(250, intent);
                finish();

            } catch (IOException e) {
            }

        }
    };

    Camera.AutoFocusCallback myAutoFocusCallback = new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean b, Camera camera) {
        }
    };


}

CameraView.java:

package mano.whatever;

import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.IOException;
import java.util.List;



public class CameraView extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder mHolder;
    private Camera mCamera;
    private Camera.Size mSize = null;

    public CameraView(Context context, Camera camera) {
        super(context);


        mCamera = camera;
        mCamera.setDisplayOrientation(90);
        //get the holder and set this class as the callback, so we can get camera data here
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
            //when the surface is created, we can set the camera to draw images in this surfaceholder
            Camera.Parameters parameters = mCamera.getParameters();
            List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();

            // You need to choose the most appropriate previewSize for your app
           Size optimalSize = getOptimalPreviewSize(previewSizes, getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);

            parameters.setPreviewSize(optimalSize.width, optimalSize.height);
            mCamera.setParameters(parameters);
            mCamera.startPreview();

    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
        //before changing the application orientation, you need to stop the preview, rotate and then start it again
        if (mHolder.getSurface() == null)//check if the surface is ready to receive camera data
            return;

        try {
            mCamera.stopPreview();
        } catch (Exception e) {
            //this will happen when you are trying the camera if it's not running
        }

        //now, recreate the camera preview
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
        }

    }


    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        //our app has only one screen, so we'll destroy the camera in the surface
        //if you are unsing with more screens, please move this code your activity
    }


    private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio=(double)h / w;

        if (sizes == null) return null;

        Camera.Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        for (Camera.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);
            }
        }

        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Camera.Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }


}

我知道这是一个粗略的代码,但我很乐意听到一些建议。

提前谢谢。:)

修改

我完全重写了我的代码,摆脱了CameraView.java类,并且由于Android camera preview freezes when switching cameras?

它可以流畅地工作

1 个答案:

答案 0 :(得分:0)

没试过,但尝试这样的事情,希望它有效吗?

       public void rotateCamera() {
           boolean isFront = false;
           int CamId = 0;
           CamId = Camera.getNumberOfCameras();

           int cameraId = Camera.CameraInfo.CAMERA_FACING_BACK;

           Camera.CameraInfo currentCamInfo = new Camera.CameraInfo();
           if (mCamera != null) {
               mCamera.stopPreview();
               mCamera.release();
               mCamera = null;
           }

           if (currentCamInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK){
               camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
           }
           else{
               camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
           }
           if (mCamera != null) {
                try {
                    mCamera.setPreviewDisplay(surfaceView.getHolder());
                    mCamera.startPreview();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

       }