18

カメラを使って写真を撮ろうとしています。デフォルトのプレビューは横向きモードでしたが、縦向きモードに変更できました

    setCameraDisplayOrientation(this,1,  mCamera);
    public static void setCameraDisplayOrientation(Activity activity,
         int cameraId, android.hardware.Camera camera) {
     android.hardware.Camera.CameraInfo info =
             new android.hardware.Camera.CameraInfo();
     android.hardware.Camera.getCameraInfo(cameraId, info);
     int rotation = activity.getWindowManager().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);
 }

キャプチャされた画像は、myImages フォルダーに保存されます。しかし、画像は回転しています。(画像はランドスケープモードでキャプチャされたように見えます)

では、キャプチャした画像を回転させて保存するにはどうすればよいですか?

public class MainActivity extends Activity {

private static final int REQUEST_CODE = 1; 
ImageView imageView;
Button b;
private Camera mCamera;
private CameraPreview mPreview;
private Bitmap bitmap;
private PictureCallback mPicture;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    boolean check =checkCameraHardware(MainActivity.this);
    if(check)
    {
         mCamera = getCameraInstance();

        // mCamera.setDisplayOrientation(90);
         setCameraDisplayOrientation(this,
                 1,  mCamera);//requires min sdk 9
    }
    // Create an instance of Camera
    mPicture = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            File imagesFolder = new File(Environment.getExternalStorageDirectory(), "MyImages");
            if(!imagesFolder.exists())
            imagesFolder.mkdirs();   
            File pictureFile = new File(imagesFolder, "image.jpg");

            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);

                System.out.println("hello");
                fos.write(data);
                fos.close();
            } catch (FileNotFoundException e) {
                Log.d("No File", "File not found: " + e.getMessage());
            } catch (IOException e) {
                //Log.d(TAG, "Error accessing file: " + e.getMessage());
            }
        }
    };

    // Create our Preview view and set it as the content of our activity.
    mPreview = new CameraPreview(this, mCamera);
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
    preview.addView(mPreview);
     b = (Button) findViewById(R.id.button_capture);
     b.setOnClickListener(new OnClickListener()
      {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
                 mCamera.takePicture(null, null, mPicture);
                 Toast.makeText(MainActivity.this, "Called",1000).show();

        }

      });
  }
 public static void setCameraDisplayOrientation(Activity activity,
         int cameraId, android.hardware.Camera camera) {
     android.hardware.Camera.CameraInfo info =
             new android.hardware.Camera.CameraInfo();
     android.hardware.Camera.getCameraInfo(cameraId, info);
     int rotation = activity.getWindowManager().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);
 }
private boolean checkCameraHardware(Context context) {
    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
        // this device has a camera
         Toast.makeText(this, "Phone has camera", Toast.LENGTH_LONG).show();
        return true;
    } else {
        // no camera on this device
         Toast.makeText(this, "Phone has no camera", Toast.LENGTH_LONG).show();
        return false;
    }
}
public static Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
    }
    return c; // returns null if camera is unavailable
}


@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    mCamera.release();
}
  }

CameraPreview クラスは、開発者サイトhttp://developer.android.com/guide/topics/media/camera.htmlと同じです。

注: 前面カメラではなく、背面カメラを使用しています。

4

3 に答える 3

35

ポートレートモードでカメラから写真を撮るときに同じ問題に直面しました。以下のコード行は私の問題を解決しました:

public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) {
    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    int rotation = activity.getWindowManager().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);
}

setCameraDisplayOrientation()次のように、surfaceCreated コールバックでメソッドを呼び出します。

@Override
public void surfaceCreated(SurfaceHolder holder) {
    camera = Camera.open();
    setCameraDisplayOrientation(getActivity(), CameraInfo.CAMERA_FACING_BACK, camera);
}

カメラonPictureTaken()コールバックで画像を回転させる必要がありました。

camera.takePicture(null, null, new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            if (data != null) {
                int screenWidth = getResources().getDisplayMetrics().widthPixels;
                int screenHeight = getResources().getDisplayMetrics().heightPixels;
                Bitmap bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);

                if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                    // Notice that width and height are reversed
                    Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true);
                    int w = scaled.getWidth();
                    int h = scaled.getHeight();
                    // Setting post rotate to 90
                    Matrix mtx = new Matrix();
                    mtx.postRotate(90);
                    // Rotating Bitmap
                    bm = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true);
                }else{// LANDSCAPE MODE
                    //No need to reverse width and height
                    Bitmap scaled = Bitmap.createScaledBitmap(bm, screenWidth,screenHeight , true);
                    bm=scaled;
                }
                photoPreview.setImageBitmap(bm);
            }
            isImageCaptured = true;
            photoPreview.setVisibility(View.VISIBLE);
            surfaceView.setVisibility(View.GONE);
        }
});
于 2013-06-05T13:11:27.817 に答える
1

以下のコードは、前面カメラで機能しました。

if (data != null) {
                try {
                    int screenWidth = getResources().getDisplayMetrics().widthPixels;
                    int screenHeight = getResources().getDisplayMetrics().heightPixels;
                    bm = BitmapFactory.decodeByteArray(data, 0,
                            (data != null) ? data.length : 0);
                    CameraInfo info = new CameraInfo();
                    Camera.getCameraInfo(cameraFace, info);
                    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                        // Notice that width and height are reversed
                        // Bitmap scaled = Bitmap.createScaledBitmap(bm,
                        // screenHeight, screenWidth, true);
                        // int w = scaled.getWidth();
                        // int h = scaled.getHeight();
                        // Setting post rotate to 90
                        Matrix mtx = new Matrix();
                        mtx.postRotate(90);
                        if (cameraFace == CameraInfo.CAMERA_FACING_FRONT)
                            mtx.postRotate(180);
                        // Rotating Bitmap
                        bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
                                bm.getHeight(), mtx, true);
                    } else {// LANDSCAPE MODE
                        Bitmap scaled = Bitmap.createScaledBitmap(bm,
                                screenWidth, screenHeight, true);
                        bm = scaled;
                    }
                } catch (Exception e) {
                } catch (Error e) {
                }
            }
于 2014-09-17T11:55:42.303 に答える
1

はい、私は答えの方法を試しました。それはバックカメラで機能し、フロントカメラでは90度ではなく270度回転する必要があります.:)

于 2015-07-22T07:04:16.290 に答える