- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
最近遇到一个需求,要求将一个GL_TEXTURE_2D类型的纹理ID写入到ImageReader生成的Surface中。 其实这个需求与我之前写过的一篇文章 一文学会MediaCodeC与OpenGL录制mp4视频 需求比较接近,只需要对该案例源码进行一些改造即可.
在正式介绍实现之前,需先明确:
android.view.Surface
? Surface
中写入数据? 什么是 android.view.Surface ?
android.view.Surface
是 Android 系统中一个重要的图形渲染类,它用于与硬件显示层进行通信,将图形数据渲染到屏幕上,可以用于实现多种功能,如视频播放、相机预览、屏幕录制等。 Surface
对象代表了一个画布,可以在其上绘制图形,这些图形将通过硬件显示层呈现在屏幕上。可以在 SurfaceView
、 TextureView
、 WindowManager
等控件中使用 Surface
进行图形渲染。此外, Surface
还可以用于视频播放、相机预览、屏幕录制等功能。 Surface是一个Java层类,其持有一个Native (C层) 管理的图像缓冲区句柄。由图像缓冲区的消费者创建(如MediaRecorder),通过Surface将句柄传递给图像的生产者 (如MediaPlayer) 进行渲染。
关于 android.view.Surface 官方描述如下:
翻译过来就是:
Surface 持有一个由屏幕合成器管理(Native层管理)的 原始缓冲区的句柄 。通常是由 图像缓冲区的消费者 (如 SurfaceTexture、MediaRecorder、Allocation等)创建或生成,并被 传递给生产者 (如 OpenGL、MediaPlayer、CameraDevice等)进行绘制。 因为, Surface 只是持有Native层缓冲区的句柄,若Native层的指针被释放后,则该 Surface 不再有效.
查看 Surface 源码,可以看到 Surface 通过持有Native层的句柄 mNativeObject 来管理原始数据缓冲区.
查看 Surface 官方文档,查看其所有的公有方法:
看到上述公有方法后,发现除了通过 lockCanvas() 方法可以获取一个 Canvas 对象,然后使用 drawBitmap() 等API写入图形数据外,并无其他有用的方法,帮助我们实现 TextureID 纹理ID的写入.
要向 Surface 持有的 mNativeObject 句柄中写入图像数据,我现在已知有两种方式:
Canvas
写入; OpenGL
写入,也就是本文的要介绍的重点; 上文介绍到,在查看 Surface 的公有方法后,发现通过 lockCanvas() 方法可以获取一个 Canvas 对象,然后使用 drawBitmap() 等API写入图形数据,操作步骤如下:
SurfaceHolder
获取 Surface
对象; Surface
对象的 lockCanvas()
方法获取 Canvas
对象; Canvas
上进行绘制操作,例如调用 drawBitmap()
方法绘制位图; Canvas
对象的 unlockCanvasAndPost()
方法将绘制结果提交到 Surface
中,从而实现在屏幕上渲染数据。 以下为简单的代码举例:
SurfaceHolder holder = surfaceView.getHolder();
Surface surface = holder.getSurface();
Canvas canvas = surface.lockCanvas(null);
// 在 canvas 上进行绘制操作
canvas.drawBitmap(bitmap, 0, 0, null);
surface.unlockCanvasAndPost(canvas);
通过OpenGL向Surface中写入数据,其根本原理是:
将Surface绑定到一个EGLSurface上,然后通过OpenGL向EGLSurface渲染数据,最终将结果渲染到关联的Surface上。 具体实现是使用 EGL 提供的 eglCreateWindowSurface() 函数,将 EGLSurface 与 Surface 对象关联起来。然后就可以通过 OpenGL ES 将渲染结果绘制到 EGLSurface 中,最终渲染到Surface上.
其代码实现举例如下所示:
// 获取 EGLDisplay 对象
EGLDisplay mEglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
// 初始化 EGL 环境
int[] version = new int[2];
EGL14.eglInitialize(mEglDisplay, version, 0, version, 1)
// 配置 attribList
int[] attribList = {
EGL14.EGL_RED_SIZE, 8,
EGL14.EGL_GREEN_SIZE, 8,
EGL14.EGL_BLUE_SIZE, 8,
EGL14.EGL_ALPHA_SIZE, 8,
//
EGL14.EGL_RENDERABLE_TYPE,
EGL14.EGL_OPENGL_ES2_BIT,
0x3142,
1,
EGL14.EGL_NONE
};
EGLConfig[] configs = new EGLConfig[1];
int[] numConfigs = new int[1];
EGL14.eglChooseConfig(mEglDisplay, attribList, 0, configs, 0, configs.length, numConfigs, 0);
// 获取 EGLContext 上下文
EGLContext shareEglContext = inEglContext;
// 配置 EGLContext 属性
final int[] attrib_list = {
EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
EGL14.EGL_NONE
};
// 获取 EGLDisplay 对象
EGLDisplay eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
// 创建一个 EGLSurface 对象(绑定surface)
EGLSurface eglSurface = EGL14.eglCreateWindowSurface(eglDisplay, configs[0], surface, surfaceAttribs, 0);
// 将 EGLSurface 和 EGLContext 绑定到 EGLDisplay 上
EGL14.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
// 渲染图形 ...
// 交换前后缓冲(将egl渲染结果交换到surface上)
EGL14.eglSwapBuffers(eglDisplay, eglSurface);
将一个GL_TEXTURE_2D类型的纹理ID写入到ImageReader生成的Surface中, 源码案例工程下载地址如下: https://download.csdn.net/download/aiwusheng/87959680 。
案例代码实现流程流程如下:
案例源码效果图如下图所示:
最后此篇关于一文学会TextureID渲染到Surface的文章就讲到这里了,如果你想了解更多关于一文学会TextureID渲染到Surface的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
Surface Go是一款微软推出笔记本电脑,但不少小伙伴在使用一段时间之后总会想重装系统从而使电脑更加流畅,那么Surface Go要如何重装Win10系统,下面就和小编一起来看看如何操作吧。
在我的第二个项目中,我使用 opengl 和 SDL2。我想使用 SDL2 将文本渲染到表面,然后进行转换。 我已经在使用 SDL 从文件中加载纹理,所以我有一个可以转换曲面的函数。当我提供由 TTF
我最近更改了表面对象算法的表面引用。然后,我注意到程序运行速度变慢了。 这是一个简单示例的比较,其中我用常量值填充 3D float 数组 [400*400*400]。 表面引用API 时间:9.06
有时,当我退出我的 openGL ES 1 应用程序时,以下错误消息会不断张贴在 logcat 中,应用程序会卡住,并在某个时候终止。 E/EglHelper(4284): Surface is no
这可能是一个愚蠢的问题,但我无法在任何地方找到答案。 Microsoft Surface SDK 2.0 是否仅适用于 Microsoft Surface 产品,还是我可以将其用于其他触摸屏?我真的很
我已经将 camera2 与 textureVIew 集成在一起。它适用于所有设备,但在平板电脑上,当我们第一次捕获图像时,它会崩溃并显示以下日志。 Fatal Exception: java.la
在我正在处理的一个 pygame 项目中,角色和对象的 Sprite 会在地形上转换阴影。阴影和地形都是正常的 pygame 表面,因此,为了显示它们,阴影被 blit 到地形上。当没有其他阴影(只有
在 pygame 中将我的表面涂成黑色之后。我得到错误 pygame.error: display Surface quit. 完整错误: > D:\Programme\Anaconda3\envs\
有谁知道如何用Julia的Pyplot绘制3D曲面,例如 作为面部颜色的表面渐变? 类似于此主题适用于Python:Color matplotlib plot_surface command with
我一直在尝试将 Camera2 api 集成到我的应用程序中。它一开始捕捉图像时工作正常。但是当我第二次拍摄时,预览没有出现。我在 genymotion nexus 5 模拟器中测试了它。尝试了所有示
阅读 pygame 教程 here ,你会发现这个例子:(箭头是我的) for o in objects: screen.blit(background, o.pos, o.pos) # Re
我正在创建两个渲染目标,两者都必须共享后台缓冲区的深度缓冲区,因此我将它们设置为具有相同的多重采样参数很重要,但是 pDevice->CreateTexture(..) 没有给出任何参数设置多重采样类
我正在尝试在屏幕上对文本表面进行 blit,但出现此错误: 类型错误:参数 1 必须是 pygame.Surface,而不是元组。 可能有什么问题?我确信我的文字是一个表面。 import pygam
Joel Spolsky 在 SO 播客中提到了“浮出水面”。 这是什么意思?它是类似于“暴露”的东西吗,比如“暴露接口(interface)”? 最佳答案 这里引用自 podcast 51 的文字记
下面给了我错误 var textSurface = new Surface({ content: 'Some text here', properties:{ color: 'whit
我是一个小机器人,但有一项艰巨的任务要做。我的布局上有一个图像按钮。单击它应该开始显示 camera preview 。 (我有一个视频同时显示在另一个表面上。)两者都很好。 但是当再次按下按钮时,预
我试图每 5 秒画一个红色圆圈。我有一个 draw 和一个 run 方法,run 方法调用绘制圆圈的 draw 方法。但是,当从 run 方法调用 draw 方法时,表面无效,所以我无法绘制任何东西并
我想知道 Surfaceflinger 是否知道当前屏幕上的可点击区域,或者 SurfaceFlinger 只显示最终屏幕,它对可点击区域一无所知,并且 windowmanagerservice 将输
所以这段代码似乎是问题所在: public void surfaceCreated(final SurfaceHolder sh) { loop = new Loop(); loop.
Opengl 纹理坐标 [0,0] 位于左下角。 DDS 文件是否包含有关数据布局的信息(如果数据从左上角或左下角开始)或有一个固定的布局?例如 ktx 文件包含此类信息。 最佳答案 DDS 文件格式
我是一名优秀的程序员,十分优秀!