Android中怎么利用SurfaceView显示Camera图像

发布时间:2021-06-28 14:54:00 作者:Leah
来源:亿速云 阅读:651
# 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" />

2. 布局文件配置

<SurfaceView
    android:id="@+id/camera_preview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

3. 核心代码实现

初始化SurfaceHolder

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);
    }
}

实现SurfaceHolder.Callback

@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();
}

4. 最佳预览尺寸计算

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);
}

三、注意事项

  1. 权限处理:Android 6.0+需要运行时权限申请

    if (checkSelfPermission(Manifest.permission.CAMERA) 
       != PackageManager.PERMISSION_GRANTED) {
       requestPermissions(new String[]{Manifest.permission.CAMERA}, 100);
    }
    
  2. 方向适配:不同设备可能需要特殊处理预览方向

  3. 新API迁移:Android 5.0+建议使用Camera2 API,但SurfaceView仍适用

  4. 性能优化

    • 避免频繁修改相机参数
    • 使用TextureView替代SurfaceView可实现动画效果
    • 考虑使用SurfaceTexture进行更灵活的图像处理

四、完整示例代码

GitHub示例项目链接

通过上述实现,开发者可以构建基础的相机预览功能,后续可扩展添加拍照、滤镜等高级功能。 “`

推荐阅读:
  1. 利用Android Camera2 的照相机api 实现 实时的图像采集与预览
  2. 详解Android中SurfaceView画板操作

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

android surfaceview camera

上一篇:pomelo的配置安装教程

下一篇:SpringMVC中Model和ModelAndView的EL表达式怎么进行取值操作

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》