Android 由Grafika的存储框生成的图片是颠倒的
我根据连续捕获活动编写了一个演示。我想将视频的第一帧保存为jpeg文件,因此我使用了Grafika已经准备好的saveFrame()函数。该函数的源代码如下所示: 但我发现生成的jpeg图片是颠倒的。这不是我想要的 在保存帧之前,是否有方法旋转帧? 旋转位图不是一个优雅的解决方案,因为我们可能会遇到其他一些情况,例如视频聊天。视频的每一帧都被发送到远程对等方,然后远程用户将看到一个颠倒的视频。因此,我们应该在编码前旋转每一帧。如果不想旋转帧,则要翻转帧 这种情况的存在是因为位图认为(0,0)位于左上角,而GLES认为(0,0)位于左下角Android 由Grafika的存储框生成的图片是颠倒的,android,rotation,grafika,Android,Rotation,Grafika,我根据连续捕获活动编写了一个演示。我想将视频的第一帧保存为jpeg文件,因此我使用了Grafika已经准备好的saveFrame()函数。该函数的源代码如下所示: 但我发现生成的jpeg图片是颠倒的。这不是我想要的 在保存帧之前,是否有方法旋转帧? 旋转位图不是一个优雅的解决方案,因为我们可能会遇到其他一些情况,例如视频聊天。视频的每一帧都被发送到远程对等方,然后远程用户将看到一个颠倒的视频。因此,我们应该在编码前旋转每一帧。如果不想旋转帧,则要翻转帧 这种情况的存在是因为位图认为(0,0)位
glReadPixels()
从顶部开始填充缓冲区,位图认为缓冲区是底部,因此最终会得到一个颠倒的图像
您有两个选择:
drawFrame()
函数接受一个invert
参数,并修改从SurfaceTexture获得的矩阵(如果已设置)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编码器。