20

研究用の簡単なカメラ アプリケーションを作成しようとしていました。Android Camera の公式ドキュメントを読み、コーディングを開始しました。だから私はそれを機能させるためにいくつかの手順を実行しました

1.アプリのカメラ機能に必要な権限を追加しました。

2.アクティビティをポートレート モードのみにロックしました。

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

3. カメラを動作させるために、いくつかのカメラ コールバックを追加しました。

  • SurfaceHolder.Callback、
  • Camera.PreviewCallback
  • AutoFocusCallback
  • シャッターコールバック
  • RAW画像データのPictureCallback
  • JPG 画像データの PictureCallback

4.surfaceChangedメソッドでは、カメラの設定をカスタマイズしていますこれまでのところ、ほぼすべてのAndroidデバイスでこれを機能させています

  • LG
  • スパイス
  • サムスン
  • HTC
  • マイクロマックス
  • ソニー
  • モトローラ
  • グーグルネクサスシリーズ。

しかし、その後、Android バージョン 2.3.6 を搭載したSamsung Galaxy ACEでテストしたところ、カメラ ディスプレイ プレビューが横向きモードに回転していることがわかりました。

したがって、log-cat/break ポイントを配置した後、この特定のモデルでは以下の方法が機能しないことがわかりました

//This method is not working for Samsung Galaxy ACE
 camera.setDisplayOrientation(90); 
//or 
parameters.set("orientation", "portrait");
//or
parameters.setRotation(90);

注: 私はGoogleとSOでも多くのソリューションを探しましたが、これまでのところ運がありませんでした

参考までに私のサンプルコードは以下です

@Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
        Log.v(TAG, "surfaceChanged get called");

        if (previewing) {
            camera.stopPreview();
            previewing = false;
        }

        if (camera != null) {
            try {
                Camera.Parameters parameters = camera.getParameters();
                List<Size> sizes = parameters.getSupportedPictureSizes();

                Camera.Size result = null;
                for (int i = 0; i < sizes.size(); i++) {
                    result = (Size) sizes.get(i);
                    Log.i("PictureSize", "Supported Size. Width: "
                            + result.width + "height : " + result.height);

                    if (result.width == 640) {
                        parameters.setPreviewSize(result.width, result.height);// 640*480
                        parameters.setPictureSize(result.width, result.height);
                    } else {

                    }
                }


                //**************************************************************//

                /* 
                 * Here is the logic I have added to Manage Camera Display Orientation
                 *  It checks Current Orientation and SDK and then rotate display to make it Portrait view.
                 */
                int currentSDKVersion = android.os.Build.VERSION.SDK_INT;
                Log.d(TAG, "currentVersion " + currentSDKVersion);

                if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                    if (currentSDKVersion != 7) {

                        camera.setDisplayOrientation(90);
                         parameters.setRotation(90);
                    } else {
                            parameters.setRotation(90);

                        /*
                         * params.set("orientation", "portrait");
                         * params.set("rotation",90);
                         */
                    }
                } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
                    if (currentSDKVersion != 7) {

                        camera.setDisplayOrientation(0);
                    } else {

                        parameters.set("orientation", "landscape");
                        parameters.set("rotation", 90);

                    }
                }


                //**************************************************************//

                camera.setParameters(parameters);
                camera.setPreviewDisplay(surfaceHolder);
                camera.startPreview();
                camera.autoFocus(myAutoFocusCallback);
                camera.setOneShotPreviewCallback(cameraPreviewCallback);
                previewing = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

マイ カメラ アクティビティ (MainActivity.java) 完全なコードは次のとおりです。

public class MainActivity extends Activity implements SurfaceHolder.Callback,
        OnClickListener {

    public static final String TAG = "CameraActivity";
    private Context context = null;
    Camera camera = null;
    private SurfaceView surfaceView = null;
    private SurfaceHolder surfaceHolder = null;
    boolean previewing = false;
    private LayoutInflater controlInflater = null;
    private Button buttonTakePicture = null;
    //private TextView textViewResultInfo = null;

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Log.v(TAG, "onCreate get called");

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        //textViewResultInfo = (TextView) findViewById(R.id.textViewResultInfo);
        context = this;

        getWindow().setFormat(PixelFormat.UNKNOWN);
        surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        controlInflater = LayoutInflater.from(getBaseContext());
        View viewControl = controlInflater.inflate(R.layout.control, null);
        LayoutParams layoutParamsControl = new LayoutParams(
                LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        this.addContentView(viewControl, layoutParamsControl);

        buttonTakePicture = (Button) findViewById(R.id.takepicture);
        buttonTakePicture.setOnClickListener(this);

    }

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {

        Log.v(TAG, "surfaceCreated get called");
        camera = Camera.open();

        if (camera != null) {
            try {
                camera.setPreviewDisplay(surfaceHolder);
                camera.startPreview();
                previewing = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
        Log.v(TAG, "surfaceChanged get called");

        if (previewing) {
            camera.stopPreview();
            previewing = false;
        }

        if (camera != null) {
            try {

                 //new MainActivity().setCameraDisplayOrientation();

                Camera.Parameters parameters = camera.getParameters();
                // List<String> focusModes =
                // parameters.getSupportedFocusModes();
                // if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO))
                // {
                // parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                // }

                List<Size> sizes = parameters.getSupportedPictureSizes();

                Camera.Size result = null;
                for (int i = 0; i < sizes.size(); i++) {
                    result = (Size) sizes.get(i);
                    Log.i("PictureSize", "Supported Size. Width: "
                            + result.width + "height : " + result.height);

                    if (result.width == 640) {
                        parameters.setPreviewSize(result.width, result.height);// 640*480
                        parameters.setPictureSize(result.width, result.height);
                    } else {

                    }
                }


                //**************************************************************//

                Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
                int rotation = display.getRotation();
                Log.v(TAG, "Current Device Orientation is ="+rotation);

                /* 
                 * Here is the logic I have added to Manage Camera Display Orientation
                 *  It checks Current Orientation and SDK and then rotate display to make it Portrait view.
                 */
                int currentSDKVersion = android.os.Build.VERSION.SDK_INT;
                Log.d(TAG, "currentVersion " + currentSDKVersion);

                if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                    if (currentSDKVersion != 7) {
                        Log.i(TAG, "ORIENTATION_PORTRAIT +SDK is: " + currentSDKVersion
                                + "rotate 90");
                        camera.setDisplayOrientation(90);
                         parameters.setRotation(90);
                    } else {
                        Log.i(TAG, "ORIENTATION_PORTRAIT +SDK is: " + currentSDKVersion
                                + "rotate 90");
                        parameters.setRotation(90);

                        /*
                         * params.set("orientation", "portrait");
                         * params.set("rotation",90);
                         */
                    }
                } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
                    if (currentSDKVersion != 7) {
                        Log.i(TAG, "ORIENTATION_LANDSCAPE +SDK is: " + currentSDKVersion
                                + "rotate 90");

                        camera.setDisplayOrientation(0);
                    } else {

                        Log.i(TAG, "ORIENTATION_LANDSCAPE +SDK is: " + currentSDKVersion
                                + "rotate 90");

                        parameters.set("orientation", "landscape");
                        parameters.set("rotation", 90);

                    }
                }


                //**************************************************************//


                camera.setParameters(parameters);
                camera.setPreviewDisplay(surfaceHolder);
                camera.startPreview();
                camera.autoFocus(myAutoFocusCallback);
                camera.setOneShotPreviewCallback(cameraPreviewCallback);
                previewing = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        Log.v(TAG, "surfaceDestroyed get called");
        camera.stopPreview();
        camera.release();
        camera = null;
        previewing = false;

    }


    public void setCameraDisplayOrientation() 
    {        
        Log.v(TAG, "setCameraDisplayOrientation get called");

         if (camera == null)
         {
             Log.d(TAG,"setCameraDisplayOrientation - camera null");
             return;             
         }

         Camera.CameraInfo info = new Camera.CameraInfo();
         Camera.getCameraInfo(1, info);

         WindowManager winManager = (WindowManager) context.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);
    }


    @Override
    public void onClick(View v) {
        Log.v(TAG, "onClick get called");

        if (v == buttonTakePicture) {
            camera.takePicture(myShutterCallback, myPictureCallback_RAW,
                    myPictureCallback_JPG);
        }

    }

    private Camera.PreviewCallback cameraPreviewCallback = new Camera.PreviewCallback() {
        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            Log.i(TAG, "onPreviewFrame size=" + data.length);
        }
    };

    AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback() {

        @Override
        public void onAutoFocus(boolean arg0, Camera arg1) {
            Log.v(TAG, "onAutoFocus get called");
            buttonTakePicture.setEnabled(true);
        }
    };

    ShutterCallback myShutterCallback = new ShutterCallback() {

        @Override
        public void onShutter() {
            Log.v(TAG, "onShutter get called");
        }
    };

    PictureCallback myPictureCallback_RAW = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] arg0, Camera arg1) {
            Log.v(TAG, "onPictureTaken-RAW get called");

        }
    };

    public static Bitmap RotateBitmap(Bitmap source, float angle) {
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
                source.getHeight(), matrix, true);
    }

    PictureCallback myPictureCallback_JPG = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] arg0, Camera arg1) {
            Bitmap rawImage = BitmapFactory.decodeByteArray(arg0, 0,
                    arg0.length);

            if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                Log.v(TAG, "#####  ORIENTATION_PORTRAIT   ####");

                rawImage = MainActivity.RotateBitmap(rawImage, 90);

                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                rawImage.compress(Bitmap.CompressFormat.JPEG, 100, stream);
                arg0 = stream.toByteArray();

            } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
                Log.v(TAG, "#####   ORIENTATION_LANDSCAPE  #####");

            }

            Intent intent = new Intent(MainActivity.this, ResultActivity.class);
            intent.putExtra("picture", arg0);
            startActivity(intent);

            Log.v(TAG, "onPictureTaken-JPG get called");

        }
    };

    /**
     * Get the size in bitmap.
     * 
     * @param bitmap
     * @return size in bytes
     */
    @TargetApi(12)
    public static int getBitmapSize(Bitmap bitmap) {
        if (MainActivity.hasHoneycombMR1()) {
            return bitmap.getByteCount();
        }
        // Pre HC-MR1
        return bitmap.getRowBytes() * bitmap.getHeight();
    }

    public static boolean hasHoneycombMR1() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1;
    }

}

編集:開発者フォーラムにコメントを投稿しましたが、応答がありません。

お願いします!!誰かがこの問題に関するアイデアを持っています。

どんな種類の提案でも本当に感謝しています。

4

3 に答える 3

12

2.2.1 を実行しているオリジナルの Galaxy Tab で同様の問題が発生したとき、次の手順で解決できました。

Camera.Parameters parameters = camera.getParameters();
parameters.set("orientation", "portrait");
parameters.setRotation(90);
camera.setParameters(parameters);

ただし、上記のコードが同一 (ただしコメントアウトされている) であることを考えると、その正確な組み合わせを既に試している可能性があります。ただし、現在のコードの方法では、Ace は API レベル (10) であるため、コメントされたコードがある場所をバイパスします。このブロック内で具体的に試してください:

if (currentSDKVersion != 7) { }

そして、それがうまくいくかどうか教えてください。ありがとう!

于 2013-10-08T20:00:45.667 に答える