【发布时间】:2014-10-20 03:03:29
【问题描述】:
我需要通过 JNI 将 java 端的 drawable 等图像数据传递给 cocos2d-x。我如何实现它? jni函数的参数应该是什么,在cocos2d-x端怎么投?
【问题讨论】:
标签: android java-native-interface cocos2d-x cocos2d-x-3.0
我需要通过 JNI 将 java 端的 drawable 等图像数据传递给 cocos2d-x。我如何实现它? jni函数的参数应该是什么,在cocos2d-x端怎么投?
【问题讨论】:
标签: android java-native-interface cocos2d-x cocos2d-x-3.0
为 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);
}
然后在某处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 对象来创建精灵或做任何您想做的事情
从 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());
【讨论】:
我只将图像数据从 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;
}
【讨论】:
我认为最好和最简单的方法是将其保存在 Java 中,然后从 cpp 访问文件,然后在使用后将其删除。
【讨论】: