cocos2dx实现手动选取区域截图

前端之家收集整理的这篇文章主要介绍了cocos2dx实现手动选取区域截图前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

使用的方法是:RenderTexture渲染纹理+对当前场景的层Layer施加位移(先改后还)。
全屏截图可以使用以前的方法 RenderTexture渲染纹理,
也可以使用cocos2d::utils::captureScreen方法来完成。
保存下截图文件的话,还是需要使用到RenderTexture的saveToFile方法
(鄙人新手一枚,如有好的方法,或者认为我这样做存在问题的,请多多指教,在此谢过了!)

代码如下:

Screen.h

  1. #ifndef _SCREEN_H_
  2. #define _SCREEN_H_
  3. #include "cocos2d.h"
  4. USING_NS_CC;
  5. class ScreenScene :public Layer
  6. {
  7. public:
  8. static Scene* createScene();
  9. virtual bool init();
  10. CREATE_FUNC(ScreenScene);
  11. void menuCloseCallback(Ref *pSender);
  12. bool onTouchBegan(Touch *touch,Event *event);
  13. void onTouchEnded(Touch *touch,Event *event);
  14. void afterCaptured(bool success,std::string fileName);
  15. //屏幕截图
  16. void screenShoot(Size size);
  17. private:
  18. //触摸起始点与结束点
  19. Vec2 _startPos,_endPos;
  20. };
  21. #endif

Screen.cpp

  1. #include "Screen.h"
  2. Scene* ScreenScene::createScene()
  3. {
  4. auto scene = Scene::create();
  5. auto layer = ScreenScene::create();
  6. scene->addChild(layer,0,11);
  7. return scene;
  8. }
  9.  
  10. bool ScreenScene::init()
  11. {
  12. if (!Layer::init())
  13. {
  14. return false;
  15. }
  16. //获取视图
  17. auto visibleSize = Director::getInstance()->getVisibleSize();
  18. //添加背景图片
  19. auto bgSprite = Sprite::create("HelloWorld.png");
  20. bgSprite->setScale(visibleSize.width / bgSprite->getContentSize().width,visibleSize.height / bgSprite->getContentSize().height);
  21. bgSprite->setPosition(visibleSize.width / 2,visibleSize.height / 2);
  22. this->addChild(bgSprite);
  23.  
  24. //添加关闭按钮
  25. auto closeItem = MenuItemImage::create(
  26. "CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(ScreenScene::menuCloseCallback,this));
  27.  
  28. closeItem->setPosition(visibleSize.width - closeItem->getContentSize().width / 2,closeItem->getContentSize().height / 2);
  29. // create menu,it's an autorelease object
  30. auto menu = Menu::create(closeItem,nullptr);
  31. menu->setPosition(Vec2::ZERO);
  32. this->addChild(menu,1);
  33.  
  34. auto touchListener = EventListenerTouchOneByOne::create();
  35. touchListener->onTouchBegan = CC_CALLBACK_2(ScreenScene::onTouchBegan,this);
  36. touchListener->onTouchEnded = CC_CALLBACK_2(ScreenScene::onTouchEnded,this);
  37. _eventDispatcher->addEventListenerWithSceneGraPHPriority(touchListener,this);
  38.  
  39. //this->setPosition(-20,-20);
  40. return true;
  41. }
  42.  
  43. void ScreenScene::menuCloseCallback(Ref *pSender)
  44. {
  45. _director->end();
  46. }
  47.  
  48. bool ScreenScene::onTouchBegan(Touch *touch,Event *event)
  49. {
  50. //获取起始点
  51. auto nodeLocation = this->convertToNodeSpace(touch->getLocation());
  52. _startPos = nodeLocation;
  53. return true;
  54. }
  55.  
  56.  
  57. void ScreenScene::onTouchEnded(Touch *touch,Event *event)
  58. {
  59. auto visibleSize = _director->getVisibleSize();
  60. auto origin = Director::getInstance()->getVisibleOrigin();
  61. //获得结束点
  62. _endPos = this->convertToNodeSpace(touch->getLocation());
  63. //定义一个划取大小的渲染纹理
  64. auto shootSize = Size(MIN(abs(_startPos.x - _endPos.x),visibleSize.width),MIN(abs(_startPos.y - _endPos.y),visibleSize.height));
  65. auto renderTexture = RenderTexture::create(shootSize.width,shootSize.height);
  66. //获取当前场景
  67. auto currentScene = _director->getRunningScene();
  68. //获取左下点
  69. auto LeftDownPoint = Vec2(MAX(MIN(_startPos.x,_endPos.x),0),MAX(MIN(_startPos.y,_endPos.y),0));
  70. auto offset = Vec2(0,0) - LeftDownPoint;
  71. //位移
  72. currentScene->getChildByTag(11)->setPosition(offset);
  73.  
  74. renderTexture->beginWithClear(0.0f,0.0f,0.0f);
  75. currentScene->visit();
  76. renderTexture->end();
  77.  
  78. //还原
  79. //这里不设置延迟的话,由于前后时间的问题,会导致截图出现大的偏差。
  80. auto delay = DelayTime::create(0.001f);
  81. auto callfunc = CallFunc::create([=]{
  82. //不让其还原的时候闪烁一下
  83. Director::getInstance()->pause();
  84. currentScene->getChildByTag(11)->setPosition(0,0);
  85. Director::getInstance()->resume();
  86. });
  87. this->runAction(Sequence::create(delay,callfunc,nullptr));
  88.  
  89. //这个path是截图保存的路径。
  90. auto path = FileUtils::getInstance()->getWritablePath();
  91. renderTexture->saveToFile("ScreenShoot5201314.png",Image::Format::PNG);
  92. return;
  93.  
  94. //这个是截取全屏的,因为上面已经return了,所以不会执行到这
  95. //可以把上面全部注释掉,就能够看到效果了。
  96. utils::captureScreen(CC_CALLBACK_2(ScreenScene::afterCaptured,this),"newScreenShoot.png");
  97. return;
  98. }
  99.  
  100. //捕获之后
  101. void ScreenScene::afterCaptured(bool success,std::string fileName)
  102. {
  103. auto visibleSize = _director->getVisibleSize();
  104. if (success)
  105. {
  106. //先在中间显示,然后慢慢淡出,移除。当然还是将截图保存下来了
  107. auto shootSprite = Sprite::create(fileName);
  108. shootSprite->setScale(0.25);
  109. shootSprite->setPosition(visibleSize.width / 2,visibleSize.height / 2);
  110. this->addChild(shootSprite,1,1);
  111. screenShoot(shootSprite->getContentSize());
  112. auto delay = DelayTime::create(1.0f);
  113. auto fadeOut = FadeOut::create(2.0f);
  114. auto callFunc = CallFunc::create([=]{shootSprite->removeFromParent(); log("the sprite has removed from his parentNode!"); });
  115. shootSprite->runAction(Sequence::create(delay,fadeOut,callFunc,nullptr));
  116.  
  117. }
  118. else
  119. {
  120. log("capture screen Failed!");
  121. }
  122. }
  123.  
  124. void ScreenScene::screenShoot(Size size)
  125. {
  126. auto visibleSize = _director->getVisibleSize();
  127.  
  128. auto renderTexture = RenderTexture::create(size.width,size.height,Texture2D::PixelFormat::RGBA8888);
  129. auto shootSprite = this->getChildByTag(1);
  130. renderTexture->beginWithClear(0,0);
  131. shootSprite->visit();
  132. renderTexture->end();
  133. //这个path是截图保存的路径。
  134. auto path = FileUtils::getInstance()->getWritablePath();
  135. renderTexture->saveToFile("newScreenShoot.png",Image::Format::PNG);
  136. return;
  137. }

猜你在找的Cocos2d-x相关文章