Рисование растрового изображения в видеофрейме с помощью OpenGL - PullRequest
0 голосов
/ 22 января 2020

Я работаю над классом, который расширяет Camera2Capturer, чтобы получить кадр из камеры, изменить его и затем передать обратно в обратный вызов наблюдателя. Я могу получить кадр, преобразовать его в растровое изображение, изменить это растровое изображение до нужного и затем нарисовать его с OpenGL на новом видеофрейме, который я возвращаю с capturerObserver.onFrameCaptured(videoFrame);

Проблема в том, что мой недавно созданный видеокадр растягивается. Растровое изображение корректно, когда я его проверяю, но нарисованное видеокадр растянуто сбоку. Я пробовал это на другом устройстве с другим разрешением, но проблема везде одинакова.

Вот код из моего метода startCapture:

@Override
    public void startCapture(int width, int height, int fps) {
        super.startCapture(width, height, fps);
        this.width = width;
        this.height = height;

        captureThread = new Thread(() -> {

            final int[] textureHandle = new int[1];
            GLES20.glGenTextures(1, textureHandle, 0);
            Matrix matrix = new Matrix();
            matrix.postScale(1f, -1f);
            TextureBufferImpl buffer = new TextureBufferImpl(width, height, VideoFrame.TextureBuffer.Type.RGB, textureHandle[0], matrix, surTexture.getHandler(), yuvConverter, null);

            // Bind to the texture in OpenGL
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);

            try {
                while (true) {
                    surTexture.getHandler().post(() -> {
                        if (needsToRedrawFrame) {
                            VideoFrame lastFrameReceived = capturerObs.getLastFrameReceived();

                            //This is the bitmap I want to draw on the video frame
                            Bitmap bitmapToDraw = drawingCanvasView.getmBitmap();


                            //At this point, bitmmapToDraw contains the drawing and the frame captured from the camera overlayed
                            //Now we need to convert it to fit into the onFrameCaptured callback (requires a VideoFrame).

                            // Set filtering
                            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
                            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);

                            // Load the bitmap into the bound texture.
                            GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmapToDraw, 0);

                            bitmapToDraw.recycle();

                            //The bitmap is drawn on the GPU at this point.

                            //We transfer it to the VideoFrame
                            VideoFrame.I420Buffer i420Buf = yuvConverter.convert(buffer);

                            VideoFrame videoFrame = new VideoFrame(i420Buf, 0, lastFrameReceived.getTimestampNs());

                            ogCapturerObserver.onFrameCaptured(videoFrame);
                            needsToRedrawFrame = false;
                        }
                    });

                    Thread.sleep(100);
                }
            } catch (Exception e) {
                LogHelper.logError(CapturerObserverProxy.class, "RMTEST THIS > " + e.getMessage(), e);
            }
        });
        captureThread.start();
    }

Вот как выглядит bitmapToDraw: Bitmap

А вот как выглядит видеокадр, нарисованный в SurfaceView: VideoFrame

Чего мне точно не хватает? Я совсем не знаком с OpenGL.

1 Ответ

0 голосов
/ 24 января 2020

Оказывается, рамка нарисована правильно. Но у рамки было другое разрешение, чем у Поверхности, где она фактически нарисована, следовательно, растяжение. Мне пришлось изменить размер (при сохранении соотношения сторон!) Растрового изображения, которое я собирался нарисовать. Если растровое изображение имеет тот же размер, что и поверхность, на которой оно отображается, то оно не будет растягиваться.

...