1

私はAPI7(2.1)用に開発しています。私は次のようなカメラビューを実装しました:

public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;

int width;
int height;

Camera mCamera;

public CameraView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initHolder();
}

public CameraView(Context context) {
    super(context);
    initHolder();
}

private void initHolder() {
    // Install a SurfaceHolder.Callback so we get notified when the
    // underlying surface is created and destroyed.
    mHolder = getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, acquire the camera and tell it where to
    // draw.
    mCamera = Camera.open();

//      Parameters params = mCamera.getParameters();
//      // If we aren't landscape (the default), tell the camera we want
//      // portrait mode
//      if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
//          params.set("orientation", "portrait"); // "landscape"
//          // And Rotate the final picture if possible
//          // This works on 2.0 and higher only
//          // params.setRotation(90);
//          // Use reflection to see if it exists and to call it so you can
//          // support older versions
//          try {
//              Method rotateSet = Camera.Parameters.class.getMethod("setRotation", new Class[] { Integer.TYPE });
//              Object arguments[] = new Object[] { new Integer(90) };
//              rotateSet.invoke(params, arguments);
//          } catch (NoSuchMethodException nsme) {
//              // Older Device
//              Log.v("CAMERAVIEW", "No Set Rotation");
//          } catch (IllegalArgumentException e) {
//              Log.v("CAMERAVIEW", "Exception IllegalArgument");
//          } catch (IllegalAccessException e) {
//              Log.v("CAMERAVIEW", "Illegal Access Exception");
//          } catch (InvocationTargetException e) {
//              Log.v("CAMERAVIEW", "Invocation Target Exception");
//          }
//      }
//      mCamera.setParameters(params);
    setDisplayOrientation(mCamera, 90);

    try {
        mCamera.setPreviewDisplay(holder);
    } catch (IOException exception) {
        mCamera.release();
        mCamera = null;
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // Surface will be destroyed when we return, so stop the preview.
    // Because the CameraDevice object is not a shared resource, it's very
    // important to release it when the activity is paused.
    mCamera.stopPreview();
    mCamera.release();
    mCamera = null;
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    width = w;
    height = h;
    // Now that the size is known, set up the camera parameters and begin the preview.
    Camera.Parameters parameters = mCamera.getParameters();
    //parameters.setPreviewSize(w, h);
    mCamera.setParameters(parameters);

    mCamera.startPreview();
}

public void takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback jpeg) {
    mCamera.takePicture(shutter, raw, jpeg);
}

protected void setDisplayOrientation(Camera camera, int angle){
    Method downPolymorphic;
    try {
        downPolymorphic = camera.getClass().getMethod("setDisplayOrientation", new Class[] { int.class });
        if (downPolymorphic != null) {
            downPolymorphic.invoke(camera, new Object[] { angle });
        }

    } catch (Exception e1) {}
}
}

反射を使用するアプローチ( Androidカメラの回転でのWilliewの回答から取得)のみがデバイスで機能し、正しい回転でプレビューを表示します。それ以外の場合、プレビューは常に-90°回転します

これまでのところ良いですが、今は別の問題があります。アクティビティのコールバックでビットマップを取得すると、次のようになります。

public void onPictureTaken(byte[] data, Camera camera) {
    Bitmap b = BitmapFactory.decodeByteArray(data, 0, data.length);

    Log.d("test", "---width: "  + b.getWidth() + " height: " + b.getHeight());
}

常にランドスケープモードです!(この場合は2560 x 1920)。したがって、ユーザーがデバイスをポートレートモードで保持している写真を撮った場合、ビットマップ2560 x 1920が得られます。これは、とにかく、画像ビューに入れたときに撮ったポートレート写真とまったく同じように見えます。ユーザーがデバイスを横向きモードで保持している写真を撮るときに問題が発生します。結果を縦向きモード(縮小)で表示するために、または横向きの写真に対して他の特別なアクションを実行するために、デバイスを回転させたいと思います。

しかし、ビットマップの寸法が同じであるため、ポートレート写真と区別することはできません:/

ポートレート/風景写真をどのように認識しますか?

何か案が...?私はカメラに不慣れで、ちょっと迷子になりました...よろしくお願いします。

編集 OK、問題はないと思います。デバイスをどのように持っていても、画像は実際には常に同じ寸法であるため、寸法は常に同じです。私が理解していない唯一のことは、プレビューと写真が明らかにポートレートモードであるときに、なぜ幅>高さを常に取得するのかということです。

4

0 に答える 0