如何通过JNI将图像从Java传递到Cocos2d-x?

时间:2014-10-20 03:03:30

标签: android java-native-interface cocos2d-x cocos2d-x-3.0

我需要通过JNI将类似drawable的图像数据从java端传递到cocos2d-x。我该如何实现它? JNI函数的参数应该是什么以及如何在cocos2d-x中投射?

3 个答案:

答案 0 :(得分:3)

  1. 为JNI创建一个Java接口,如:

    public static native void setBG(int[] raw, int width, int height);
    
  2. 在c ++代码中执行:

    //Use static variable here for simplicity
    
    int *imagedata;
    int staticwidth;
    int staticheight;
    Texture2D *userBackgroundImage;
    
    
    
    void Java_com_my_company_JniHelper_setBG(JNIEnv*  env, jobject thiz, jintArray raw, jint width, jint height)
    {
        jint *carr;
        carr = env->GetIntArrayElements(raw, 0);
        if(carr == NULL) {
            return; /* exception occurred */
        }
        ssize_t dataLen = (int)width * (int)height;
        int *data = new int[dataLen];
        for (long i = 0; i < dataLen; i++)
        {
            data[i] = carr[i];
        }
        imagedata = data;//Make a copy because it need to be done in GLThread
        staticwidth = (int)width;
        staticheight = (int)height;
        env->ReleaseIntArrayElements(raw, carr, 0);
        LOGD("set image: %d * %d", width, height);
    }
    
  3. 然后在某个持续时间层init或其他cocos2d-x代码中调用以下方法:

        void createImage(const void *data, ssize_t dataLen, int width, int height)
        {
            Texture2D *image = new Texture2D();
            if (!image->initWithData(data, dataLen, Texture2D::PixelFormat::BGRA8888, width,      height, Size(width, height)))
            {
                delete image;
                delete imagedata;
                image = NULL;
                imagedata = NULL;
                userBackgroundImage = NULL;
                return;
            }
            delete imagedata;
            imagedata = NULL;
            userBackgroundImage = image;
        }
    

    然后,您可以使用Texture2D对象创建精灵或执行任何您想要的操作

    1. 从java调用此代码:

      public static int[] BitmapToRaw(Bitmap bitmap) {
          Bitmap image = bitmap.copy(Bitmap.Config.ARGB_8888, false);
          int width = image.getWidth();
          int height = image.getHeight();
          int[] raw = new int[width * height];
          image.getPixels(raw, 0, width, 0, 0, width, height);
          return raw;
      }
      
      Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
      JniHelper.setBG(BitmapToRaw(image), image.getWidth(), image.getHeight());
      

答案 1 :(得分:1)

我只是将图像数据从cocos2d-x发送到Java,所以你需要找到一种方法来反转这种方法。它用于捕获节点并将其传递给屏幕截图。

CCNode* node = <some node>;
const CCSize& size(node->getContentSize());
CCRenderTexture* render = CCRenderTexture::create(size.width, size.height);

// render node to the texturebuffer
render->clear(0, 0, 0, 1);
render->begin();
node->visit();
render->end();

CCImage* image = render->newCCImage();

// If we don't clear then the JNI call gets corrupted.
render->clear(0, 0, 0, 1);

// Create the array to pass in
jsize length = image->getDataLen();
jintArray imageBytes = t.env->NewIntArray(length);
unsigned char* imageData = image->getData();
t.env->SetIntArrayRegion(imageBytes, 0, length, const_cast<const jint*>(reinterpret_cast<jint*>(imageData)));

t.env->CallStaticVoidMethod(t.classID, t.methodID, imageBytes, (jint)image->getWidth(), (jint)image->getHeight());

image->release();
t.env->DeleteLocalRef(imageBytes);
t.env->DeleteLocalRef(t.classID);

Java端看起来像这样:

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;

public static Bitmap getImage(int[] imageData, int width, int height) {
   Bitmap image = Bitmap.createBitmap(width, height, Config.ARGB_8888);
   image.setPixels(imageData, 0, width, 0, 0, width, height);
   return image;
}

答案 2 :(得分:0)

我认为最好和最简单的方法是将其保存在Java中,然后从cpp访问该文件,然后在使用后将其删除。