2013-09-29 55 views
2

我想捕获从OpenGL ES的帧缓冲数据和从它创建一个图像,基本上,以此来捕捉屏幕截图从OpenGL ES的帧缓冲区通过JNI在Android NDK创建位图图像

我试图通过JNI使用BitmapFactory类来完成转换。这里是我当前的代码:

size_t size = w * h; 
uint8_t *pixels = new uint8_t[size]; 
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 
jobject jbitmap = 0; 

if(pixels != 0) { 
    JNIEnv * env = GetEnv(state_->activity->vm); 

    //create the jbyte array and fill in with the pixel data 
    int byte_array_length = w * h; 
    jbyteArray byte_array = env->NewByteArray(byte_array_length); 
    env->SetByteArrayRegion(byte_array, 0, byte_array_length, (jbyte *)pixels); 

    //get the BitmapFactory class 
    jclass bitmap_factory_class = loadExternalClass("android/graphics/BitmapFactory"); 
    jmethodID decode_byte_array_method = env->GetStaticMethodID(bitmap_factory_class, 
    "decodeByteArray", "([BII)Landroid/graphics/Bitmap;"); 

    //get the bitmap itself 
    jbitmap = env->CallStaticObjectMethod(bitmap_factory_class, decode_byte_array_method, 
    byte_array, 0, byte_array_length); 

    env->DeleteLocalRef(byte_array); 
} 

if(jbitmap == 0) { 
    Log("Could not create image from framebuffer to share"); 
} 

基本上,代码试图做的是:

  • 捕获的OpenGL帧缓冲区为像素阵列
  • 尺寸W * H的创建jbyteArray
  • 填充jbytearray
  • 获取BitmapFactory类
  • 用jbytearray调用decodeByteArray方法

然而,jbitmap对象被连续地设置为0,这使我认为BitmapFactory呼叫失败,我不知道为什么用于捕获帧缓冲器到该像素阵列(

相同的代码即:glReadPixels调用)使用没有问题在iOS & MacOSX,所以我不认为问题在于那里

因此,任何帮助我可能会失踪?

+0

最初发布到[android-ndk google group](https://groups.google.com/forum/#!topic/android-ndk/oA6v40n49S8) – codemonkey

+0

@ AndonM.Coleman我已经记录了所有三个(w, h&像素)。 W&H确实符合我的屏幕尺寸,并且像素不为零,也不全为零。对于我来说,确定它是否确实是有效的数据有点困难,但我猜测它应该是,因为它只是一个直线glReadPixels调用 – codemonkey

回答

3

你为什么打电话解码关于glReadPixels (...)返回的数据?在大多数情况下,数据是原始RGB [A];它会更有意义编码它。对于我所知道的,这可能是正确的,但对于Google来说,调用一个将像素的原始缓冲区编码为更专门的像素集合的函数是愚蠢的。

我不得不从一个直观的角度来想象,decodeByteArray (...)实际上是要采取代表一些标准图像文件格式的字节数组并将其解码为通用位图。

既然如此,就不会是这样的:

Bitmap bm = Bitmap.createBitmap (w, h, Bitmap.Config.ARGB_8888); // Yes, ARGB 
bm.copyPixelsFromBuffer (pixels); 

更有意义?

我不完全确定JNI绑定应该看起来像这样,但是这会从RAW像素数据创建一个位图,而不是尝试解码未首先编码的东西。我想象一下,当Android在前几个字节的数据中找不到可识别的文件签名时,您正在尝试执行的操作几乎立即失败。

+0

具有很大意义。谢了哥们。我会相应地调整代码 – codemonkey

相关问题