简体   繁体   English

自定义相机活动的Android图像方向问题

[英]Android image orientation issue with custom camera activity

I wrote a custom camera activity to handle some issues I've been having with certain android devices when calling intent image capture. 我写了一个自定义相机活动来处理我在调用意图图像捕获时遇到的某些问题。 The user is able to either select save image or just use the data returned back from the OnPictureTakenCallback . 用户可以选择保存图像,也可以只使用从OnPictureTakenCallback返回的数据。

The problem I'm having is displaying the image correctly with respect to the orientation it was taken. 我遇到的问题是正确显示图像的方向。 I force the activity to be displayed in portrait by calling SetRequestedOrientation . 我通过调用SetRequestedOrientation强制活动以纵向显示。

How would I know the correct Orientation the camera was in when the user took the picture? 当用户拍照时,我怎么知道相机所处的正确方向? ie The user could take the picture at a rotation of 90 (portrait). 即用户可以以90°(肖像)的旋转拍摄照片。

I've tried to get to use the getRotation() on the window manager's default display, but with setting the requested orientation to portrait that only returns Surface.ROTATION_0 . 我试图在窗口管理器的默认显示上使用getRotation() ,但是将请求的方向设置为仅返回Surface.ROTATION_0

Update: To clarify my other issue, how could I determine the orientation from just the byte[] data in the picture callback if the user were to not save the image? 更新:为了澄清我的另一个问题,如果用户不保存图像,如何从图片回调中的byte[]数据确定方向?

Update: After trying the answers below with this code all I'm getting is ExifInterface.ORIENTATION_NORMAL. 更新:使用此代码尝试下面的答案后,我得到的是ExifInterface.ORIENTATION_NORMAL。 I've also changed my code to just save the file returned from the camera as I'm not sure there is an easy way to determine the orientation with just having the byte[] data. 我还改变了我的代码,只保存从相机返回的文件,因为我不确定是否有一种简单的方法来确定方向,只需要有byte[]数据。

    private PictureCallback mPicture = new PictureCallback() 
    {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) 
        {
            File directory = new File(android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_PICTURES),
                    "MyApp");
            if(!directory.exists())
            {
                if(!directory.mkdirs())
                {
                    Log.d("CAMERA", "Unable to create directory to save photos.");
                    return;
                }
            }
            File file = new File(directory.getPath() + file.separator + "IMG_" + SimpleDateFormat.getDateTimeInstance().toString() + ".jpg");
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data);
            fos.close();
            ExifInterface exif = new ExifInterface(file.getCanonicalPath());
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            int rotate = 0;

            switch (orientation) 
            {
                case ExifInterface.ORIENTATION_ROTATE_90:
                   rotate = 90;
                   break; 
                case ExifInterface.ORIENTATION_ROTATE_180:
                   rotate = 180;
                   break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                   rotate = 270;
                   break;
                case default:
                   break;
             }
        }
    };

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/ 此链接显示了一个简单的相机捕获活动的示例应用程序: 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);
       }

You will need to read the Metadata from the original JPEG to verify the orientation in which the picture was taken. 您需要从原始JPEG中读取元数据,以验证拍摄照片的方向。

ExifInterface exif = new ExifInterface(SourceFileName);
String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);

Source: How to determine orientation of picture without ExifInterface? 来源: 如何在没有ExifInterface的情况下确定图片的方向?

Edit: Answering your edit, have you tried using the getCameraInfo() method that is available with the Camera object passed in the callback? 编辑:回答您的编辑,您是否尝试使用回调中传递的Camera对象可用的getCameraInfo()方法? Does it have the info you require? 它有您需要的信息吗?

Source: http://developer.android.com/reference/android/hardware/Camera.html 资料来源: http//developer.android.com/reference/android/hardware/Camera.html

public void surfaceCreated(SurfaceHolder holder) {
    try {
        mCamera.setPreviewDisplay(holder);
        Camera.Parameters parameters = mCamera.getParameters();
        if (this.getResources().getConfiguration().orientation !=
                Configuration.ORIENTATION_LANDSCAPE)
        {
            parameters.set("orientation", "portrait"); <----THis gets the job done!!!
            // For Android Version 2.2 and above
            mCamera.setDisplayOrientation(90);
            // For Android Version 2.0 and above
            parameters.setRotation(90);
        }


        // End Effects for Android Version 2.0 and higher
        mCamera.setParameters(parameters);
    }
    catch (IOException exception)
    {
        mCamera.release();
    }

}

Removing the setRequestedOrientation() allowed getWindowManager().getDefaultDisplay().getRotation() to give the correct rotation. 删除setRequestedOrientation()允许getWindowManager().getDefaultDisplay().getRotation()以提供正确的旋转。 I guess setting the requested orientation prevents the activity from redrawing itself when the configuration changes thus the device doesn't know any kind of rotation changed. 我想设置所请求的方向可防止活动在配置更改时重新绘制,因此设备不知道任何类型的旋转已更改。 My only issue now is switching from landscape mode at 0 degrees orientation to landscape mode 180 degrees rotation does not fire this: 我现在唯一的问题是从0度方向的横向模式切换到横向模式180度旋转不会触发:

@Override
public void onConfigurationChanged(Configuration newconfig)
{
    super.onConfigurationChanged(newconfig);

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM