3

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 で反転できますか?

別のメモ/考え: 作成後にビットマップを反転するコストは些細なことかもしれません。これはユーザーの操作に依存しているため、メモリ エラーが発生するほど頻繁に発生しないからです。

4

2 に答える 2

3

openGL 提示バッファーの最初のピクセルが左下にあるため、読み取りピクセルを使用すると、画像が常に反転しているように見えます。正しい順序を取得するには 2 つの方法があります。

1 つは、別のバッファーで行うことができ、現在の描画パイプラインにまったく干渉しない、逆さまにバッファーに描画することです。これは、別のスレッドで実行したい場合や、画像のサイズを変更したい場合に特に良いアイデアかもしれません。これはすべて、1 回の描画呼び出しで実行できます。

もう 1 つは、データを手動で反転することです。これは、行のみを反転する必要があるため、見た目ほど悪くはありません (列はかなり悪いでしょう)。とにかく、実際には同じバッファーでこれを行うことができます。バッファーのコピーは必要ありません。最初の行を保存し、最後の行に置き換え、最後の行を保存した行に置き換えて、2 行目を続けます。

于 2015-02-06T12:41:20.667 に答える