【问题标题】:How to pass a Image through JNI from Java to Cocos2d-x?java - 如何通过JNI将图像从Java传递到Cocos2d-x?
【发布时间】:2014-10-20 03:03:29
【问题描述】:

我需要通过 JNI 将 java 端的 drawable 等图像数据传递给 cocos2d-x。我如何实现它? jni函数的参数应该是什么,在cocos2d-x端怎么投?

【问题讨论】:

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


    【解决方案1】:
    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);
      }
      

    然后在某处duration layer 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());
      

    【讨论】:

      【解决方案2】:

      我只将图像数据从 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;
      }
      

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-08
          • 1970-01-01
          • 2010-10-26
          • 2012-07-08
          相关资源
          最近更新 更多