在遍历完所有支持的大小之后,必须确保获得了所需要的值。如果bestHeight和bestWidth变量等于0,那么没有发现任何与我们的需要相匹配的大小,或者只存在一种支持的大小,从而不应采取任何操作。反之,如果它们有值,那么将使用bestWidth和bestHeight变量调用Camera.Parameters对象上的setPreviewSize方法。
另外,还需要告诉摄像头预览SurfaceView对象(即cameraView)以该大小进行显示。如果不这么做,那么SurfaceView不会改变大小,且来自摄像头的预览图像会扭曲或质量非常低。
要采用Camera类捕获图像,必须调用takePicture方法。该方法接受3个或4个参数,所有这些参数都是回调方法。takePicture方法的最简单形式是将所有的参数都设置为null。尽管能够捕获照片,但是不能获得它的引用。因此,至少应该实现一种回调方法。一种最安全的回调方法是Camera.PictureCallback.onPictureTaken。它确保会被调用,并且在压缩图像时被调用。为了利用该方法,我们将在活动中实现Camera.PictureCallback,并添加一个onPictureTaken方法。
public class SnapShot extends Activity implements
SurfaceHolder.Callback, Camera.PictureCallback {
public void onPictureTaken(byte[] data, Camera camera) {
}
该onPictureTaken方法有两个参数:第一个是实际的JPEG图像数据的字节数组,第二个是捕获该图像的Camera对象的引用。
由于给定了实际的JPEG数据,因此为了保存它,只需要将其写入磁盘的某个位置。正如我们已经知道的那样,可以利用MediaStore指定它的位置和元数据。
当执行onPictureTaken方法时,可以调用Camera对象上的startPreview。当调用takePicture方法时预览已经自动暂停,并且这个方法会告诉我们,现在可以安全地重新启动它。
public void onPictureTaken(byte[] data, Camera camera) {
Uri imageFileUri = getContentResolver().insert(Media.EXTERNAL_
CONTENT_URI, new ContentValues());
try {
OutputStream imageFileOS = getContentResolver().
openOutputStream(imageFileUri);
imageFileOS.write(data);
imageFileOS.flush();
imageFileOS.close();
}catch (FileNotFoundException e) {
} catch (IOException e) {
}
camera.startPreview();
}