Android 上的 OpenGL - 将位图转换为纹理,并保存纹理

Posted

技术标签:

【中文标题】Android 上的 OpenGL - 将位图转换为纹理,并保存纹理【英文标题】:OpenGL on Android - Convert a Bitmap to a Texture, and save a Texture 【发布时间】:2017-06-18 08:45:51 【问题描述】:

我和我的团队目前正在开发一款 android 应用来进行快速实时和非实时图像处理。

我们面临两个问题:

首先,我们想将 Bitmap 转换为 Texture 以使用 OpenGL 着色器处理图片,然后将其转换回 Bitmap。我们尝试了一些不成功的实现,例如在 SurfaceTexture 和 Renderer 中使用 GLUtils.texImage2D 函数。

我们的第二个问题是我们目前不知道如何在实时相机活动中保存纹理。我们使用处理图像的 OnFrameAvailableListener。但就目前而言,我们无法保留原始纹理。

我们希望有人可以为我们的问题提供答案。提前致谢 !

【问题讨论】:

【参考方案1】:

第一

位图到纹理

来源:

http://www.learnopengles.com/android-lesson-four-introducing-basic-texturing/


  public static int loadTexture(final Context context, final int resourceId)

    final int[] textureHandle = new int[1];
 
    GLES20.glGenTextures(1, textureHandle, 0);
 
    if (textureHandle[0] != 0)
    
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled = false;   // No pre-scaling
 
        // Read in the resource
        final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options);
 
        // Bind to the texture in OpenGL
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
 
        // Set filtering
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
 
        // Load the bitmap into the bound texture.
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
 
        // Recycle the bitmap, since its data has been loaded into OpenGL.
        bitmap.recycle();
    
 
    if (textureHandle[0] == 0)
    
        throw new RuntimeException("Error loading texture.");
    
 
    return textureHandle[0];

纹理到位图:

来源:

How do you convert opengl texture back to bitmap in android?

第二

我链接的 SO 链接中还有一个保存选项。

【讨论】:

【参考方案2】:

这是 Mohamed 答案的 Kotlin 版本

/**
 * Load Texture from Bitmap
 **/

fun loadTexture(context: Context, resourceId: Int) : Int 

    val textureHandle : IntArray = IntArray(1)

    GLES20.glGenTextures(1, textureHandle, 0)

    if (textureHandle[0] != 0)
    
        val options : BitmapFactory.Options = BitmapFactory.Options()
        
        options.inScaled = false   // No pre-scaling

        // Read in the resource
        
        val bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options)

        // Bind to the texture in OpenGL
        
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0])

        // Set filtering

        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST)
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST)

        // Load the bitmap into the bound texture.

        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0)

        // Recycle the bitmap, since its data has been loaded into OpenGL.

        bitmap.recycle()

    

    if (textureHandle[0] == 0) 

        throw RuntimeException("Error loading texture.")

    

    return textureHandle[0]


【讨论】:

以上是关于Android 上的 OpenGL - 将位图转换为纹理,并保存纹理的主要内容,如果未能解决你的问题,请参考以下文章

Android OpenGL 是不是具有用于绘制位图性能的离屏功能

在Android上将int数组转换为Bitmap

有没有办法直接从GLSurfaceView(OpenGL ES)创建视频文件?

如何将 android 位图转换为 NV12 颜色格式?

android opengl位图图像未使用texImage2D渲染

Android 位图线性插值混合