android中的surfaceview与surfacetexture

本文探讨了SurfaceView和SurfaceTexture中颜色设置的区别及影响。指出在SurfaceView上可以设置多个SurfaceTexture的颜色,并强调了视频播放应用应采用SurfaceTexture默认设置而非SurfaceView设置的重要性。

surfaceview上会有很多个surfacetexture,各个surfacetexture可以设置各个texture的颜色。

视频播放时,视频画面对应的是一个texture。

修改core/java/android/view/SurfaceView.java中的颜色格式设置,会影响到所有的surfaceview,除了用skia绘制的surfaceview,比如桌面,图片的显示

因此应用,如一个网络视频的apk,最好是使用surfacetexture的的默认设置,而不是surfaceview的。

### 使用 `SurfaceView` 和 `SurfaceTexture` 进行视频渲染或摄像头预览 #### SurfaceViewSurfaceTexture关系概述 `SurfaceView` 是 Android 中用于显示多媒体内容的一个视图组件,它允许应用程序创建独立的窗口层来处理图形绘制操作。而 `SurfaceTexture` 则是自 Android 3.0 (API level 11) 起引入的一种特殊类型的 OpenGL ES 纹理对象,它可以接收来自相机或其他图像源的数据流并将其转换成纹理供 GPU 处理[^3]。 两者之间的主要区别在于: - **合成方式**: 当使用 `SurfaceView` 显示内容时,其背后的内容是由硬件合成器(即 SurfaceFlinger)负责管理并其它应用界面元素一起组成最终的画面输出给屏幕;相比之下,当采用 `SurfaceTexture` 结合 `TextureView` 或者其他支持该特性的控件展示画面时,这些内容会先被传递至 GPU 并通过 OpenGL ES 渲染管线完成进一步加工后再参整体 UI 绘制过程。 - **性能表现**: 如前所述,由于 `SurfaceView` 可以让媒体播放等任务绕过常规的应用程序绘图流程直接交给底层系统去执行,所以在某些情况下能够获得更好的性能优势特别是对于复杂场景下的实时性要求较高的场合而言更为明显。 #### 实现基于SurfaceViewSurfaceTexture的摄像机预览功能 下面给出一段简单的 Java 代码片段用来说明如何利用上述两个类实现基本的摄相头预览效果: ```java // 创建Camera实例 private Camera camera; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获取SurfaceView引用 final SurfaceView surfaceView = findViewById(R.id.surface_view); final SurfaceHolder holder = surfaceView.getHolder(); holder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { try{ if(camera==null){ camera=Camera.open(); // 打开默认后置摄像头 } // 设置预览参数 Camera.Parameters parameters=camera.getParameters(); List<Size> previewSizes=parameters.getSupportedPreviewSizes(); Size optimalSize=getOptimalPreviewSize(previewSizes,holder.getSize().getWidth(),holder.getSize().getHeight()); parameters.setPreviewSize(optimalSize.width,optimalSize.height); camera.setParameters(parameters); // 将surface设置为camera预览目标 camera.setPreviewDisplay(holder); // 开始预览 camera.startPreview(); // 如果想要获取原始帧数据还可以注册callback监听 /* * camera.setPreviewCallback(new Camera.PreviewCallback(){ * @Override * public void onPreviewFrame(byte[] data,Camera camera){} * }); */ }catch(IOException e){ Log.e("MainActivity","Error setting up the camera",e); } } private Size getOptimalPreviewSize(List<Size> sizes,int w,int h){...}//省略具体算法 ... }); } @Override protected void onDestroy(){ super.onDestroy(); if(this.camera!=null){ this.camera.stopPreview(); this.camera.release(); this.camera=null; } } ``` 这段代码展示了怎样打开设备上的照相机并将捕捉到的画面呈现在界面上指定位置处所放置好的 `SurfaceView` 上面。需要注意的是这里并没有涉及到任何关于 `SurfaceTexture` 的部分——这是因为如果希望借助后者来进行更高级别的定制化开发工作的话,则需要额外构建一个继承自 `GLSurfaceView.Renderer` 接口的对象,并在里面定义好相应的着色器脚本以及顶点坐标数组等内容之后再调用 `setRenderer()` 方法传入即可[^2]。 另外值得注意的一点就是,在实际项目当中为了兼容更多版本号较低的操作系统环境建议优先考虑选用官方推荐的新一代 API —— 即 `android.hardware.Camera2` 替代旧版接口(`android.hardware.Camera`)进行编程实践。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值