Я написал демонстрацию о камере, которая похожа на ContinuousCaptureActivity графики (Исходный код ContinuousCaptureActivity.java). Для каждого кадра я добавил несколько операций помимо отрисовки кадра на экран.
Я создаю fbo, затем привязываю его и рисую рамку в fbo. Чтобы проверить изображение, отображаемое в fbo, я считываю данные изображения обратно в ОЗУ с помощью pbo и сохраняю изображение в формате jpg каждые 50 кадров. Таким образом, я получил файл jpg, но он был масштабирован, картина выглядит следующим образом:
Я предположил, что матрица из SurfaceTexture вызвала масштабирование, потому что каждая функция drawFrame() применяла эту матрицу. Поэтому я создал еще один fbo и нарисовал кадр первого fbo в этом fbo, затем сохранил изображение как jpg, и изображение стало нормально, как и ожидалось. Посмотрите на это:
Так что вывод такой, что 2 прорисовки восстановят изображение правильно.
Но изображение странное в моем телефоне huawei (модель: huawei MT7-CL00). Посмотрите на это:
Я проверил изображение первого fbo с телефоном huawei, оно масштабируется, как и ожидалось, но не странно. Поэтому я думаю, что ошибка произошла во втором файле fbo. Но не могу понять причину. Кто может дать мне несколько советов?
Некоторые исходники:
определения ФБО:
private GlTexture mGlTexture;
private GlFrameBuffer mGlFrameBuffer;
private GlFrameBuffer mGlFrameBuffer1;
Исходные коды классов GlTexture и GlFrameBuffer:
Метод bindFbo:
private void bindFBO(int fbo)
{
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo);
GLES20.glClearColor(0.0F, 0.0F, 0.0F, 0.0F);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
SurfaceView sv = (SurfaceView) findViewById(R.id.continuousCapture_surfaceView);
GLES20.glViewport(0, 0, 640, 480);
}
коды клавиш в drawFrame():
mDisplaySurface.makeCurrent();
mCameraTexture.updateTexImage();
mCameraTexture.getTransformMatrix(mTmpMatrix);
// Fill the SurfaceView with it.
SurfaceView sv = (SurfaceView) findViewById(R.id.continuousCapture_surfaceView);
int viewWidth = 640;
int viewHeight = 480;
GLES20.glViewport(0, 0, viewWidth, viewHeight);
mFullFrameBlit.drawFrame(mTextureId, mTmpMatrix);
//drawExtra(mFrameNum, viewWidth, viewHeight);
mDisplaySurface.swapBuffers();
bindFBO(mGlFrameBuffer.getID());
mFullFrameBlit.drawFrame(mTextureId, mTmpMatrix);
bindFBO(mGlFrameBuffer1.getID());
mFullFrameBlit2d.drawFrame(mGlTexture.getID(), mTmpMatrix);
String filename = "/sdcard/test/" + System.currentTimeMillis() + ".jpg";
new File(filename).getParentFile().mkdirs();
if (mFrameNum % 50 == 0)
{
try {
getPixelFromPBO(viewWidth, viewHeight, filename);
}
catch (Exception e) {
}
}