Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
297 views
in Technique[技术] by (71.8m points)

android - Camera preview is in portrait mode but image captured is rotated

I am trying to capture a photo using the camera. The preview by default was in landscape mode which i could change it to portrait mode using

    setCameraDisplayOrientation(this,1,  mCamera);
    public static void setCameraDisplayOrientation(Activity activity,
         int cameraId, android.hardware.Camera camera) {
     android.hardware.Camera.CameraInfo info =
             new android.hardware.Camera.CameraInfo();
     android.hardware.Camera.getCameraInfo(cameraId, info);
     int rotation = activity.getWindowManager().getDefaultDisplay()
             .getRotation();
     int degrees = 0;
     switch (rotation) {
         case Surface.ROTATION_0: degrees = 0; break;
         case Surface.ROTATION_90: degrees = 90; break;
         case Surface.ROTATION_180: degrees = 180; break;
         case Surface.ROTATION_270: degrees = 270; break;
     }

     int result;
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
         result = (info.orientation + degrees) % 360;
         result = (360 - result) % 360;  // compensate the mirror
     } else {  // back-facing
         result = (info.orientation - degrees + 360) % 360;
     }
     camera.setDisplayOrientation(result);
 }

The image captured is stored under a folder myImages. But the images is rotated. (look's like the image is captured in landscape mode)

So how can i rotate the image captured and save the same?

public class MainActivity extends Activity {

private static final int REQUEST_CODE = 1; 
ImageView imageView;
Button b;
private Camera mCamera;
private CameraPreview mPreview;
private Bitmap bitmap;
private PictureCallback mPicture;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    boolean check =checkCameraHardware(MainActivity.this);
    if(check)
    {
         mCamera = getCameraInstance();

        // mCamera.setDisplayOrientation(90);
         setCameraDisplayOrientation(this,
                 1,  mCamera);//requires min sdk 9
    }
    // Create an instance of Camera
    mPicture = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            File imagesFolder = new File(Environment.getExternalStorageDirectory(), "MyImages");
            if(!imagesFolder.exists())
            imagesFolder.mkdirs();   
            File pictureFile = new File(imagesFolder, "image.jpg");

            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);

                System.out.println("hello");
                fos.write(data);
                fos.close();
            } catch (FileNotFoundException e) {
                Log.d("No File", "File not found: " + e.getMessage());
            } catch (IOException e) {
                //Log.d(TAG, "Error accessing file: " + e.getMessage());
            }
        }
    };

    // Create our Preview view and set it as the content of our activity.
    mPreview = new CameraPreview(this, mCamera);
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
    preview.addView(mPreview);
     b = (Button) findViewById(R.id.button_capture);
     b.setOnClickListener(new OnClickListener()
      {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
                 mCamera.takePicture(null, null, mPicture);
                 Toast.makeText(MainActivity.this, "Called",1000).show();

        }

      });
  }
 public static void setCameraDisplayOrientation(Activity activity,
         int cameraId, android.hardware.Camera camera) {
     android.hardware.Camera.CameraInfo info =
             new android.hardware.Camera.CameraInfo();
     android.hardware.Camera.getCameraInfo(cameraId, info);
     int rotation = activity.getWindowManager().getDefaultDisplay()
             .getRotation();
     int degrees = 0;
     switch (rotation) {
         case Surface.ROTATION_0: degrees = 0; break;
         case Surface.ROTATION_90: degrees = 90; break;
         case Surface.ROTATION_180: degrees = 180; break;
         case Surface.ROTATION_270: degrees = 270; break;
     }

     int result;
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
         result = (info.orientation + degrees) % 360;
         result = (360 - result) % 360;  // compensate the mirror
     } else {  // back-facing
         result = (info.orientation - degrees + 360) % 360;
     }
     camera.setDisplayOrientation(result);
 }
private boolean checkCameraHardware(Context context) {
    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
        // this device has a camera
         Toast.makeText(this, "Phone has camera", Toast.LENGTH_LONG).show();
        return true;
    } else {
        // no camera on this device
         Toast.makeText(this, "Phone has no camera", Toast.LENGTH_LONG).show();
        return false;
    }
}
public static Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
    }
    return c; // returns null if camera is unavailable
}


@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    mCamera.release();
}
  }

The CameraPreview class is the same from the developer site http://developer.android.com/guide/topics/media/camera.html

Note: I am using the back camera not the front facing camera.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I faced the same problem when taking photo from camera in portrait mode. Below lines of code solved my problem:

public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) {
    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
    int degrees = 0;
    switch (rotation) {
    case Surface.ROTATION_0:
            degrees = 0;
            break;
    case Surface.ROTATION_90:
            degrees = 90;
            break;
    case Surface.ROTATION_180:
            degrees = 180;
            break;
    case Surface.ROTATION_270:
            degrees = 270;
            break;
    }

    int result;
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360; // compensate the mirror
    } else { // back-facing
            result = (info.orientation - degrees + 360) % 360;
    }
    camera.setDisplayOrientation(result);
}

Call setCameraDisplayOrientation() method in surfaceCreated callback as the following:

@Override
public void surfaceCreated(SurfaceHolder holder) {
    camera = Camera.open();
    setCameraDisplayOrientation(getActivity(), CameraInfo.CAMERA_FACING_BACK, camera);
}

I had to rotate the image in Camera onPictureTaken() callback:

camera.takePicture(null, null, new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            if (data != null) {
                int screenWidth = getResources().getDisplayMetrics().widthPixels;
                int screenHeight = getResources().getDisplayMetrics().heightPixels;
                Bitmap bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);

                if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                    // Notice that width and height are reversed
                    Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true);
                    int w = scaled.getWidth();
                    int h = scaled.getHeight();
                    // Setting post rotate to 90
                    Matrix mtx = new Matrix();
                    mtx.postRotate(90);
                    // Rotating Bitmap
                    bm = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true);
                }else{// LANDSCAPE MODE
                    //No need to reverse width and height
                    Bitmap scaled = Bitmap.createScaledBitmap(bm, screenWidth,screenHeight , true);
                    bm=scaled;
                }
                photoPreview.setImageBitmap(bm);
            }
            isImageCaptured = true;
            photoPreview.setVisibility(View.VISIBLE);
            surfaceView.setVisibility(View.GONE);
        }
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...