您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Android中怎么利用SurfaceView显示Camera图像
## 一、SurfaceView与Camera概述
在Android应用开发中,实时显示摄像头图像是常见需求。`SurfaceView`作为专门用于高效绘制动态内容的视图组件,配合`Camera` API可以实现这一功能。其核心优势在于:
1. **独立绘制线程**:SurfaceView拥有独立的Surface,可在非UI线程渲染
2. **双缓冲机制**:减少画面闪烁
3. **硬件加速支持**:适合视频/3D等高性能场景
## 二、实现步骤详解
### 1. 添加权限和特性声明
```xml
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<!-- 适配Android 9+ -->
<uses-permission android:name="android.permission.RECORD_AUDIO"
android:required="false" />
<SurfaceView
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
public class CameraActivity extends AppCompatActivity
implements SurfaceHolder.Callback {
private Camera mCamera;
private SurfaceView mSurfaceView;
private SurfaceHolder mHolder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
mSurfaceView = findViewById(R.id.camera_preview);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
// 设置Surface类型
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
// 打开后置摄像头
mCamera = Camera.open();
// 设置预览方向(解决画面旋转问题)
mCamera.setDisplayOrientation(90);
// 绑定SurfaceView
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.e("Camera", "Error setting preview: " + e.getMessage());
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// Surface尺寸变化时重新设置参数
if (mHolder.getSurface() == null) return;
try {
mCamera.stopPreview();
Camera.Parameters params = mCamera.getParameters();
// 设置预览尺寸(需选择设备支持的尺寸)
List<Camera.Size> sizes = params.getSupportedPreviewSizes();
Camera.Size optimalSize = getOptimalSize(sizes, width, height);
params.setPreviewSize(optimalSize.width, optimalSize.height);
mCamera.setParameters(params);
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.e("Camera", "Error restarting preview: " + e.getMessage());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
releaseCamera();
}
private void releaseCamera() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
@Override
protected void onPause() {
super.onPause();
releaseCamera();
}
private Camera.Size getOptimalSize(List<Camera.Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) h / w;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
double diff = Math.abs(size.height - h) + Math.abs(size.width - w);
if (diff < minDiff) {
optimalSize = size;
minDiff = diff;
}
}
return optimalSize != null ? optimalSize : sizes.get(sizes.size() - 1);
}
权限处理:Android 6.0+需要运行时权限申请
if (checkSelfPermission(Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, 100);
}
方向适配:不同设备可能需要特殊处理预览方向
新API迁移:Android 5.0+建议使用Camera2
API,但SurfaceView仍适用
性能优化:
TextureView
替代SurfaceView
可实现动画效果SurfaceTexture
进行更灵活的图像处理通过上述实现,开发者可以构建基础的相机预览功能,后续可扩展添加拍照、滤镜等高级功能。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。