OpenGLES使用glReadPixels保存并旋转处理一张Bitmap图片,记录一下

1. 必须GLThread线程里调用
fun saveFrame(filename: String,  Int, height: Int) {
val startTime = System.currentTimeMillis()
//1.glReadPixels返回的是大端的RGBA Byte组数,我们使用小端Buffer接收得到ABGR Byte组数
val buffer: ByteBuffer = ByteBuffer.allocateDirect(width * height * 4).order(ByteOrder.LITTLE_ENDIAN)
GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer)
buffer.rewind()//reset position
val pixelCount = width * height
val colors = IntArray(pixelCount)
buffer.asIntBuffer().get(colors)
for (i in 0 until pixelCount) {
val c = colors[i] //2.每个int类型的c是接收到的ABGR,但bitmap需要ARGB格式,所以需要交换B和R的位置
colors[i] = c and -0xff0100 or (c and 0x00ff0000 shr 16) or (c and 0x000000ff shl 16) //交换B和R,得到ARGB
}
//上下翻转
for (y in 0 until height / 2) {
for (x in 0 until width) {
val temp: Int = colors[(height - y - 1) * width + x]
colors[(height - y - 1) * width + x] = colors[y * width + x]
colors[y * width + x] = temp
}
}
//写入文件
var fos: FileOutputStream? = null
try {
fos = FileOutputStream(filename)
val bmp = Bitmap.createBitmap(colors, width, height, Bitmap.Config.ARGB_8888)
bmp.compress(Bitmap.CompressFormat.PNG, 90, fos)
bmp.recycle()
} catch (ioe: IOException) {
throw RuntimeException("Failed to write file $filename", ioe)
} finally {
try {
fos?.close()
} catch (ioe2: IOException) {
throw RuntimeException("Failed to close file $filename", ioe2)
}
}
val endTime = System.currentTimeMillis()
Log.d(TAG, "Saved duration:" + (endTime - startTime) + "ms -> " + width + "x" + height + " frame as '" + filename + "'")
}
2.使用方法
glSurfaceView.queueEvent { //run on GLThread
val filename = Environment.getExternalStorageDirectory().absolutePath + "/fbo_${System.currentTimeMillis()}.png"
File(filename).createNewFile()
GLHelper.saveFrame(filename, glSurfaceView.width, glSurfaceView.height)
runOnUiThread {//run on UIThread
Toast.makeText(this, "保存成功", Toast.LENGTH_SHORT).show()
}
}
原文地址:https://www.cnblogs.com/yongfengnice/p/13262381.html