Screenshot Sharing of Creator Native Platform

Baidu actually has a lot of articles about screenshots of Creator's native platform, but why should I write this article? Because I met a big pit today.
The screenshots codes introduced in other articles on the Internet are actually available. The pit is that there are problems when you need to share them with Wechat on Android platform.
Wechat sharing requires reading local pictures, but by looking at CCRenderTexture.cpp, we know that the files saved by renderTexture.saveToFile are actually in your game application directory, and wechat cannot read them. So it can pull up the sharing of Wechat, but it always shows that it is in the process of sending.

bool RenderTexture::saveToFile(const std::string& fileName, Image::Format format, bool isRGBA, std::function<void (RenderTexture*, const std::string&)> callback)
{
    CCASSERT(format == Image::Format::JPG || format == Image::Format::PNG,
             "the image can only be saved as JPG or PNG format");
    if (isRGBA && format == Image::Format::JPG) CCLOG("RGBA is not supported for JPG format");

    _saveFileCallback = callback;

std::string fullpath = FileUtils::getInstance()->getWritablePath() + fileName;
_saveToFileCommand.init(_globalZOrder);
_saveToFileCommand.func = CC_CALLBACK_0(RenderTexture::onSaveToFile, this, fullpath, isRGBA);

Director::getInstance()->getRenderer()->addCommand(&_saveToFileCommand);
return true;
}

So you need to save the screenshot file another time.
The code is as follows:

var getScreenShotImagePath = function(){
    var fullPath = jsb.fileUtils.getWritablePath() + 'ScreenShotShare.png'; //Get the writable path, save the image locally, and read the file on the ios or java side
    if(cc.sys.os == cc.sys.OS_ANDROID){
        fullPath = '/sdcard/ScreenShotShare.png';
    }
    if (jsb.fileUtils.isFileExist(fullPath)) {  
        jsb.fileUtils.removeFile(fullPath);  
    }
    return fullPath;
}
/**
 * shareNode Nodes to be screenshot
 * hideNodes List of nodes to hide
 * hasMask   Does it contain Mask?
 */
var shareScreenShoot = function(shareNode, hideNodes, hasMask){    
    if(!cc.sys.isNative){
        return;
    }    
    //If the scene to be screenshot contains mask, use the statement annotated below to create renderTexture
    var renderTexture;
    if(!hasMask){
        renderTexture = cc.RenderTexture.create(shareNode.width,shareNode.height);
    }else{
        renderTexture = cc.RenderTexture.create(shareNode.width,shareNode.height, cc.Texture2D.PIXEL_FORMAT_RGBA8888, gl.DEPTH24_STENCIL8_OES);
    }
    //Code for actual screenshots
    var position = shareNode.position;
    renderTexture.begin();
    shareNode.position = cc.p(shareNode.width/2,shareNode.height/2);
    var setBtnVisible = function(hideNodes, active){
        for(var index in hideNodes){
            hideNodes[index].active = active;
        }
    }
    setBtnVisible(hideNodes);
    shareNode._sgNode.visit();
    renderTexture.end();
    var imagePath = getScreenShotImagePath();
    //saveToFile is placed in the path of jsb.fileUtils.getWritablePath(), and only the file name can be passed in. Can't pass the path
    renderTexture.saveToFile("ScreenShotShare.png",cc.ImageFormat.PNG, true, function () {
        if (jsb.fileUtils.isFileExist(jsb.fileUtils.getWritablePath() + "ScreenShotShare.png")) {
            if(cc.sys.os == cc.sys.OS_ANDROID){//Android's sharing path is rather poor, so it can only rewrite files.
                var fileData = jsb.fileUtils.getDataFromFile(jsb.fileUtils.getWritablePath() + "ScreenShotShare.png");
                jsb.fileUtils.writeDataToFile(fileData, imagePath);
                jsb.fileUtils.removeFile(jsb.fileUtils.getWritablePath() + "ScreenShotShare.png");//Delete old files after writing new ones
            }
            //shareImage(imagePath); //Wechat Sharing Interface, need to be implemented by oneself
        }
        shareNode.position = position;
        setBtnVisible(hideNodes, true);
    });
}

 

Usage method:

    onShareClick(){
        var btnList = [];
        btnList[btnList.length] = cc.find("Close", this.node);
        btnList[btnList.length] = cc.find("Btn_share", this.node);
        gamemain.shareScreenShoot(this.node, btnList);
    }

 

 

 

 

 

 

 

 

Tags: Android iOS Java

Posted on Sun, 06 Oct 2019 06:02:34 -0700 by Dave96