Goz*_*Goz 15 c java java-native-interface android bitmap
我设法创建了一个android.graphics.Bitmap,我通过SetPixels命令成功填充它.
问题是我从RGBA数据开始.然后我创建了一个jintArray.然后我调用SetIntArray(有效地将数据memcpying到缓冲区).然后,最后,我调用setPixels来实际设置像素(这可能导致另一个副本).
这样做的一个大问题是,无论我使用R8G8B8A8还是R5G6B5或A8,我仍然需要将我的像素数据转换为R8G8B8A8数据.
理想情况下,我想要一种只使用一个副本来填充缓冲区的方法,并允许我在不进行像素格式转换的情况下完成此操作.
有没有办法直接获取位图中包含的缓冲区数据?我看到JNI中有一个函数GetDirectBufferAddress,但是我可以在其上找到的文档表明它仅限于java.nio.buffer.我可以使用此功能直接获取像素数据吗?也许通过获取Bitmap类使用的内部缓冲区?
我唯一的方法是使用它来创建Global Ref'd Java.nio.buffer然后每次我想要更新,将我的像素数据复制到其中,然后使用copyPixelsFromBuffer?这仍然涉及2个副本,但至少可以消除像素格式的变化.这比我已经使用的方法更有效吗?
有没有更好的方法呢?
顺便说一句,我AM知道的事实,我可以在使用功能<机器人/ bitmap.h>,但我真的想不失去的Android 2.1和Android 2.2的支持...
提前干杯!
这是一个肮脏但有效的解决方案,适用于 Android 1.5 到 4.0。代码是 C++ 的。
                              //decls of some partial classes from Skia library
class SkRefCnt{
public:
   virtual ~SkRefCnt(){}
private:
   mutable int fRefCnt;
};
//----------------------------
class SkPixelRef: public SkRefCnt{
public:
   virtual class Factory getFactory() const;
   virtual void flatten(class SkFlattenableWriteBuffer&) const;
protected:
   virtual void* onLockPixels(class SkColorTable**) = 0;
   virtual void onUnlockPixels() = 0;
public:
   void *GetPixels(){
      SkColorTable *ct;
      return onLockPixels(&ct);
   }
};
jobject java_bitmap;  //your Bitmap object
jclass java_bitmap_class = env.GetObjectClass(java_bitmap);
class SkBitmap;
SkBitmap *sk_bitmap = (SkBitmap*)env.CallIntMethod(java_bitmap, env.GetMethodID(java_bitmap_class, "ni", "()I"));
SkPixelRef *sk_pix_ref;
sk_pix_ref = (SkPixelRef*)((int*)sk_bitmap)[1];
// get pointer to Bitmap's pixel memory, and lenght of single line in bytes
int buffer_pitch = env.CallIntMethod(java_bitmap, env.GetMethodID(java_bitmap_class, "getRowBytes", "()I"));
void *buffer = sk_pix_ref->GetPixels();
| 归档时间: | 
 | 
| 查看次数: | 2905 次 | 
| 最近记录: |