Can we create cc.Sprite with base64 data in Cocos2d-JS?

I have try these but not success. It is not working on native and website.

cc.Sprite.create("data:image/png;base64,iVBORw0KGgoAAAANSU…");
cc.Sprite.create("iVBORw0KGgoAAAANSU…");

new cc.Sprite("data:image/png;base64,iVBORw0KGgoAAAANSU…");
new cc.Sprite("iVBORw0KGgoAAAANSU…");

Then i try cc.Texture2D() but also failure.

var texture = new cc.Texture2D();
texture.initWithData(base64, cc.Texture2D.PIXEL_FORMAT_RGB8888, 100, 100, cc.size(100, 100));

I can create image with the base64 in website with

new cc.newElement("IMG");

But it is hard to control the DOM element visibility so i would like to create the image with a cc.Sprite.

Anyone have idea to do so?

Thanks.

Hello,

Can you try with create sprite using texture. I think it may work.

var base64Img = cc.Sprite.createWithTexture(“data:image/png;base64,iVBORw0KGgoAAAANSU…”);

Let me know it works fine.

Thanks

Thanks for your reply.

I have tried your solution.
There is no error in the log but the cc.Sprite is not showing any image.

But i found a solution which is working on website.

var imgElement = new cc.newElement("IMG");
imgElement.setAttribute("src", base64Data);

cc.textureCache.cacheImage("uniqueKey", imgElement);
var sprite = new cc.Sprite("uniqueKey");

You need to generate an “uniqueKey” as path for the cache.

1 Like

hey Zinnitter, do you complete sprite with base64?
how about decode a image from string base 64?

Do you mean you want to create a sprite from base64 image?

This code is working to create sprite in web

var imgElement = new cc.newElement("IMG");
imgElement.setAttribute("src", base64Data);

cc.textureCache.cacheImage("uniqueKey", imgElement);
var sprite = new cc.Sprite("uniqueKey");

However, it is a bit tricky for native.
You need to do it in C++ for JSB, something like this.

Image *image = new Image();
image->initWithImageData((unsigned char*)bufferPtr, lengthOfArray);
Texture2D* texture = new Texture2D();
texture->initWithImage(image);
Sprite* sprite = new Sprite();
sprite->initWithTexture(texture);

The GitHub issue link
https://github.com/cocos2d/cocos2d-js/issues/1762

i run: cc.loader.loadImg(url, {isCrossOrigin : true }, function(err, img){

            });

it notify that: can not load
what is the problem?

I need to ask you some question to understand your situation.

  1. What you want to load and what is your purpose?

  2. Are you passing an image url or base64 to the cc.loader.loadImg?

  3. What platform you want to use with? Native or Web?

Thanks.

i want to load an image from base64 string to get captcha.
and i wan to use with native.
base64: data:image/jpeg;base64,/9j/4QAYRXh…"
thanks

From @pandamicro suggested

In JSB:

1.Create cc.Image with base64 data (transformed to uint8array and then pass to JSB and transform to a unsigned char * data), need manual bindings
2.Create a texture with the cc.Image object
3.Create a sprite 

It is a little complicated to do in native.

1.Basically, you have to create a new function which accept your base64 data in C++.

You can try add in

/frameworks/js-bindings/cocos2d-x/cocos/renderer/CCTexture2D.cpp

or

/frameworks/js-bindings/cocos2d-x/cocos/2d/CCSprite.cpp

2.Correctly setup the environment for Bindings generator: https://github.com/cocos2d/bindings-generator/

3.Then execute the auto javascript binding /tools/tojs/genbindings.py

Between, how you get the base64 string?

My code is:
var url = “data:image/jpeg;base64,dsfsdsdvsdv…”
var texture2d = new cc.Texture2D();
var img = cc.loader.getRes(url);
texture2d.initWithElement(img);
texture2d.handleLoadedTexture();
var logo = cc.Sprite.create(texture2d);
app.addChild(logo);

when i run: it notify that: “type is null”
what is my error?
how can i fix it.

The code you using is for web, won’t work in native.

I only done create cc.Sprite with base64 in web, here is the example code

var sprite = new cc.Sprite();
sprite.setPositon(cc.winSize.width/2, cc.winSize.height/2);
this.addChild(sprite);
cc.DOM.convert(sprite);

var spriteDom = new cc.newElement("IMG");
sprite.dom.appendChild(spriteDom);
spriteDom.setAttribute("src", base64Data);

var texture2d = new cc.Texture2D();
texture2d.initWithElement(spriteDom);
texture2d.handleLoadedTexture();

var newSprite = new cc.Sprite(texture2d);
newSprite.setPositon(cc.winSize.width/2, cc.winSize.height/2);
this.addChild(newSprite);

I am trying to follow your instructions but I do not get to pass the uint8array to the function, currently I have:

CCSprite.cpp:

Sprite* Sprite::createWithBase64(uint8_t *a)
{    
    return nullptr;
}

CCSprite.h:

static Sprite* createWithBase64(uint8_t* a);

MenuScene.js (mine)

       var aUint8 = new Uint8Array(4);
        aUint8[0] = 104;
        aUint8[1] = 111;
        aUint8[2] = 108;
        aUint8[3] = 97;
        cc.Sprite.createWithBase64(aUint8);

And it gets to the function, cause when the argument was an int and I passed an uint8 from javascript it arrived well and I printed it via log, but this give me this error:

jsb: ERROR: File /Users/pupgam/Documents/cocosWorkspace/CrossySky/frameworks/runtime-src/proj.android/../../js-bindings/bindings/auto/jsb_cocos2dx_auto.cpp: Line: 48245, Function: js_cocos2dx_Sprite_createWithBase64
js_cocos2dx_Sprite_createWithBase64 : Error processing arguments
JS: /data/data/com.pupgam.playscape.crossyskyguriko/files/debugruntime/src/scenes/menu_scene.js:205:Error: js_cocos2dx_Sprite_createWithBase64 : Error processing arguments

Any help welcome, thank you!

@alexgg

Sorry for the late reply.

Unfortunately, i’m not very familiar with the C++ code and uint8array too.

I have tried when i modifying the ImagePicker but not success.

May be you can try study how this Image Picker work on passing the data to JS.

And have you run “auto javascript binding /tools/tojs/genbindings.py” under tojs/ folder after modify CCSprite.cpp?

You can verify that your binding success by checking this 2 files have your new implementation since you modify CC.Sprite.

/frameworks/js-bindings/bindings/auto/jsb_cocos2dx_auto.hpp

/frameworks/js-bindings/bindings/auto/jsb_cocos2dx_auto.cpp

Finally I have found a solution usign the genbindings.py and leaving (in both the sdk and the frameworks/js-bindings/etcetera alothough i think it’s only needed it in the later) CCSprite like this:

CCSprite.cpp:

Sprite* Sprite::createWithBase64(const std::string& filename)
{   
    int len = 0;
    unsigned char *buffer;    
    len = base64Decode((unsigned char*)filename.c_str(), (unsigned int)filename.length(), &buffer);

    Image *img = new Image();
    bool ok = img->initWithImageData(buffer,len); 

    if(!ok) {        
        dbgprint("ERROR CREATING IMAGE WITH BASE64");
        return nullptr;
    }
    Texture2D* texture = new Texture2D();
    texture->initWithImage(img);
    Sprite* sprite = new Sprite();
    if(sprite && sprite->initWithTexture(texture)){
        sprite->autorelease();
        return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return nullptr;
}

CCSprite.h:

static Sprite* createWithBase64(const std::string& filename);

Then in .js:

var sprite = cc.Sprite.createWithBase64(chunk of base64 without the metadata at the beginning);
addChild(sprite);
1 Like

@alexgg

So you have success create the CCSprite with the above code you provided?

And your problem is on generating the bindings not the code?

No no with this solution everything is solved :smile: , my question was before I figured it out.

Thank you for your answers!

Great you have solved the problems! :smile:

For the future:

In the same folder of genbindings has to be a file “userconf.init” with:

[DEFAULT]
androidndkdir = PATH_TO/android-ndk-r10d
clangllvmdir = PATH_TO/android-ndk-r10d/toolchains/llvm-3.4/prebuilt/darwin-x86_64
cocosdir = PATH_TO_PROJECT/frameworks/js-bindings/cocos2d-x
jsbdir = PATH_TO_PROJECT/rameworks/js-bindings
cxxgeneratordir = PATH_TO_PROJECT/tools/bindings-generator

Can we add .gif images to the preloading screen with this method??