在Android中由相机拍摄的旋转照片

时间:2012-08-05 21:08:00

标签: android camera rotation

我正在尝试使用前置摄像头拍照但没有UI的应用程序我已成功做到这一点但唯一的问题是图片总是以横向模式拍摄,有没有办法强迫它到肖像模式?

public class TakePicture extends Activity implements SurfaceHolder.Callback
{
    private ImageView iv_image;
    private SurfaceView sv;

    private Bitmap bmp;

    private SurfaceHolder sHolder;  
    private Camera mCamera;
    private int cameraId = 1;
    private Parameters parameters;

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        iv_image = (ImageView) findViewById(R.id.imageView);
        sv = (SurfaceView) findViewById(R.id.surfaceView);        
        sHolder = sv.getHolder();

        sHolder.addCallback(this);

        sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    }


    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) 
    {
parameters = mCamera.getParameters();
         mCamera.setParameters(parameters);
         mCamera.startPreview();



         //mCamera.setDisplayOrientation(90);
         //sets what code should be executed after the picture is taken
         Camera.PictureCallback mCall = new Camera.PictureCallback() 
         {
                public void onPictureTaken(byte[] data, Camera camera) {

                    File pictureFileDir = getDir();

                    if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {

                        Log.d("DEBUG", "Can't create directory to save image.");
                        Toast.makeText(TakePicture.this, "Can't create directory to save image.",
                                Toast.LENGTH_LONG).show();
                        return;

                    }

                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
                    String date = dateFormat.format(new Date());
                    String photoFile = "Picture_" + date + ".jpg";

                    String filename = pictureFileDir.getPath() + File.separator + photoFile;

                    File pictureFile = new File(filename);

                    try {
                        FileOutputStream fos = new FileOutputStream(pictureFile);
                        fos.write(data);
                        fos.close();
                        Toast.makeText(TakePicture.this, "New Image saved:" + photoFile,
                                Toast.LENGTH_LONG).show();
                        finish();
                    } catch (Exception error) {
                        Log.d("DEBUG", "File" + filename + "not saved: "
                                + error.getMessage());
                        Toast.makeText(TakePicture.this, "Image could not be saved.",
                                Toast.LENGTH_LONG).show();
                    }
                }
         };

         mCamera.takePicture(null, null, mCall);

    }


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

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

    public void surfaceDestroyed(SurfaceHolder holder) 
    {
        //stop the preview
        mCamera.stopPreview();
        //release the camera
        mCamera.release();
        //unbind the camera from this object
        mCamera = null;
    }  


    private File getDir() {
        File sdDir = Environment
          .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        return new File(sdDir, "Camera!");
    }
}

1 个答案:

答案 0 :(得分:0)

据我记得在尝试这样做时,这有点棘手。

我找到的一种方法是:

public void surfaceCreated(SurfaceHolder holder) {
    mCamera = Camera.open();

    Parameters params = mCamera.getParameters();
    if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
        params.set("orientation", "portrait");


        try {
            //not sure if this block of code had an OR relationship with the previous line params.set("orientation", "portrait");
            Method rotateSet = Camera.Parameters.class.getMethod("setRotation", new Class[] { Integer.TYPE });
            Object arguments[] = new Object[] { new Integer(90) };
            rotateSet.invoke(params, arguments);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    mCamera.setParameters(params);

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

但它对我不起作用(虽然我使用的Android版本高于2.0,但这应该可行)。

我还发现了一个使用反射的黑客,并且有效:

public void surfaceCreated(SurfaceHolder holder) {
    mCamera = Camera.open();

    if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {}
    setDisplayOrientation(mCamera, 90);

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

setDisplayOrientation是:

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

    } catch (Exception e1) {}
}