cocos2d-x Cocos Studio项目的PNG图片资源加密

本文是以cocos2d-x对PNG图片资源进行加密为基础进行的修改,原文方法对Cocos Studio生成的项目并没有支持,Studio生成的csb文件是二进制文件,也就是说我们无法提前修改它里面要加载的图片资源扩展名,所以只能从引擎源代码下手。


首先按照原文所说下载加密解密的算法和工具,将提供的6个文件导入到源代码项目中,然后在CCDecryptImage.h和CCDecryptImage.cpp中添加一个函数:

void ChangeExtensionToEPNG(std::string &file_path)
{
	std::string::size_type pos = file_path.rfind('.');
	std::string extstr;
	if (std::string::npos != pos)
	{
		extstr = file_path.substr(pos);
		if (extstr == ".png")
		{
			file_path = file_path.substr(0,pos);
			file_path.append(".epng");
		}
	}
}
很简单,就是给传入的png图片路径改一个后缀名,改成epng


然后修改CCImage.cpp中的initWithImageFile和initWithImageFileThreadSafe函数:

bool Image::initWithImageFile(const std::string& path)
{
	std::string epngpath = path;
	if (splitext(epngpath)[1] == ".png")
	{
		ChangeExtensionToEPNG(epngpath);
	}
    bool ret = false;
	_filePath = FileUtils::getInstance()->fullPathForFilename(epngpath);

    Data data = FileUtils::getInstance()->getDataFromFile(_filePath);

    if (!data.isNull())
    {
		// 图片文件解密
		if (splitext(epngpath)[1] == ".epng")
		{
			auto image_data = DecryptImage(epngpath,data);
			ret = initWithImageData(&image_data[0],image_data.size());
		}
		else
		{
			ret = initWithImageData(data.getBytes(),data.getSize());
		}
    }

    return ret;
}

bool Image::initWithImageFileThreadSafe(const std::string& fullpath)
{
	std::string epngpath = fullpath;
	if (splitext(epngpath)[1] == ".png")
	{
		ChangeExtensionToEPNG(epngpath);
	}
    bool ret = false;
	_filePath = epngpath;

	Data data = FileUtils::getInstance()->getDataFromFile(epngpath);

    if (!data.isNull())
    {
		// 图片文件解密
		if (splitext(epngpath)[1] == ".epng")
		{
			auto image_data = DecryptImage(epngpath,data.getSize());
		}
    }

    return ret;
}
特别解释一下:_filePath是CCImage类的成员变量,它将会添加到一个内存列表中,用于判断内存是否已经加载了这个图片资源,所以它的值也必须是.epng的后缀,否则引擎会无法识别是否已经加载了某个图片资源。getDataFromFile同样也要传入epng路径,因为我们打包游戏的时候不可能也把png图片打包进去,所以如果不用epng路径,它返回的值将永远是NULL。


这样就大功告成了,重新编译项目即可。


需要注意的是,由于通常我们不会单独加载某张图片,一般都是做成合图然后加载合图资源,所以合图应该这样加载和使用:

cc.SpriteFrameCache:getInstance():addSpriteFrames("plisttest.plist","plisttest.epng")

self:getResourceNode():getChildByName("img"):loadTexture("aboutBtn_normal.png",1)
为什么加载的时候要用epng而使用的时候用png呢?

因为epng路径是告诉引擎,你应该加载这个文件并且记住你已经加载了它,而引擎解析plist后,由于plist中记录的是png路径,所以引擎会将拆分出来的Texture用png路径标识,所以要使用Texture还是得用png路径。

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...