android中三星设备上的相机捕捉方向

Posted

技术标签:

【中文标题】android中三星设备上的相机捕捉方向【英文标题】:Camera capture orientation on samsung devices in android 【发布时间】:2013-08-14 17:33:10 【问题描述】:

我正在创建一个相机应用程序。捕获的图像显示在网格视图中。 现在,该代码在除三星设备之外的所有设备上都可以正常运行。

我正面临方向问题。当我以纵向模式拍摄图像时,图像在网格视图中显示时会旋转。我没有保留任何旋转代码。 其次,使用 EXIF,我在网格视图中获得了正确的图像,但是当设备方向发生变化时,图像再次以奇怪的方式旋转。

附加图片:

对不起,图片的分辨率。请让我知道它们是否不正确。将再次上传。我知道有很多这样的帮助。但我想我被困在某个地方了。

我指的是以下链接:

http://blog.andolasoft.com/2013/06/how-to-show-captured-images-dynamically-in-gridview-layout.html

【问题讨论】:

【参考方案1】:

这是我使用的代码(适用于所有设备):

这部分是我在主要活动中将拍摄的照片设置为图像视图的地方:

            try 
                File imageFile = new File(cursor.getString(0));
                ExifInterface exif = new ExifInterface(
                        imageFile.getAbsolutePath());
                int orientation = exif.getAttributeInt(
                        ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_NORMAL);
                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;
                

                Log.v("", "Exif orientation: " + orientation);
             catch (Exception e) 
                e.printStackTrace();
            
            Matrix matrix = new Matrix();
            matrix.postRotate(rotate);
            bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
            testImage.setImageBitmap(null);
            testImage.setImageBitmap(bmp);

相机活动中的常量值:

  private static final int ORIENTATION_PORTRAIT_NORMAL =  1;
  private static final int ORIENTATION_PORTRAIT_INVERTED =  2;
  private static final int ORIENTATION_LANDSCAPE_NORMAL =  3;
  private static final int ORIENTATION_LANDSCAPE_INVERTED =  4;
  private OrientationEventListener mOrientationEventListener;
  private int mOrientation =  -1;

相机活动中的回调函数:

      Camera.PictureCallback photoCallback=new Camera.PictureCallback()
          public void onPictureTaken(final byte[] data, final Camera camera)

              dialog=ProgressDialog.show(CameraActivity.this,"","Please wait while the photo is being saved..");
              new Thread()
                  public void run()
                      try
                          Thread.sleep(1000);         
                      
                      catch(Exception ex)
                      onPictureTake(data,camera);     
                  
              .start();      
          
      ;

相机活动中的拍照功能:

      public void onPictureTake(byte[] data, Camera camera)
          switch (mOrientation) 
          case ORIENTATION_PORTRAIT_NORMAL:
              rotate = 90;
              break;
          case ORIENTATION_LANDSCAPE_NORMAL:
              rotate = 0;
              break;
          case ORIENTATION_PORTRAIT_INVERTED:
              rotate = 270;
              break;
          case ORIENTATION_LANDSCAPE_INVERTED:
              rotate = 180;
              break;
          

          Matrix matrix = new Matrix();
          matrix.postRotate(rotate);
          bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
          bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
          mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true);
          savePhoto(mutableBitmap);
          dialog.dismiss();
          flag = 0;
          finish();
      

在相机活动的 onresume 中调用的方向监听器:

mOrientationEventListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) 

                @SuppressWarnings("deprecation")
                @Override
                public void onOrientationChanged(int orientation) 

                    // determine our orientation based on sensor response
                    int lastOrientation = mOrientation;

                    Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();   
                    int rotation = getWindowManager().getDefaultDisplay().getRotation();
                    System.out.println(rotation+"");

                if (display.getOrientation() != Surface.ROTATION_0)    // landscape oriented devices
                        System.out.println("LANDSCAPE");
                        if (orientation >= 315 || orientation < 45) 
                            if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL)                          
                                mOrientation = ORIENTATION_LANDSCAPE_NORMAL;
                            
                         else if (orientation < 315 && orientation >= 225) 
                            if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) 
                                mOrientation = ORIENTATION_PORTRAIT_INVERTED;
                                                   
                         else if (orientation < 225 && orientation >= 135) 
                            if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) 
                                mOrientation = ORIENTATION_LANDSCAPE_INVERTED;
                                                   
                         else if (orientation <135 && orientation > 45)  
                            if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) 
                                mOrientation = ORIENTATION_PORTRAIT_NORMAL;
                                                   
                                               
                     else   // portrait oriented devices
                        System.out.println("PORTRAIT");
                        if (orientation >= 315 || orientation < 45) 
                            if (mOrientation != ORIENTATION_PORTRAIT_NORMAL)                           
                                mOrientation = ORIENTATION_PORTRAIT_NORMAL;
                            
                         else if (orientation < 315 && orientation >= 225) 
                            if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) 
                                mOrientation = ORIENTATION_LANDSCAPE_NORMAL;
                                                   
                         else if (orientation < 225 && orientation >= 135) 
                            if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) 
                                mOrientation = ORIENTATION_PORTRAIT_INVERTED;
                                                   
                         else if (orientation <135 && orientation > 45)  
                            if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) 
                                mOrientation = ORIENTATION_LANDSCAPE_INVERTED;
                                                   
                        
                    

                
            ;

【讨论】:

只为三星工作!!【参考方案2】:

这是我在我的应用中用于旋转并适用于所有设备的代码:

private Bitmap adjustImageOrientation(Bitmap image) 
        ExifInterface exif;
        try 
            exif = new ExifInterface(picturePath);
            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 = image.getWidth();
                int h = image.getHeight();

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

                // Rotating Bitmap & convert to ARGB_8888, required by tess
                image = Bitmap.createBitmap(image, 0, 0, w, h, mtx, false);

            
         catch (IOException e) 
                 return null;
        
        return image.copy(Bitmap.Config.ARGB_8888, true);
    

【讨论】:

这是在旋转我的手机屏幕:(【参考方案3】:

首先你需要得到原始文件的方向--

      try 
                        ExifInterface exif = new ExifInterface("File AbsolutePath");
                        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
                        Bitmap bm = rotateBitmap("Old Bitmap", orientation);
                     catch (IOException e) 
                        e.printStackTrace();
                    

您需要编写一个方法,将位图旋转到正确的方向后返回它。

public Bitmap rotateBitmap(Bitmap bitmap, int orientation) throws IOException 

        Matrix matrix = new Matrix();
        switch (orientation) 
        case ExifInterface.ORIENTATION_NORMAL:
            return bitmap;
        case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
            matrix.setScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            matrix.setRotate(180);
            break;
        case ExifInterface.ORIENTATION_FLIP_VERTICAL:
            matrix.setRotate(180);
            matrix.postScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_TRANSPOSE:
            matrix.setRotate(90);
            matrix.postScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_ROTATE_90:
            matrix.setRotate(90);
            break;
        case ExifInterface.ORIENTATION_TRANSVERSE:
            matrix.setRotate(-90);
            matrix.postScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            matrix.setRotate(-90);
            break;
        default:
            return bitmap;
        
        try 
            Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            bitmap.recycle();
            return bmRotated;
         catch (OutOfMemoryError e) 
            e.printStackTrace();
            return null;
        
    

【讨论】:

以上是关于android中三星设备上的相机捕捉方向的主要内容,如果未能解决你的问题,请参考以下文章

Nexus设备上的Android相机捕获活动错误

为啥使用相机意图捕获的图像会在 Android 上的某些设备上旋转?

三星 Galaxy S3 上的 Android 相机预览不正确

通过具有 16:9 传感器阵列的相机上的 android Camera2 API 捕获 4:3 相机图片

固定方向Android上的设备旋转

Android中的相机方向问题