由于公司其他项目有一个分享截屏功能,用分享后的图片来吸引好友玩游戏!在这个项目中也准备这么做。
大的方向就是两步,先实现截屏,再实现分享!
在cocos中自带了截屏功能(但是早起版本2.X并没有集成这个功能,我们可以自己实现),
第一种方式:
具体做法如下:
1、我创建个CCRenderTexture 对象
2、把需要在图片中显示的动动渲染一次(调用一次vist 或者update接口)
3、调用CCRenderTexture对象的接口进行保存。
原理:
1、在创建CCRenderTexture的时候把gpu中的内容清空(一般用某个默认颜色进行填充),
2、然后渲染一遍需要保存的图片,把图片数据从gpu保存到cpu内存中,
3、保存导出到cpu内存中的图片数据。
具体实现(以下是cocos2x—2.1.2版本的lua实现)
local RenderTexture = {}
RenderTexture.__index = RenderTexture
function RenderTexture:new(width,height)
local cls =
{
rt = nil,
width = width or 100,
height = height or 100,
}
setmetatable(cls,self)
cls.rt = CCRenderTexture:create(cls.width,cls.height)
cls.rt:retain()
return cls
end
function RenderTexture:begin()
self.rt:beginWithClear(0,0,0,0)
end
function RenderTexture:endToLua()
self.rt:endToLua()
end
function RenderTexture:getRetainCount()
return self.rt:retainCount()
end
RenderTextureCreate = function (width, height)
return RenderTexture:new(width,height)
end
local re = RenderTextureCreate(shareHeroAwakenSize.width, shareHeroAwakenSize.height)
re.rt:beginWithClear(0,0,0,0)
//这里改成自己需要渲染的ui
shareHeroAwakenNode:visit()
container:visit()
re:endToLua()
re.rt:saveToFile(filename)
re.rt:release()
//这里就不要看了,这里是自己定义的微信分享接口
local QR = { width = 128, height= 128}
if EDShareToFriendsPoolQR then
EDShareToFriendsPoolQR("","",filename,shareHeroAwakenSize.width-QR.width*1.2,shareHeroAwakenSize.height-QR.height*1.3 ,QR.width,QR.height)
end
当然这里有需要注意的地方:
cocos2dx 裁剪区域
第二种方式:
这里我们可以使用cocos自带的接口:
cc.utils:captureScreen(callback, fileName)
或者封装过的接口(可以根据情况自己封装):
function display.captureScreen(callback, fileName)
cc.utils:captureScreen(callback, fileName)
end
这里的fileName可以是"xx.png",可以用安卓模拟器结合ES浏览器查看到
Android:保存在 /data/data/包名/files/xxx.png
filename可以只是一个文件名(保存到相对路径):像这样 “ScreenShot.png”。
filename也可以是一个绝对路径 :像这样 “/sdcard/ScreenShot.png”。
下面的是使用举例:
local function afterCaptured(succeed, outputFile)
--截图结束可以显示截屏前隐藏的按钮,或者一些图片
if succeed then
G_ShareImage({
description = "斗地主",
-- 这里的outputFile是包含了路径的
image = outputFile,
} ,
function(plateform)
-- 分享后的回调
end )
-- 分享后要移除图片防止占用内存
cc.FileUtils:getInstance():removeFile(outputFile)
else
Hall.showTips("截屏失败")
end
end
local outputFile = "screenshot"..tostring(os.time())..".png"
display.captureScreen(afterCaptured, outputFile)
其他截图参考:
点击查看其他截图参考
项目中接入的是友盟的分享,其中包含分享链接和图片。这里主要说说图片分享,图片分享调用
G_ShareImage({
description = "斗地主",
-- 这里的imagePath是包含了路径的
image = imagePath,
} ,callBack)
图片image 有两种:一种是本地图片,另一种是网络图片!首先尝试了网络图片传入一个图片地址(http),分享成功!分享截图时,调用失败,连微信都没调起!查看源码
public String ShareImage(final String param,final String callback) {
try {
//解析参数
JSONObject json = new JSONObject(param);
String description = json.getString("description");
String image = json.getString("image");
if(image.indexOf("assets") == 0)
{
Bitmap bmp_ = getAssetImage(mActivity,image.substring(7));
UMImage shareImage = new UMImage(mActivity,bmp_ );
mShareAction.withMedia(shareImage).open();
}
else if(image.indexOf("http") == 0)
{
UMImage shareImage = new UMImage(mActivity, image);
mShareAction.withMedia(shareImage).open();
}
// UMImage thumb = new UMImage(mActivity, "https://game469.com/app/icon.png");
// shareImage.setThumb(thumb);
mShareAction.setCallback(new UMShareListener(){
@Override
public void onStart(SHARE_MEDIA platform) {
}
@Override
public void onResult(SHARE_MEDIA platform) {
if(callback.equals("")) return;
if (platform.name().equals("WEIXIN_FAVORITE")) {
//Toast.makeText(mActivity, " 收藏成功啦", Toast.LENGTH_SHORT).show();
}
else {
int target = 0;
if(platform == SHARE_MEDIA.WEIXIN) {
target = 1;
}else if(platform == SHARE_MEDIA.WEIXIN_CIRCLE) {
target = 2;
}else if(platform == SHARE_MEDIA.QQ) {
target = 3;
}else if(platform == SHARE_MEDIA.QZONE) {
target = 4;
}else if(platform == SHARE_MEDIA.SMS) {
target = 5;
}
VCTChannel.Response("{\"success\":true,\"platform\":" + target + "}", callback);
}
}
@Override
public void onError(SHARE_MEDIA platform, Throwable t) {
if (platform != SHARE_MEDIA.MORE && platform != SHARE_MEDIA.SMS
&& platform != SHARE_MEDIA.EMAIL
&& platform != SHARE_MEDIA.FLICKR
&& platform != SHARE_MEDIA.FOURSQUARE
&& platform != SHARE_MEDIA.TUMBLR
&& platform != SHARE_MEDIA.POCKET
&& platform != SHARE_MEDIA.PINTEREST
&& platform != SHARE_MEDIA.INSTAGRAM
&& platform != SHARE_MEDIA.GOOGLEPLUS
&& platform != SHARE_MEDIA.YNOTE
&& platform != SHARE_MEDIA.EVERNOTE) {
int target = 0;
if(platform == SHARE_MEDIA.WEIXIN) {
target = 1;
}else if(platform == SHARE_MEDIA.WEIXIN_CIRCLE) {
target = 2;
}else if(platform == SHARE_MEDIA.QQ) {
target = 3;
}else if(platform == SHARE_MEDIA.QZONE) {
target = 4;
}else if(platform == SHARE_MEDIA.SMS) {
target = 5;
}
//Toast.makeText(mActivity, "分享失败啦", Toast.LENGTH_SHORT).show();
VCTChannel.Response("{\"success\":false,\"platform\":" + target + "}", callback);
if (t != null) {
Log.d("throw", "throw:" + t.getMessage());
}
}
}
@Override
public void onCancel(SHARE_MEDIA platform) {
//Toast.makeText(mActivity, "分享取消了", Toast.LENGTH_SHORT).show();
}
});
} catch (JSONException e) {
e.printStackTrace();
}
return "";
}
private Bitmap getAssetImage(Activity activity,String path) {
AssetManager assetManager = activity.getAssets();
try {
InputStream is = assetManager.open(path);
Bitmap bitmap = BitmapFactory.decodeStream(is);
return bitmap;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
观察发现image.indexOf()判断了字符串的开始是不是网络图片:http或https,还是本地资源asset文件夹下。而我们传入的截图是放在data/data/包名/files/文件夹下的,不满足任何一个所以!需要修改
if(image.indexOf("assets") == 0)
{
Bitmap bmp_ = getAssetImage(mActivity,image.substring(7));
UMImage shareImage = new UMImage(mActivity,bmp_ );
mShareAction.withMedia(shareImage).open();
}
else if(image.indexOf("http") == 0)
{
UMImage shareImage = new UMImage(mActivity, image);
mShareAction.withMedia(shareImage).open();
}
//以下是新加入的
else
{
File file = new File(image);
//如果需要缩小图片的可以使用下面
//BitmapFactory.decodeFile(filePath,getBitmapOption(2)); //将图片的长和宽缩小为原来的1/2
Bitmap bmp_ = BitmapFactory.decodeFile(filePath);
UMImage shareImage = new UMImage(mActivity, bmp_ );
mShareAction.withMedia(shareImage).open();
}
修改完成后就可以了,我们在其中加入相机咔嚓的效果
local function afterCaptured(succeed, outputFile)
--截图结束显示按钮
self.btnShare:show()
if succeed then
local function shareImag()
G_ShareImage({
description = "王者荣耀五杀",
image = outputFile,
} ,callBack)
-- 分享后要移除(立即移除有可能分享不成功,可以在上面分享成功的回调中移除)
if cc.FileUtils:getInstance():isFileExist(outputFile) then
cc.FileUtils:getInstance():removeFile(outputFile)
end
end
local screenShort = ccui.ImageView:create(outputFile)
self.baseNode:addChild(screenShort)
screenShort:setAnchorPoint(cc.p(0.5,0.5))
screenShort:setPosition(cc.p(display.cx,display.cy))
local action = cc.Sequence:create(
cc.Show:create(),
cc.ScaleTo:create(0.5, 0.5),
cc.DelayTime:create(0.5),
cc.RemoveSelf:create(),
cc.CallFunc:create(shareImag))
-- 咔嚓动画
screenShort:runAction(action)
else
Hall.showTips("截屏失败")
end
end
local outputFile = "screenshot"..tostring(os.time())..".png"
display.captureScreen(afterCaptured, outputFile)
友盟ios分享将在后面的章节中介绍,点击进入友盟ios分享。
The End
好了,今天的分享就到这里,如有不足之处,还望大家及时指正,随时欢迎探讨交流!!!
喜欢的朋友们,请帮顶、点赞、评论!您的肯定是我写作的不竭动力!