您的位置:首页 > 移动开发 > Android开发

Android 系列 5.6使用android.media.Camera拍照

2017-01-10 09:26 295 查看
5.6使用android.media.Camera拍照

问题

您想要在拍摄照片时对所涉及的各个阶段有更多的控制。



创建SurfaceView并实现当用户拍摄照片时触发的回调,以便控制图像捕获进程。

讨论

有时,您可能希望在拍摄照片时对所涉及的阶段进行更多的控制,或者您可能想要访问和修改相机获取的原始图像数据。在这些情况下,使用简单的Intent来拍照是不够的。

我们将创建一个新的Activity并自定义视图,使其在onCreate方法中全屏显示(示例5-11)。

实施例5-11。拍照活动

Preview类是配方的主体。它处理绘制像素的Surface和Camera对象。

我们在构造函数中定义一个ClickListener,以便用户可以通过在屏幕上点击一次来拍摄照片。一旦我们收到点击的通知,我们拍摄一张图片,作为参数传递四(所有可选)回调(参见示例5-12)。

实例5-12。 SurfaceView实现
class Preview extends SurfaceView implements SurfaceHolder.Callback, PictureCallback {
private SurfaceHolder mHolder;
private Camera mCamera;
private RawCallback mRawCallback;
public Preview(Context context) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mRawCallback = new RawCallback();
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mCamera.takePicture(mRawCallback, mRawCallback, null,
Preview.this);
}
});
}


Preview类实现了SurfaceHolder.Callback接口,以便在创建,更改和销毁基础表面时获得通知。我们将使用这些回调来正确处理Camera对象(参见示例5-13)。

实例5-13。 surfaceChanged()方法
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(width, height);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
configure(mCamera);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
closeCamera();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
closeCamera();
}


一旦相机被创建,我们调用配置为了设置相机将使用拍摄图片的参数 - 例如闪光模式,效果,图片格式,图片大小,场景模式等(例5-14)。由于并非所有设备都支持各种功能,因此在设置前,请先询问支持哪些功能。

实例5-14。 configure()方法
private void configure(Camera camera) {
Camera.Parameters params = camera.getParameters();
// Configure image format. RGB_565 is the most common format.
List<Integer> formats = params.getSupportedPictureFormats();
if (formats.contains(PixelFormat.RGB_565))
params.setPictureFormat(PixelFormat.RGB_565);
else
params.setPictureFormat(PixelFormat.JPEG);
// Choose the biggest picture size supported by the hardware
List<Size> sizes = params.getSupportedPictureSizes();
Camera.Size size = sizes.get(sizes.size()-1);
params.setPictureSize(size.width, size.height);
List<String> flashModes = params.getSupportedFlashModes();
if (flashModes.size() > 0)
params.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
// Action mode takes pictures of fast moving objects
List<String> sceneModes = params.getSupportedSceneModes();
if (sceneModes.contains(Camera.Parameters.SCENE_MODE_ACTION))
params.setSceneMode(Camera.Parameters.SCENE_MODE_ACTION);
else
params.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);
// if you choose FOCUS_MODE_AUTO remember to call autoFocus() on
// the Camera object before taking a picture
params.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);
camera.setParameters(params);
}


当表面被破坏,我们关闭相机,释放其资源:
private void closeCamera() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}


jpeg回调是最后一个调用;这是我们重新启动预览并将文件保存在磁盘上的位置。
@Override
public void onPictureTaken(byte[] jpeg, Camera camera) {
// now that all the callbacks have been called it is safe to resume preview
mCamera.startPreview();
saveFile(jpeg);
}
}


最后,我们实现ShutterCallback,我们再次实现

PictureCallback接收未压缩的原始图像数据(参见示例5-15)。
实例5-15。 ShutterCallback实现

class RawCallback implements ShutterCallback, PictureCallback {
@Override
public void onShutter() {
// notify the user, normally with a sound, that the picture has
// been taken
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// manipulate uncompressed image data
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐