如何动态创建一个SurfaceView来预览相机

// 为surfaceHolder添加一个回调监听器()

sfh.addCallback(new SurfaceHolder.Callback() {

//在surface的大小发生改变时触发

@Override

public void surfaceChanged(SurfaceHolder holder, int format,

int width, int height) {

}

//在创建时触发,一般在这里调用画图的线程。

@Override

public void surfaceCreated(SurfaceHolder holder) {

initcarm()

}

//销毁时触发,一般在这里将画图的线程停止、释放。

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

}

})

添加该段就成功了,看来new建立对象不能立刻使用,需要等待创建完事件发生后才能使用。

SurfaceView是View的子类,它内嵌了一个专门用于绘制的Surface,你可以控制这个Surface的格式和尺寸,Surfaceview控制这个Surface的绘制位置。surface是纵深排序(Z-ordered)的,说明它总在自己所在窗口的后面。SurfaceView提供了一个可见区域,只有在这个可见区域内的surface内容才可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果surface上面有透明控件,那么每次surface变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。

SurfaceView默认使用双缓冲技术的,它支持在子线程中绘制图像,这样就不会阻塞主线程了,所以它更适合于游戏的开发。

SurfaceView的使用

首先继承SurfaceView,并实现SurfaceHolder.Callback接口,实现它的三个方法:surfaceCreated,surfaceChanged,surfaceDestroyed。

surfaceCreated(SurfaceHolder holder):surface创建的时候调用,一般在该方法中启动绘图的线程。

surfaceChanged(SurfaceHolder holder, int format, int width,int height):surface尺寸发生改变的时候调用,如横竖屏切换。

surfaceDestroyed(SurfaceHolder holder) :surface被销毁的时候调用,如退出游戏画面,一般在该方法中停止绘图线程。

还需要获得SurfaceHolder,并添加回调函数,这样这三个方法才会执行。

SurfaceView实战

下面通过一个小demo来学习SurfaceView在实际项目中的使用,绘制一个精灵,该精灵有四个方向的行走动画,让精灵沿着屏幕四周不停的行走。

既然无法在父容器中拦截,那么不妨丢一个跟子 View A 大小一样的 View B 盖在上面,那么事件必然会先经过 View B。因此,在获取到 View A 的宽高之后,动态添加一把 View B,再到 View B 的 onTouchEvent 中拦截事件。

如 浅析鸿蒙原理 一文所述 ,鸿蒙中的界面是由 SurfaceView 过渡到鸿蒙自己的绘制体系的,因此可以尝试通过获取 SurfaceView 的截图,再通过对坐标的换算,即可获取到坐标点的颜色值。

下面重点阐述下获取 SurfaceView 截图的步骤和原理。

常见的获取 View 截图的方式如下所示

获取 View 截图

获取 ViewGroup 截图

但通过 SurfaceView#getDrawingCache 获取到的却是一块黑色。跟一下 View#getDrawingCache 的流程,核心的调用逻辑在 View#buildDrawingCacheImpl 中。

由上述分析可知 View#getDrawingCache 实际就是手动调了一把 View#draw,将绘制结果丢到自己创建的Bitmap 中。但是 SurfaceView#onDraw 中只是绘制一个黑色背景,其真正的绘制逻辑一般是通过如下方式:

经过一番搜索,发现 Android 有提供如下Api 去获取 SurfaceView 或 Window 的截图。

跟一下流程,核心 调用 如下所示

通过 surface.getLastQueuedBuffer拿到了最后一次入队的Buffer,即最后一次绘制的数据,并拷贝给输出的Bitmap。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/7842954.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-10
下一篇 2023-04-10

发表评论

登录后才能评论

评论列表(0条)

保存