这是一个老问题,但我想回复一段代码。
以下对于实时来说太慢了。我打算稍后使用它与OpenTOK屏幕共享。任何快速替代?
ByteBuffer bb = ByteBuffer.allocateDirect(screenshotSize * 4);
bb.order(ByteOrder.nativeOrder());
GLES20.glReadPixels(0, 0, width, height, GL_RGBA,
GL10.GL_UNSIGNED_BYTE, bb);
int pixelsBuffer[] = new int[screenshotSize];
bb.asIntBuffer().get(pixelsBuffer);
final Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.RGB_565);
bitmap.setPixels(pixelsBuffer, screenshotSize - width, -width,
0, 0, width, height);
pixelsBuffer = null;
short sBuffer[] = new short[screenshotSize];
ShortBuffer sb = ShortBuffer.wrap(sBuffer);
bitmap.copyPixelsToBuffer(sb);
for (int i = 0; i < screenshotSize; ++i) {
short v = sBuffer[i];
sBuffer[i] = (short) (((v & 0x1f) << 11) | (v & 0x7e0) | ((v & 0xf800) >> 11));
}
sb.rewind();
bitmap.copyPixelsFromBuffer(sb);
PS:我已经尝试了GL_RGB和GL_BGRA,但它仍然很慢,我只是黑屏。
答案 0 :(得分:0)
首先,glReadPixels并不是导致代码速度变慢的原因。所有缓冲区的分配和将图像转换为另一种格式都是。
重用缓冲区。分配一次并重复使用它们。
ByteBuffer bb = ByteBuffer.allocateDirect(screenshotSize * 4);
bb.order(ByteOrder.nativeOrder());
这个位没问题。
GLES20.glReadPixels(0, 0, width, height, GL_RGBA,
GL10.GL_UNSIGNED_BYTE, bb);
现在您正准备转换为另一种具有大量开销的格式。坚持使用您收到的格式。而且,您再次分配缓冲区而不是重用。
但是,Bitmap可以分配一次并重复使用。
int pixelsBuffer[] = new int[screenshotSize];
bb.asIntBuffer().get(pixelsBuffer);
final Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.RGB_565);
bitmap.setPixels(pixelsBuffer, screenshotSize - width, -width,
0, 0, width, height);
pixelsBuffer = null;
short sBuffer[] = new short[screenshotSize];
ShortBuffer sb = ShortBuffer.wrap(sBuffer);
bitmap.copyPixelsToBuffer(sb);
然后你不需要这种不必要的转换。
for (int i = 0; i < screenshotSize; ++i) {
short v = sBuffer[i];
sBuffer[i] = (short) (((v & 0x1f) << 11) | (v & 0x7e0) | ((v & 0xf800) >> 11));
}
只要您的Bitmap格式相同,就可以使用copyPixelsFromBuffer()。
bitmap.copyPixelsFromBuffer(bb);
通常,Android位图与GL_RGBA的格式相同,因此您不太可能需要转换。以上内容将所有内容简化为只读和复制。