8

カメラアプリに問題があります.カメラのアクティビティは縦向きモードです.だから私は与えました

camera.setDisplayOrientation(90);

SO のさまざまな投稿によると、これはポートレート モードで正常に機能します。

問題は、プレビューが左または右に 90 度回転したことです。Htc では問題ありません。しかし、galaxy シリーズでは機能しません。

誰でも私を助けることができますか?

4

4 に答える 4

2

次のさまざまな方法で向きとプレビューを設定し、要件として使用します。

最初の方法:

  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
  {            
    if (isPreviewRunning)
    {
        mCamera.stopPreview();
    }

    Parameters parameters = mCamera.getParameters();
    Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

    if(display.getRotation() == Surface.ROTATION_0)
    {
        parameters.setPreviewSize(height, width);                           
        mCamera.setDisplayOrientation(90);
    }

    if(display.getRotation() == Surface.ROTATION_90)
    {
        parameters.setPreviewSize(width, height);                           
    }

    if(display.getRotation() == Surface.ROTATION_180)
    {
        parameters.setPreviewSize(height, width);               
    }

    if(display.getRotation() == Surface.ROTATION_270)
    {
        parameters.setPreviewSize(width, height);
        mCamera.setDisplayOrientation(180);
    }

    mCamera.setParameters(parameters);
    previewCamera();                      
}

  public void previewCamera()
  {        
     try 
     {           
          mCamera.setPreviewDisplay(mSurfaceHolder);          
          mCamera.startPreview();
          isPreviewRunning = true;
     }
     catch(Exception e)
     {
         Log.d(APP_CLASS, "Cannot start preview", e);    
     }
 }

2 番目の方法:

  private Camera mCamera;
  private OrientationEventListener mOrientationEventListener;
  private int mOrientation =  -1;

 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;

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         // force Landscape layout
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR |           ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
   /*
      Your other initialization code here
   */
   }

 @Override 
  protected void onResume() {
       super.onResume();

        if (mOrientationEventListener == null) {            
              mOrientationEventListener = new OrientationEventListener(this,  SensorManager.SENSOR_DELAY_NORMAL) {

        @Override
        public void onOrientationChanged(int orientation) {

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

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

            if (lastOrientation != mOrientation) {
                changeRotation(mOrientation, lastOrientation);
            }
        }
    };
}
if (mOrientationEventListener.canDetectOrientation()) {
    mOrientationEventListener.enable();
    }
 }

  @Override protected void onPause() {
       super.onPause();
       mOrientationEventListener.disable();
  }

    /**
     * Performs required action to accommodate new orientation
     * @param orientation
     * @param lastOrientation
    */
   private void changeRotation(int orientation, int lastOrientation) {
   switch (orientation) {
    case ORIENTATION_PORTRAIT_NORMAL:
        mSnapButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_camera, 270));
        mBackButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_revert, 270));
        Log.v("CameraActivity", "Orientation = 90");
        break;
    case ORIENTATION_LANDSCAPE_NORMAL:
        mSnapButton.setImageResource(android.R.drawable.ic_menu_camera);
        mBackButton.setImageResource(android.R.drawable.ic_menu_revert);
        Log.v("CameraActivity", "Orientation = 0");
        break;
    case ORIENTATION_PORTRAIT_INVERTED:
        mSnapButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_camera, 90));
        mBackButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_revert, 90));
        Log.v("CameraActivity", "Orientation = 270");
        break;
    case ORIENTATION_LANDSCAPE_INVERTED:
        mSnapButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_camera, 180));
        mBackButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_revert, 180));      
        Log.v("CameraActivity", "Orientation = 180");
        break;
     }
  } 

    /**
   * Rotates given Drawable
   * @param drawableId    Drawable Id to rotate
   * @param degrees       Rotate drawable by Degrees
   * @return              Rotated Drawable
   */
 private Drawable getRotatedImage(int drawableId, int degrees) {
    Bitmap original = BitmapFactory.decodeResource(getResources(), drawableId);
    Matrix matrix = new Matrix();
    matrix.postRotate(degrees);

   Bitmap rotated = Bitmap.createBitmap(original, 0, 0, original.getWidth(),  original.getHeight(),  matrix, true);
  return new BitmapDrawable(rotated);
}

次に、PictureCallback でメタデータを設定して、回転レベルを示します。

private Camera.PictureCallback mJpegCallback = new Camera.PictureCallback() {

@Override
public void onPictureTaken(byte[] data, Camera camera) {
    try {
        // Populate image metadata

        ContentValues image = new ContentValues();
        // additional picture metadata
        image.put(Media.DISPLAY_NAME, [picture name]);
        image.put(Media.MIME_TYPE, "image/jpg");
        image.put(Media.TITLE, [picture title]);
        image.put(Media.DESCRIPTION, [picture description]);
        image.put(Media.DATE_ADDED, [some time]);
        image.put(Media.DATE_TAKEN, [some time]);
        image.put(Media.DATE_MODIFIED, [some time]);

        // do not rotate image, just put rotation info in
        switch (mOrientation) {
            case ORIENTATION_PORTRAIT_NORMAL:
                image.put(Media.ORIENTATION, 90);
                break;
            case ORIENTATION_LANDSCAPE_NORMAL:
                image.put(Media.ORIENTATION, 0);
                break;
            case ORIENTATION_PORTRAIT_INVERTED:
                image.put(Media.ORIENTATION, 270);
                break;
            case ORIENTATION_LANDSCAPE_INVERTED:
                image.put(Media.ORIENTATION, 180);
                break;
        }

        // store the picture
        Uri uri = getContentResolver().insert(
                Media.EXTERNAL_CONTENT_URI, image);

        try {
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
                    data.length);
            OutputStream out = getContentResolver().openOutputStream(
                    uri);
            boolean success = bitmap.compress(
                    Bitmap.CompressFormat.JPEG, 75, out);
            out.close();
            if (!success) {
                finish(); // image output failed without any error,
                            // silently finish
            }

現在、ランドスケープ ベースのデバイスが表示されている場合は、OrientationEventListener で追加のチェックが必要です。

  Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();                                        
 if (display.getOrientation() == Surface.ROTATION_0) { 
    // landscape oriented devices
 } else { 
     // portrait oriented device
 }

完全なコード (LC では少し無駄ですが、アプローチを簡単に示します)

 @Override
 public void onOrientationChanged(int orientation) {

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

Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();                                        

if (display.getOrientation() == Surface.ROTATION_0) {   // landscape oriented devices
    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
    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_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
    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;
        }                       
    }
 }

  if (lastOrientation != mOrientation) {
    changeRotation(mOrientation, lastOrientation);
  }
 }

第三の方法:

 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);
}
于 2014-09-13T11:26:14.070 に答える
1

私は同様の質問にこの回答をしましたが、あなたが言うように、それは HTC デバイス上にありました。ローテーション コードにブレークポイントを追加し、デバイスを物理的に回転させながら変数を調べることをお勧めします。これは、Galaxy モデルとの違いを特定するのに役立つ場合があります。

于 2012-08-18T09:34:55.863 に答える
1

私のために働いた新しいソリューションを投稿するだけです。

基本的に、Camera.CameraInfo から向きの値を取得できます。これにより、画像が適切に表示されるようにsetDisplayOrientationで使用する必要がある角度がわかります。背面カメラを使用する場合は、取得した値でsetDisplayOrientationを使用するだけで済みますが、前面カメラを使用する場合は、Android システムが画像を反転して鏡のように表示するため、少し微調整する必要があります。

以下のコードは私にとってはうまくいき、Nexus6とGalaxyを含む4つの異なるデバイスでテストされました.

Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
int cameraCount = Camera.getNumberOfCameras();
int camIdx = 0; // DO your logic to get front or back camera...or loop through all avaialable.
Camera.getCameraInfo(camIdx, cameraInfo);

try {
    mCamera = Camera.open(camIdx);
    // If using back camera then simply rotate what CameraInfo tells you.
    if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK)
        mCamera.setDisplayOrientation(cameraInfo.orientation);
    else
        // If using front camera note that image might be flipped to give users the impresion the are looking at a mirror.
        mCamera.setDisplayOrientation( (360 - cameraInfo.orientation) % 360);
} catch (Exception e) {
    e.printStackTrace();
}
于 2016-08-04T03:33:02.007 に答える
1

「画面の自動回転」オプションが電話の設定でチェックされているかどうかを確認します (設定 > ディスプレイまたは画面 - Android のバージョンによって異なります)。

于 2014-03-28T13:45:13.023 に答える