GLES20 从图像文件的字节数组中绘制纹理
GLES20 draw texture from image file's byte array
我正在尝试使用 opengl 从图像文件字节中绘制纹理:
//Read bytes from image URI
@Throws(IOException::class)
private fun Uri.readBytes(): ByteArray? =
context.contentResolver.openInputStream(this)?.buffered()?.use { it.readBytes() }
//Create ByteBuffer for OpenGL
val pixels = ByteBuffer.wrap(data).flip()
glTextureId = OpenGlUtils.loadTexture(pixels, width, height, glTextureId)
//Trying to draw texture
fun loadTexture(data: ByteBuffer, width: Int, height: Int, usedTexId: Int): Int {
val textures = IntArray(1)
GLES20.glGenTextures(1, textures, 0)
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0])
GLES20.glTexParameterf(
GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR.toFloat()
)
GLES20.glTexParameterf(
GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR.toFloat()
)
GLES20.glTexParameterf(
GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE.toFloat()
)
GLES20.glTexParameterf(
GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE.toFloat()
)
GLES20.glTexImage2D(
GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height,
0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, data
)
}
但结果是这样的
result
如果我更改最后一行,将使用文件字节数组从位图中绘制图片,如下所示:
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size), 0)
它显示正确的图像,但它工作得太慢(我需要每 100 毫秒绘制 2mb 纹理,并且纹理变化看起来很滞后),这就是为什么这种方式不适合我
我找到了解决方案。据我了解,位图按原始图像大小(宽度 * 高度 * 4(对于 ARGB))分配用于解码的字节,并调整自身大小以适合纹理。
所以我实现了 TurboJpeg 库,现在我将 jpeg 解码为正确的大小,将输出字节放入 ByteBuffer,并显示从此缓冲区创建的纹理。现在它几乎可以立即绘制纹理
我正在尝试使用 opengl 从图像文件字节中绘制纹理:
//Read bytes from image URI
@Throws(IOException::class)
private fun Uri.readBytes(): ByteArray? =
context.contentResolver.openInputStream(this)?.buffered()?.use { it.readBytes() }
//Create ByteBuffer for OpenGL
val pixels = ByteBuffer.wrap(data).flip()
glTextureId = OpenGlUtils.loadTexture(pixels, width, height, glTextureId)
//Trying to draw texture
fun loadTexture(data: ByteBuffer, width: Int, height: Int, usedTexId: Int): Int {
val textures = IntArray(1)
GLES20.glGenTextures(1, textures, 0)
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0])
GLES20.glTexParameterf(
GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR.toFloat()
)
GLES20.glTexParameterf(
GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR.toFloat()
)
GLES20.glTexParameterf(
GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE.toFloat()
)
GLES20.glTexParameterf(
GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE.toFloat()
)
GLES20.glTexImage2D(
GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height,
0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, data
)
}
但结果是这样的 result
如果我更改最后一行,将使用文件字节数组从位图中绘制图片,如下所示:
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size), 0)
它显示正确的图像,但它工作得太慢(我需要每 100 毫秒绘制 2mb 纹理,并且纹理变化看起来很滞后),这就是为什么这种方式不适合我
我找到了解决方案。据我了解,位图按原始图像大小(宽度 * 高度 * 4(对于 ARGB))分配用于解码的字节,并调整自身大小以适合纹理。 所以我实现了 TurboJpeg 库,现在我将 jpeg 解码为正确的大小,将输出字节放入 ByteBuffer,并显示从此缓冲区创建的纹理。现在它几乎可以立即绘制纹理