工作中遇到需要自定义拍照的需求,然后就碰到预览时图像变形的问题,从网络上找到一些参考,综合一下解决了问题,记录一下。顺便希望有人可以一起讨论一下系统拍照程序的实现。我不知道源码里面是怎么实现的,因为下载的源码一直没看,甚至编译不出镜像文件。每天工作十几个小时,暂时实在没精力继续下去,而且老罗列出的读Android源码前需要看的书也没看完。终于有点时间整理下工作中遇到的问题,希望可以跟大家交流下。顺便说一下,有目的的学习似乎是我尝试过的所有学习方法中最有效率的一种。以下是正文。
Android提供了调用系统相机的API,借此我们可以实现自己的拍照程序,实现过程中遇到很多问题,下面是几个主要的问题:
1.预览的时候图像变形;
2.拍照结束后图片变形;
3.拍照结束后图片被旋转。
遇到这些问题与需求也有关系,我的需求是要控制拍照得到的图片的大小不超过800*800,预览窗口要全屏。
由于Android设备的硬件配置繁多,要适应大多数设备比较难。为了实现全屏,开始的时候就导致了预览窗口变形;等全屏预览实现后,发现某些设备上拍完的照片又变形了;接着又是发现横屏拍完后图片被旋转了90度……
我实现的方式是使用SurfaceView作为预览的控件,得到相机支持的预览窗口尺寸并改变SurfaceView的width和height达到全屏的效果;得到相机支持的图片尺寸并结合对图片尺寸的要求确定最终拍照得到的尺寸;最后使用了Sensor判断拍照时相机旋转的角度用来修正最终拍到的照片的显示效果。下面是程序中的一些关键代码和注释,只有大部分代码,可运行的Demo有空整理完再放上来。所以,下面的代码是不能运行的!
public class DemoActivity extends Activity implements Callback,
OnClickListener, PictureCallback, AutoFocusCallback {
private static final String TAG = "DemoPickActivity";
private static final int MAXIMUM_SIZE = xxx;// 需求里允许照片的最大尺寸
private SensorManager mSensorManager = null;
private RotationSensorListener mRotationSensorListener = null;
private Sensor mSensor = null;
private Camera mCamera = null;
private SurfaceView mSurfaceView = null;// 用来作为预览窗口的控件
private SurfaceHolder mSurfaceHolder = null;
private String focusMode = Camera.Parameters.FOCUS_MODE_FIXED;// 设备支持的默认对焦模式
private boolean previewMode = true;// 状态标志量,标示当前状态是否是预览状态
private float angle = 0;// 设备旋转角度,以竖屏方向作为起始的0度
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
// 初始化
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSen