Grafika的saveFrame生成的图片是倒置的
Picture produced by saveFrame of Grafika is upside-down
根据Continuous capture写了个demo activity.I想把视频的第一帧保存为jpeg文件,所以用了Grafika已经准备好的saveFrame()函数。函数源码如下:
https://github.com/google/grafika/blob/master/src/com/android/grafika/gles/EglSurfaceBase.java
但是我发现生成的jpeg图片是上行的-down.This不是我想要的。
有没有办法在保存框架之前旋转框架?
旋转位图不是一个优雅的解决方案,因为我们可能会遇到一些其他情况,例如视频聊天。视频的每一帧都被发送到远程端,然后远程端的人会看到一个倒置的视频。所以我们应该在编码之前旋转每一帧。
您不想旋转 框架,您想要翻转 框架。
存在这种情况是因为Bitmap认为(0,0)在左上角,而GLES认为(0,0)在左下角。 glReadPixels()
从顶部开始填充缓冲区,Bitmap 认为它是底部,所以你最终得到一个颠倒的图像。
您有两个选择:
- 使用 GLES 将框架倒置绘制,然后像现在一样抓取它。这就是 ExtractMpegFramesTest 代码所做的——注意
drawFrame()
函数接受一个 invert
参数,并修改从 SurfaceTexture 获得的矩阵(如果已设置)。
- 像现在一样绘制和提取帧,然后翻转缓冲区中的像素,然后再将它们转换为位图。这是移动字节的简单问题。它会增加一些开销,但由于 JPEG 压缩,您已经有点慢了。 (使用
System.arrayCopy()
复制整行可能比使用 Java 代码复制单个字节更好。)
我的实现如下,速度很快,不到10ms。
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");
}
根据Continuous capture写了个demo activity.I想把视频的第一帧保存为jpeg文件,所以用了Grafika已经准备好的saveFrame()函数。函数源码如下: https://github.com/google/grafika/blob/master/src/com/android/grafika/gles/EglSurfaceBase.java
但是我发现生成的jpeg图片是上行的-down.This不是我想要的。
有没有办法在保存框架之前旋转框架?
旋转位图不是一个优雅的解决方案,因为我们可能会遇到一些其他情况,例如视频聊天。视频的每一帧都被发送到远程端,然后远程端的人会看到一个倒置的视频。所以我们应该在编码之前旋转每一帧。
您不想旋转 框架,您想要翻转 框架。
存在这种情况是因为Bitmap认为(0,0)在左上角,而GLES认为(0,0)在左下角。 glReadPixels()
从顶部开始填充缓冲区,Bitmap 认为它是底部,所以你最终得到一个颠倒的图像。
您有两个选择:
- 使用 GLES 将框架倒置绘制,然后像现在一样抓取它。这就是 ExtractMpegFramesTest 代码所做的——注意
drawFrame()
函数接受一个invert
参数,并修改从 SurfaceTexture 获得的矩阵(如果已设置)。 - 像现在一样绘制和提取帧,然后翻转缓冲区中的像素,然后再将它们转换为位图。这是移动字节的简单问题。它会增加一些开销,但由于 JPEG 压缩,您已经有点慢了。 (使用
System.arrayCopy()
复制整行可能比使用 Java 代码复制单个字节更好。)
我的实现如下,速度很快,不到10ms。
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");
}