
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
如果是 Android 6.0 以上的平台还必须在代码中动态请求权限。
2、通过 mCamera = Camera.open(int cameraId) 获得相机实例,cameraId 可以在 0 和 mCamera.getNumberOfCameras() – 1 之间选取,代表前后。
3、如果必须设置相机的一些参数,可以借助 mCamera.getParameters() 获取至相机的参数,并且设置后通过 mCamera.setParameters(Camera.Parameters) 修改。
4、通过 mCamera.setDisplayOrientation(int) 修改展示的翻转视角,如果是竖屏参数为 90 才是正常的预览画面。

5、初始化一个 SurfaceHolder,然后通过 mCamera.setPreviewDisplay(SurfaceHolder) 设置预览的 surface,具体将在上面章节介绍。
6、通过 mCamera.startPreview() 即可开始预览捕获的场景了。
我们可以通过 takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback) 进行拍照并保存,在 Activity 不可见的之后(即对应生命周期的 onPause() 回调)需要对 Camera 进行释放,调用 ,mCamera.release() 方法即可。
SurfaceView 是一个继承于 View 的类,而不同于 View 的是 SurfaceView 会进入一个子线程来刷新页面,经常被用于的渲染,并在底层实现了双缓冲模式。
将相机预览放到 SurfaceView 需要下面步骤:

1、创建一个 SurfaceView,并且实现 SurfaceHolder.Callback 接收 surface 的改变,其中包含 SurfaceView 创建 – surfaceCreated、改变 – surfaceChanged、销毁 -surfaceDestroyed。
2、获取 SurfaceHolder,SurfaceHolder 是 surface 的控制,可控制其大小、格式等,可以通过 mSurfaceView.getHolder() 取得。
3、将 Camera 的预览更改到此 SurfaceView 的 SurfaceHolder 中,通过 mCamera.setPreviewDisplay(mHolder) 设置。
4、相机进入预览:mCamera.startPreview();
此时即可在此 SurfaceView 中发现手机的预览画面了。参考代码:

public class SurfaceViewActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private final static String TAG = "SurfaceViewActivity";
private Camera mCamera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_surface_view);
SurfaceView surfaceView = findViewById(R.id.surface_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
if (Camera.getNumberOfCameras() > 0) {
mCamera = Camera.open(0);
} else {
Log.i(TAG, "Error");
}
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
if (mCamera != null && surfaceHolder != null) {
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
// 当 Surface 改变时调用
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
// 当 Surface 销毁时调用
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
}
}
}
TextureView 必须在硬件加速开启的窗口中使用获取surfaceview大小,不支持硬件加速的设备 TextureView 将不会显示任何东西,用于显示内容流,可以是视频流或是 OpenGL 场景。在使用中最大的不同就是 TextureView 可以改变 View 的大小,不象 SurfaceView 单独建立一个窗口。
将相机预览放到 TextureView 中的话,我们应该 setSurfaceTextureListener() TextureView 的变化,实例代码如下:
public class TextureViewActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener {
private static final String TAG = "TextureViewActivity";
private Camera mCamera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_texture_view);
TextureView textureView = findViewById(R.id.texture_view);
textureView.setSurfaceTextureListener(this);
if (Camera.getNumberOfCameras() > 0) {
mCamera = Camera.open(0);
} else {
Log.i(TAG, "Error");
}
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
try {
mCamera.setPreviewTexture(surfaceTexture);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {
// 大小改变
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
}
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
// Texture 刷新
}
}
如果必须获得 NV21 的回调,在 Camera 在 release 之前设置 PreviewCallback 即可获取surfaceview大小,比如:

mCamera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] bytes, Camera camera) {
}
});
其中 bytes 即为 NV21 数据。
Android 官方 Camera 文档
Android 官方 SurfaceView 文档
Android API 指南 — Camera API
Android 官方 TextureView 文档
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-131240-1.html
我更新后下载App无法下载
您好
只要去关注就可以了