1

我正在尝试做一个应用程序,用前置摄像头在没有 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!");
    }
}
4

1 回答 1

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

但这对我不起作用(尽管我使用的是高于 2.0 的 Android 版本,这应该可以工作)。

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

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) {}
}
于 2012-08-05T21:22:19.960 回答