Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/223.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 由Grafika的存储框生成的图片是颠倒的_Android_Rotation_Grafika - Fatal编程技术网

Android 由Grafika的存储框生成的图片是颠倒的

Android 由Grafika的存储框生成的图片是颠倒的,android,rotation,grafika,Android,Rotation,Grafika,我根据连续捕获活动编写了一个演示。我想将视频的第一帧保存为jpeg文件,因此我使用了Grafika已经准备好的saveFrame()函数。该函数的源代码如下所示: 但我发现生成的jpeg图片是颠倒的。这不是我想要的 在保存帧之前,是否有方法旋转帧? 旋转位图不是一个优雅的解决方案,因为我们可能会遇到其他一些情况,例如视频聊天。视频的每一帧都被发送到远程对等方,然后远程用户将看到一个颠倒的视频。因此,我们应该在编码前旋转每一帧。如果不想旋转帧,则要翻转帧 这种情况的存在是因为位图认为(0,0)位

我根据连续捕获活动编写了一个演示。我想将视频的第一帧保存为jpeg文件,因此我使用了Grafika已经准备好的saveFrame()函数。该函数的源代码如下所示:

但我发现生成的jpeg图片是颠倒的。这不是我想要的

在保存帧之前,是否有方法旋转帧?

旋转位图不是一个优雅的解决方案,因为我们可能会遇到其他一些情况,例如视频聊天。视频的每一帧都被发送到远程对等方,然后远程用户将看到一个颠倒的视频。因此,我们应该在编码前旋转每一帧。

如果不想旋转帧,则要翻转帧

这种情况的存在是因为位图认为(0,0)位于左上角,而GLES认为(0,0)位于左下角
glReadPixels()
从顶部开始填充缓冲区,位图认为缓冲区是底部,因此最终会得到一个颠倒的图像

您有两个选择:

  • 用画笔将画框上下颠倒,然后像现在一样抓住它。代码就是这样做的——请注意,
    drawFrame()
    函数接受一个
    invert
    参数,并修改从SurfaceTexture获得的矩阵(如果已设置)
  • 按现在的方式绘制并提取帧,然后在将像素转换为位图之前翻转缓冲区中的像素。这是一个简单的移动字节的问题。这会增加一些开销,但由于JPEG压缩,速度已经有点慢了。(使用
    System.arrayCopy()
    复制整行可能比使用Java代码复制单个字节要好。)

  • 我的实现如下,速度非常快,不到10毫秒

        private void reverseBuf(ByteBuffer buf, int width, int height)
    {
        long ts = System.currentTimeMillis();
        int i = 0;
        byte[] tmp = new byte[width * 4];
        while (i++ < height / 2)
        {
            buf.get(tmp);
            System.arraycopy(buf.array(), buf.limit() - buf.position(), buf.array(), buf.position() - width * 4, width * 4);
            System.arraycopy(tmp, 0, buf.array(), buf.limit() - buf.position(), width * 4);
        }
        buf.rewind();
        Log.d(TAG, "reverseBuf took " + (System.currentTimeMillis() - ts) + "ms");
    }
    
    private void reverseebuf(字节缓冲buf,整数宽度,整数高度)
    {
    长ts=System.currentTimeMillis();
    int i=0;
    字节[]tmp=新字节[宽度*4];
    而(i++<高度/2)
    {
    buf.get(tmp);
    System.arraycopy(buf.array(),buf.limit()-buf.position(),buf.array(),buf.position()-width*4,width*4);
    System.arraycopy(tmp,0,buf.array(),buf.limit()-buf.position(),width*4);
    }
    buf.倒带();
    Log.d(标记“reverseBuf take”+(System.currentTimeMillis()-ts)+“ms”);
    }
    
    我选择了选项2,因为第一帧也将被编码到视频流中。我不希望视频中的第一帧倒置。你把它放在哪里?我假设你在调用mMuxer之前使用它。writeSampleData。。。你知道有没有办法将直接字节缓冲反转?我使用这种方法将视频帧捕获到jpg。对于视频编码,我们应该处理每一帧,这种方法太慢了。我们应该使用GPU。GPU的方法是使用旋转矩阵将帧渲染到新fbo,以便新fbo中的图像具有正确的方向。然后我们将图像读取到内存中,并将其提供给h264编码器。