Google の Grafika リポジトリに依存するライブ ストリーミング API を使用しています。私は Grafika EGLSurfaceBase の saveFrame メソッドを使用して、ユーザーがストリーミング中にビデオの静止画をキャプチャできるようにしています。
https://github.com/google/grafika/blob/master/src/com/android/grafika/gles/EglSurfaceBase.java
実際のキャプチャは機能しますが、一部のカメラの向きでは明らかに画像が反転します。
OpenGL テクスチャから取得した反転ビットマップに関連する多くの質問を見つけましたが、ほとんどは描画された画像を参照し、次のいずれかに依存しているようです。
a) OpenG でテクスチャを反転します。しかし、私の場合、ライブ ストリーミング API を使用しているため、テクスチャを反転して画像をキャプチャすると、実際にはビデオ ストリームでも画像キャプチャが反転する可能性があります。
また
b) リソースに基づいて生成された後にビットマップを反転する。私の場合、リソースがありません。バイトバッファからビットマップを作成しているので、複製して反転させたくありません。
API が持つ基本的な EGLSurfaceBase メソッドは次のとおりです。カメラの向きをそれに渡しますが、私の質問は次のとおりです。
String filename = file.toString();
int width = getWidth();
int height = getHeight();
ByteBuffer buf = ByteBuffer.allocateDirect(width * height * 4);
buf.order(ByteOrder.LITTLE_ENDIAN);
GLES20.glReadPixels(0, 0, width, height,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buf);
GlUtil.checkGlError("glReadPixels");
buf.rewind();
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(new FileOutputStream(filename));
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bmp.copyPixelsFromBuffer(buf);
bmp.compress(Bitmap.CompressFormat.PNG, 90, bos);
bmp.recycle();
} finally {
if (bos != null) bos.close();
}
Log.d(TAG, "Saved " + width + "x" + height + " frame as '" + filename + "'");
}
私の好ましい解決策は、BMP.createbitmap の前に (または同時に) 画像を反転する方法を見つけることです。たとえば、マトリックスを使用して、ピクセルの読み取り値を glReadPixels で反転できますか?
別のメモ/考え: 作成後にビットマップを反転するコストは些細なことかもしれません。これはユーザーの操作に依存しているため、メモリ エラーが発生するほど頻繁に発生しないからです。