【问题标题】:How to detect camera orientation in android?如何在android中检测相机方向?
【发布时间】:2017-03-21 03:19:32
【问题描述】:

当我在我的 Android One 手机或模拟器本身上测试我的应用程序时,一切正常,但在其他一些设备上出现问题。

问题是,我基本上发送一个相机意图,在用户拍照后从意图中获取数据,然后我用从相机得到的任何东西设置ImageView 的像素。对于某些设备(主要是三星),图像会旋转,拍摄时不会显示。

我的应用只能在纵向模式下工作,但如果用户在拍照时旋转手机,也可以在横向模式下拍照。

有没有办法检测设备旋转图像的默认角度,所以我在拍摄图像后旋转位图?

代码如下:

发送意图:

File path = new File(getActivity().getFilesDir(), "map_roomie");

if (!path.exists()) path.mkdirs();

mFileName = createImageFileName();

File image   = new File(path, mFileName);
Uri imageUri = FileProvider.getUriForFile(getActivity(), AddRoomFragment.CAPTURE_IMAGE_FILE_PROVIDER, image);

Intent imageCaptureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                                         imageCaptureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                                            startActivityForResult(imageCaptureIntent, AddRoomFragment.CAMERA_CAPTURE_IMAGE_REQUEST_CODE);

捕捉片段的意图

File path = new File(getActivity().getFilesDir(), "map_roomie");

if (!path.exists()) path.mkdirs();

File imageFile = new File(path, mFileName);

setBitmapOfImageView(mCurrentPhotoId, decodeAndReturnBitmap(imageFile.getAbsolutePath()));

辅助函数:

public void setBitmapOfImageView(int photoId, Bitmap bitmap)
{
    mPhotos[photoId].setImageBitmap(bitmap);

    mPhotosState[photoId] = 1;
}

public Bitmap decodeAndReturnBitmap(String filePath)
{
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds    = true;

    BitmapFactory.decodeFile(filePath, o);

    final int REQUIRED_SIZE = 512;

    int widthTemp = o.outWidth, heightTemp = o.outHeight;
    int scale     = 1;

    while (true) {
        if (widthTemp < REQUIRED_SIZE && heightTemp < REQUIRED_SIZE) {
            break;
        }

        widthTemp  /= 2;
        heightTemp /= 2;
        scale      *= 2;
    }

    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize          = scale;

    return BitmapFactory.decodeFile(filePath, o2);
}

【问题讨论】:

    标签: android


    【解决方案1】:

    如果你想让摄像头图像显示在与显示器相同的方向,可以使用以下代码。

    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);
         }
    

    更多信息,请参考https://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)

    【讨论】:

    • 感谢您的快速回复。我应该创建什么并将其作为参数传递给第二个和第三个参数?
    【解决方案2】:

    这个解决方案适合我。

    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);
    }
    

    【讨论】:

      【解决方案3】:

      请看-

          private int getCameraId() {
              int curCameraId = 0;
      
              if (Camera.getNumberOfCameras() > 0) {
                  curCameraId = (curCameraId + 1) % Camera.getNumberOfCameras();
              } else {
                  curCameraId = 0;
              }
              return curCameraId;
          }
      
          public void setCameraDisplayOrientation(Activity activity, int curCameraId) {
              if (camera == null) {
                  try {
                      camera = Camera.open(curCameraId);
                  } catch (Exception e) {
                  }
              }
              Camera.CameraInfo info = new Camera.CameraInfo();
      
              Camera.getCameraInfo(curCameraId, info);
              WindowManager winManager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
              int rotation = winManager.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);
          }
      

      【讨论】:

      • java.lang.RuntimeException: 无法启动活动 ComponentInfo java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'void android.hardware.Camera.setDisplayOrientation(int)'跨度>
      【解决方案4】:

      我使用 ExifInterface 解决了这个问题。但是,如果有人能对在拍照时检测应用在图像上的默认角度有所了解,那就太好了。

      代码如下:

      public Bitmap decodeAndReturnBitmap(String filePath)
      {
          BitmapFactory.Options o = new BitmapFactory.Options();
          o.inJustDecodeBounds    = true;
      
          BitmapFactory.decodeFile(filePath, o);
      
          final int REQUIRED_SIZE = 512;
      
          int widthTemp = o.outWidth, heightTemp = o.outHeight;
          int scale     = 1;
      
          while (true) {
              if (widthTemp < REQUIRED_SIZE && heightTemp < REQUIRED_SIZE) {
                  break;
              }
      
              widthTemp  /= 2;
              heightTemp /= 2;
              scale      *= 2;
          }
      
          ExifInterface exifInterface = null;
      
          try {
              exifInterface = new ExifInterface(filePath);
          } catch (IOException e) {
              e.printStackTrace();
          }
      
          int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
      
          Matrix matrix = new Matrix();
      
          switch(orientation) {
              case ExifInterface.ORIENTATION_ROTATE_90 :
                  matrix.setRotate(90.0f);
                  break;
      
              case ExifInterface.ORIENTATION_ROTATE_180:
                  matrix.setRotate(180.0f);
                  break;
      
             case ExifInterface.ORIENTATION_ROTATE_270:
                  matrix.setRotate(270.0f);
                  break;
      
          }
      
          BitmapFactory.Options o2 = new BitmapFactory.Options();
          o2.inSampleSize          = scale;
      
          Bitmap bitmap = BitmapFactory.decodeFile(filePath, o2);
      
          return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
      }
      

      【讨论】:

        猜你喜欢
        • 2018-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-02
        • 2013-12-02
        相关资源
        最近更新 更多