Android设备上的图像旋转问题

时间:2014-03-01 18:12:55

标签: android camera rotation android-camera

我在Android应用中创建了一个自定义相机活动,但根据拍摄的设备,图像旋转90度时出现问题。这只发生在特定设备上,我似乎无法弄清楚原因。

我在应用中做的是

  1. 更新变量“mOrientation”,以度数(0-360)保存手机的当前方向
  2. 当用户点击快门按钮时,我会检查上次保存的方向是什么,并在保存之前相应地旋转图像。
  3. 我在两种不同的设备上测试过,华为手机和三星Galaxy S II。我发现虽然我能够确定手机的方向正确更新并且两者都有默认的纵向方向,但它们需要不同的“mOrientation”值,偏移90度,以便保存时正确定位。

    以下是我检查当前方向的方法:

    public void onOrientationChanged(int orientation) {
    if(cameraPreview.getDeviceDefaultOrientation() == Configuration.ORIENTATION_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 { // orientation <135 && orientation > 45
            if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) {
            mOrientation = ORIENTATION_LANDSCAPE_INVERTED;
            }                       
        }   
    }else{
       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 { // orientation <135 && orientation > 45
            if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) {                          
            mOrientation = ORIENTATION_PORTRAIT_NORMAL;
        }
      }
    }
    

    以下是我保存图片的方式:

    private PictureCallback myPictureCallback_JPG = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera cam) {
            Log.d(TAG, "saving picture");
            Log.d(TAG, "portrait image? " + Boolean.toString(cameraPreview.getDeviceDefaultOrientation() == Configuration.ORIENTATION_PORTRAIT));
            Log.d(TAG, "mOrientaiton: " + mOrientation);
    
            //Degrees to rotate image by when saving
            int degree = 0;
    
            // do not rotate image, just put rotation info in
            if(cameraPreview.getDeviceDefaultOrientation() == Configuration.ORIENTATION_PORTRAIT){
                switch (mOrientation) {
                case ORIENTATION_LANDSCAPE_INVERTED:
                    Log.d(TAG, "orientation landscape inverted");
                    degree = 90;
                    break;
                case ORIENTATION_PORTRAIT_NORMAL:
                    Log.d(TAG, "orientation portrait normal");
                    degree = 0;
                    break;
                case ORIENTATION_LANDSCAPE_NORMAL:
                    Log.d(TAG, "orientation landscape normal");
                    degree = 270;
                    break;
                case ORIENTATION_PORTRAIT_INVERTED:
                    Log.d(TAG, "orientation portrait inverted");
                    degree = 180;
                    break;
                }
            }else{
                switch (mOrientation) {
                case ORIENTATION_LANDSCAPE_INVERTED:
                    degree = 270;
                    break;
                case ORIENTATION_PORTRAIT_NORMAL:
                    degree = 180;
                    break;
                case ORIENTATION_LANDSCAPE_NORMAL:
                    degree = 0;
                    break;
                case ORIENTATION_PORTRAIT_INVERTED:
                    degree = 90;
                    break;
                }
            }
    
            Bitmap bMap;
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 6;
            options.inDither = false; // Disable Dithering mode
            options.inPurgeable = true; // Tell to gc that whether it needs free
            // memory, the Bitmap can be cleared
            options.inInputShareable = true; // Which kind of reference will be
            // used to recover the Bitmap
            // data after being clear, when
            // it will be used in the future
            options.inTempStorage = new byte[32 * 1024];
            options.inPreferredConfig = Bitmap.Config.RGB_565;
            bMap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
            if(degree != 0){
                bMap = rotate(bMap, degree);
            }
    
            //Getting the picture's unique file to be added to the folder
            File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
    
            /*
             * This catches errors when creating the output file to put the picture in
             */
            if (pictureFile == null) {
                Log.d(TAG,"Error creating media file, check storage permissions");
    
                //After the camera has finished taking the picture
                handler.post(new Runnable(){
    
                    @Override
                    public void run() {
                        //Remove white border from preview
                        Log.d(TAG, "removing white background from preview");
                        cameraPreview.setBackgroundResource(0);                 
                    }
    
                });
                //Setting the onclicklistener back on the shutter
                shutter.setOnClickListener(shutterClickListener);
    
                //Restarting the preview as soon as picture is done
                camera.startPreview();
    
                Toast.makeText(getApplicationContext(), "Error saving file. Try restarting the camera.", Toast.LENGTH_LONG).show();
    
                return;
            }
    
            FileOutputStream out = null;
            try {
                //Saving the image
                out = new FileOutputStream(pictureFile);
                bMap.compress(Bitmap.CompressFormat.JPEG, 90, out);
                if (bMap != null) {
                    bMap.recycle();
                    bMap = null;
                }
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }finally{
                try {
                    //Assuring we always close the output stream
                    if(out!=null){
                        out.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            myHorizontalLayout.add(Uri.parse(pictureFile.getPath()));
    
              MediaScannerConnection.scanFile(getApplicationContext(), new String[] { Environment.getExternalStorageDirectory().toString() }, null, new MediaScannerConnection.OnScanCompletedListener() {
                    public void onScanCompleted(String path, Uri uri) 
                      {
                          Log.i("ExternalStorage", "Scanned " + path + ":");
                          Log.i("ExternalStorage", "-> uri=" + uri);
    
                          camera.startPreview();
    
                          if(myHorizontalLayout.getItemList().size() == 1){
                              //Have added the first item to the pictures set check to green
                              MenuItem check = menu.findItem(R.id.save);
                          }
    
                          //After the camera has finished taking the picture
                          handler.post(new Runnable(){
                              @Override
                              public void run() {
                                  //Remove white border from preview
                                  Log.d(TAG, "removing white background");
                                  cameraPreview.setBackgroundResource(0);                 
                              }
                          });
                          //Setting the onclicklistener back on the shutter
                          shutter.setOnClickListener(shutterClickListener);
                      }
                    });
    
    
        }
    };
    

    如果有人能帮助我,我将非常感激。此外,如果有人就如何在Android设备上测试相机配置提供一般性建议而不必拥有许多不同品牌的手机,我也会很感激。

1 个答案:

答案 0 :(得分:2)

  

根据拍摄的设备将图像旋转90度存在问题

你的照片可能技术上很好。某些设备本身不会旋转图像,而是设置一个EXIF标题,告诉图像 viewer 旋转图像。并非所有图像查看者都这样做。

  

此外,如果有人就如何在Android设备上测试相机配置提供一般性建议而不必拥有许多不同品牌的手机,我也会很感激。

依靠somebody else为你做这项工作。 : - )