我需要通过JNI将类似drawable的图像数据从java端传递到cocos2d-x。我该如何实现它? JNI函数的参数应该是什么以及如何在cocos2d-x中投射?
答案 0 :(得分:3)
为JNI创建一个Java接口,如:
public static native void setBG(int[] raw, int width, int height);
在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);
}
然后在某个持续时间层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对象创建精灵或执行任何您想要的操作
从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访问该文件,然后在使用后将其删除。