zoukankan      html  css  js  c++  java
  • 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()
    }
    }
  • 相关阅读:
    Nucleus 的网络部分
    VS2005中TextBox的ReadOnly属性(转贴)
    VS2005中TextBox的ReadOnly属性导致的问题
    外部中断
    Linux操作系统文件链接问题
    IIS 服务不能自动启动
    转贴:[C++]static用法
    串口测试的一些体会
    字符串的两种声明方式
    Tornado 2.2 中vxsim出问题的解决方法
  • 原文地址:https://www.cnblogs.com/yongfengnice/p/13262381.html
Copyright © 2011-2022 走看看