Camera Orientation Issue in Android

Android how to fix camera orientation

I found the solution here. Answer by @Ed Jellard.

i just have to add camera.setDisplayOrientation(90); on surfaceCreated(SurfaceHolder holder) method, now the display is on the right angle.

see the happy T-REX :)

Camera orientation issue in Android

There are quite a few similar topics and issues around here. Since you're not writing your own camera, I think it boils down to this:

some devices rotate the image before saving it, while others simply add the orientation tag in the photo's exif data.

I'd recommend checking the photo's exif data and looking particularly for

ExifInterface exif = new ExifInterface(SourceFileName);     //Since API Level 5
String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);

Since the photo is displaying correctly in your app, i'm not sure where the problem is, but this should definitely set you on the right path!

Why does an image captured using camera intent gets rotated on some devices on Android?

Most phone cameras are landscape, meaning if you take the photo in portrait, the resulting photos will be rotated 90 degrees. In this case, the camera software should populate the Exif data with the orientation that the photo should be viewed in.

Note that the below solution depends on the camera software/device manufacturer populating the Exif data, so it will work in most cases, but it is not a 100% reliable solution.

ExifInterface ei = new ExifInterface(photoPath);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);

Bitmap rotatedBitmap = null;
switch(orientation) {

case ExifInterface.ORIENTATION_ROTATE_90:
rotatedBitmap = rotateImage(bitmap, 90);
break;

case ExifInterface.ORIENTATION_ROTATE_180:
rotatedBitmap = rotateImage(bitmap, 180);
break;

case ExifInterface.ORIENTATION_ROTATE_270:
rotatedBitmap = rotateImage(bitmap, 270);
break;

case ExifInterface.ORIENTATION_NORMAL:
default:
rotatedBitmap = bitmap;
}

Here is the rotateImage method:

public static Bitmap rotateImage(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
matrix, true);
}

android orientation - issues with intents (camera)

When your screen orientation changes, your Activity is destroyed and recreated in the new orientation. So any variables that gained a reference during the life of the Activity will no longer refer to anything, and if you then try to access objects they refer to without re-assigning them values, you'll get a NullPointerException.

The method onSaveInstanceState() is used to save temporary data between configuration changes. This creates a Bundle which is passed to onCreate() when the Activity starts up again.

Without any code, I don't know if that's your problem, but it's worth a look.

See http://developer.android.com/reference/android/app/Activity.html#ConfigurationChanges for more information (and more accurate information than I've provided, no doubt).

How to set Android camera orientation properly?

I finally fixed this using the Google's camera app. It gets the phone's orientation by using a sensor and then sets the EXIF tag appropriately. The JPEG which comes out of the camera is not oriented automatically.

Also, the camera preview works properly only in the landscape mode. If you need your activity layout to be oriented in portrait, you will have to do it manually using the value from the orientation sensor.

Android Camera Orientation ISsue

Some devices doesn't rotate image after it was taken but just write its orientation information into Exif data. So before using taken photo you should call method like :

private int resolveBitmapOrientation(File bitmapFile) throws IOException {
ExifInterface exif = null;
exif = new ExifInterface(bitmapFile.getAbsolutePath());

return exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
}

to check its orientation. Then apply:

private Bitmap applyOrientation(Bitmap bitmap, int orientation) {
int rotate = 0;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
default:
return bitmap;
}

int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
mtx.postRotate(rotate);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}

and use this new bitmap in your listview. Or it's even better to call this methods just after your photo was taken and override it with new rotated one.

In case if you are receiving Bitmap data as Uri the following method can be used to retrieve its filepath:

public static String getPathFromURI(Context context, Uri contentUri) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT &&
DocumentsContract.isDocumentUri(context, contentUri)) {
return getPathForV19AndUp(context, contentUri);
} else {
return getPathForPreV19(context, contentUri);
}
}

private static String getPathForPreV19(Context context, Uri contentUri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(contentUri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
try {
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
return cursor.getString(columnIndex);
} finally {
cursor.close();
}
}

return null;
}

@TargetApi(Build.VERSION_CODES.KITKAT)
private static String getPathForV19AndUp(Context context, Uri contentUri) {
String documentId = DocumentsContract.getDocumentId(contentUri);
String id = documentId.split(":")[1];

String[] column = { MediaStore.Images.Media.DATA };
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{ id }, null);

if (cursor != null) {
try {
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
return cursor.getString(columnIndex);
}
} finally {
cursor.close();
}
}

return null;
}

Android image orientation issue with custom camera activity

SO you are facing some issue with the orientation of the camera.

This link shows an example app of a simple camera capture activity :
http://labs.makemachine.net/2010/03/simple-android-photo-capture/

Maybe you should try fixing the orientation by doing something like this :

          ExifInterface exif = new ExifInterface(_path);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);

int rotate = 0;

switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;

case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;

case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}

if (rotate != 0) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();

// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);

// Rotating Bitmap & convert to ARGB_8888, required by tess
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
}

JavaCameraView Camera Orientation Issue

I have solve this issue :
Use below class instead of javaCameraView :

       public class PortraitCameraView extends CameraBridgeViewBase implements Camera.PreviewCallback {

private static final int MAGIC_TEXTURE_ID = 10;
private static final String TAG = "JavaCameraView";

private byte mBuffer[];
private Mat[] mFrameChain;
private int mChainIdx = 0;
private Thread mThread;
private boolean mStopThread;

public Camera mCamera;
protected JavaCameraFrame[] mCameraFrame;
private SurfaceTexture mSurfaceTexture;
private int mCameraId;
Handler handler;
boolean callBuffer = false;
Camera.Size bestSize = null;
Camera.Size pictureSize = null;
private LayoutMode mLayoutMode;
private int mCenterPosX = -1;
private int mCenterPosY;

public static enum LayoutMode {
FitToParent, // Scale to the size that no side is larger than the parent
NoBlank // Scale to the size that no side is smaller than the parent
}

public static class JavaCameraSizeAccessor implements ListItemAccessor {

public int getWidth(Object obj) {
Camera.Size size = (Camera.Size) obj;
return size.width;
}

public int getHeight(Object obj) {
Camera.Size size = (Camera.Size) obj;
return size.height;
}
}

public PortraitCameraView(Context context, int cameraId) {
super(context, cameraId);
}

public PortraitCameraView(Context context, AttributeSet attrs) {
super(context, attrs);
}

protected boolean initializeCamera(int width, int height) {

handler = new Handler();
Log.d(TAG, "Initialize java camera");
boolean result = true;
synchronized (this) {
mCamera = null;

boolean connected = false;
int numberOfCameras = android.hardware.Camera.getNumberOfCameras();
android.hardware.Camera.CameraInfo cameraInfo = new android.hardware.Camera.CameraInfo();
for (int i = 0; i < numberOfCameras; i++) {
android.hardware.Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK) {
try {
mCamera = Camera.open(i);
mCameraId = i;
connected = true;
} catch (RuntimeException e) {
Log.e(TAG, "Camera #" + i + "failed to open: " + e.getMessage());
}
if (connected) break;
}
}

if (mCamera == null) return false;

/* Now set camera parameters */
try {
Camera.Parameters params = mCamera.getParameters();
List<Camera.Size> sizes = params.getSupportedPreviewSizes();
List<Camera.Size> Picturesizes = params.getSupportedPictureSizes();
pictureSize = Picturesizes.get(0);

List<Camera.Size> sizeList = sizes;
bestSize = sizeList.get(0);
Log.d(TAG, "getSupportedPreviewSizes() " + bestSize.width + " " + bestSize.height);
Log.d(TAG, "Picturesizes() " + pictureSize.width + " " + pictureSize.height);

// bestSize.width = GlobalArea.display_width;
//// bestSize.height = GlobalArea.display_height;
for (int i = 1; i < sizeList.size(); i++) {

if ((sizeList.get(i).width * sizeList.get(i).height) > (bestSize.width * bestSize.height)) {
Log.d(TAG, "getSupportedPreviewSizes() " + sizeList.get(i).width + " " + sizeList.get(i).height);
bestSize = sizeList.get(i);
}
}

if (sizes != null) {
/* Select the size that fits surface considering maximum size allowed */
Size frameSize = calculateCameraFrameSize(sizes, new JavaCameraSizeAccessor(), height, width); //use turn around values here to get the correct prev size for portrait mode

params.setPreviewFormat(ImageFormat.NV21);
Log.e(TAG, "Set preview size to " + Integer.valueOf((int) bestSize.width) + " x " + Integer.valueOf((int) bestSize.height));
Log.e(TAG, "Set preview size to " + width + " x " + height);
params.setPreviewSize((int) bestSize.width, (int) bestSize.height);
params.setPictureSize((int) pictureSize.width, (int) pictureSize.height);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
params.setRecordingHint(true);

List<String> FocusModes = params.getSupportedFocusModes();
if (FocusModes != null && FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
boolean hasFlash = SevenBitsDemo.getInstance().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if (hasFlash) {
// mOpenCvCameraView.flashOn();
params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);

}
List<int[]> ints = params.getSupportedPreviewFpsRange();
for (int i = 0; i < ints.size(); i++) {
Log.e("privew size", String.valueOf(ints.get(i).length));
}
// params.setPreviewFpsRange(10000,10000);
mCamera.setParameters(params);

// boolean mSurfaceConfiguring = adjustSurfaceLayoutSize(bestSize, true, width, height);

params = mCamera.getParameters();
GlobalArea.preview_size = params.getPreviewSize();
mFrameWidth = params.getPreviewSize().height; //the frame width and height of the super class are used to generate the cached bitmap and they need to be the size of the resulting frame
mFrameHeight = params.getPreviewSize().width;

int realWidth = mFrameHeight; //the real width and height are the width and height of the frame received in onPreviewFrame ...
int realHeight = mFrameWidth;
if ((getLayoutParams().width == LinearLayout.LayoutParams.MATCH_PARENT) && (getLayoutParams().height == LinearLayout.LayoutParams.MATCH_PARENT))
mScale = Math.min(((float) height) / mFrameHeight, ((float) width) / mFrameWidth);
else
mScale = 0;

if (mFpsMeter != null) {
mFpsMeter.setResolution((int) pictureSize.width, (int) pictureSize.height);
}

int size = mFrameWidth * mFrameHeight;
size = size * ImageFormat.getBitsPerPixel(params.getPreviewFormat()) / 8;
mBuffer = new byte[size];

mCamera.addCallbackBuffer(mBuffer);
mCamera.setPreviewCallbackWithBuffer(this);

mFrameChain = new Mat[2];
mFrameChain[0] = new Mat(realHeight + (realHeight / 2), realWidth, CvType.CV_8UC1); //the frame chane is still in landscape
mFrameChain[1] = new Mat(realHeight + (realHeight / 2), realWidth, CvType.CV_8UC1);

AllocateCache();

mCameraFrame = new JavaCameraFrame[2];
mCameraFrame[0] = new JavaCameraFrame(mFrameChain[0], mFrameWidth, mFrameHeight); //the camera frame is in portrait
mCameraFrame[1] = new JavaCameraFrame(mFrameChain[1], mFrameWidth, mFrameHeight);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mSurfaceTexture = new SurfaceTexture(MAGIC_TEXTURE_ID);
mCamera.setPreviewTexture(mSurfaceTexture);
} else
mCamera.setPreviewDisplay(null);

/* Finally we are ready to start the preview */
Log.d(TAG, "startPreview");
mCamera.startPreview();
} else
result = false;
} catch (Exception e) {
result = false;
e.printStackTrace();
}
}

return result;
}

protected void releaseCamera() {
synchronized (this) {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);

mCamera.release();
}
mCamera = null;
if (mFrameChain != null) {
mFrameChain[0].release();
mFrameChain[1].release();
}
if (mCameraFrame != null) {
mCameraFrame[0].release();
mCameraFrame[1].release();
}
}
}

@Override
protected boolean connectCamera(int width, int height) {

/* 1. We need to instantiate camera
* 2. We need to start thread which will be getting frames
*/
/* First step - initialize camera connection */
Log.d(TAG, "Connecting to camera");
if (!initializeCamera(width, height))
return false;

/* now we can start update thread */
Log.d(TAG, "Starting processing thread");
mStopThread = false;
mThread = new Thread(new CameraWorker());
mThread.start();

return true;
}

protected void disconnectCamera() {
/* 1. We need to stop thread which updating the frames
* 2. Stop camera and release it
*/
Log.d(TAG, "Disconnecting from camera");
try {
mStopThread = true;
Log.d(TAG, "Notify thread");
synchronized (this) {
this.notify();
}
Log.d(TAG, "Wating for thread");
if (mThread != null)
mThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mThread = null;
}

/* Now release camera */
releaseCamera();
}

public void onPreviewFrame(byte[] frame, Camera arg1) {
synchronized (this) {
mFrameChain[1 - mChainIdx].put(0, 0, frame);
this.notify();
}
if (mCamera != null)
mCamera.addCallbackBuffer(mBuffer);
}

private class JavaCameraFrame implements CvCameraViewFrame {
private Mat mYuvFrameData;
private Mat mRgba;
private int mWidth;
private int mHeight;
private Mat mRotated;

public Mat gray() {
if (mRotated != null) mRotated.release();
mRotated = mYuvFrameData.submat(0, mWidth, 0, mHeight);
//submat with reversed width and height because its done on the
landscape frame
mRotated = mRotated.t();
Core.flip(mRotated, mRotated, 1);
return mRotated;
}

public Mat rgba() {
Imgproc.cvtColor(mYuvFrameData, mRgba, Imgproc.COLOR_YUV2BGR_NV12, 4);
if (mRotated != null) mRotated.release();
mRotated = mRgba.t();
Core.flip(mRotated, mRotated, 1);
return mRotated;
}

public JavaCameraFrame(Mat Yuv420sp, int width, int height) {
super();
mWidth = width;
mHeight = height;
mYuvFrameData = Yuv420sp;
mRgba = new Mat();
}

public void release() {
mRgba.release();
if (mRotated != null) mRotated.release();
}
}

private class CameraWorker implements Runnable {

public void run() {
do {
synchronized (PortraitCameraView.this) {
try {
PortraitCameraView.this.wait();
} catch (InterruptedException e) {
Log.e(TAG, "CameraWorker interrupted", e);
}
}

if (!mStopThread) {
if (!mFrameChain[mChainIdx].empty())
deliverAndDrawFrame(mCameraFrame[mChainIdx]);
mChainIdx = 1 - mChainIdx;
}
} while (!mStopThread);
Log.d(TAG, "Finish processing thread");
}

}
}

So now use PortraitCameraView in your xml and java file because i have convert javacamera view in portrait mode in this class.

How to set camera orientation in Android?

 Camera.Parameters params= mCamera.getParameters();
params.set("rotation", 90);
mCamera.setParameters(params);


Related Topics



Leave a reply



Submit