move the capturen screen interface from Director to ccUtils

This commit is contained in:
vision 2014-05-27 10:44:23 +08:00
parent c72ae9e3c5
commit 363fd8dc2a
6 changed files with 91 additions and 75 deletions

View File

@ -1225,71 +1225,6 @@ void Director::setEventDispatcher(EventDispatcher* dispatcher)
} }
} }
void Director::captureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename)
{
_captureScreenCommand.init(std::numeric_limits<float>::max());
_captureScreenCommand.func = CC_CALLBACK_0(Director::onCaptureScreen, this, afterCaptured, filename);
Director::getInstance()->getRenderer()->addCommand(&_captureScreenCommand);
}
void Director::onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename)
{
Size frameSize = _openGLView->getFrameSize();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
frameSize = frameSize * _openGLView->getFrameZoomFactor() * _openGLView->getRetinaFactor();
#endif
int width = static_cast<int>(frameSize.width);
int height = static_cast<int>(frameSize.height);
bool succeed = false;
std::string outputFile = "";
do
{
std::shared_ptr<GLubyte> buffer(new GLubyte[width * height * 4], [](GLubyte* p){ CC_SAFE_DELETE_ARRAY(p); });
if (!buffer)
{
break;
}
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get());
std::shared_ptr<GLubyte> flippedBuffer(new GLubyte[width * height * 4], [](GLubyte* p) { CC_SAFE_DELETE_ARRAY(p); });
if (!flippedBuffer)
{
break;
}
for (int row = 0; row < height; ++row)
{
memcpy(flippedBuffer.get() + (height - row - 1) * width * 4, buffer.get() + row * width * 4, width * 4);
}
std::shared_ptr<Image> image(new Image);
if (image)
{
image->initWithRawData(flippedBuffer.get(), width * height * 4, width, height, 8);
if (FileUtils::getInstance()->isAbsolutePath(filename))
{
outputFile = filename;
}
else
{
CCASSERT(filename.find("/") == std::string::npos, "The existence of a relative path is not guaranteed!");
outputFile = FileUtils::getInstance()->getWritablePath() + filename;
}
succeed = image->saveToFile(outputFile);
}
}while(0);
if (afterCaptured)
{
afterCaptured(succeed, outputFile);
}
}
/*************************************************** /***************************************************
* implementation of DisplayLinkDirector * implementation of DisplayLinkDirector
**************************************************/ **************************************************/

View File

@ -405,11 +405,6 @@ public:
*/ */
float getFrameRate() const { return _frameRate; } float getFrameRate() const { return _frameRate; }
/**
* Capture screen
*/
void captureScreen(const std::function<void(bool, const std::string&)>& afterCaptued, const std::string& filename);
protected: protected:
void purgeDirector(); void purgeDirector();
bool _purgeDirectorInNextLoop; // this flag will be set to true in end() bool _purgeDirectorInNextLoop; // this flag will be set to true in end()
@ -428,9 +423,6 @@ protected:
void initTextureCache(); void initTextureCache();
void destroyTextureCache(); void destroyTextureCache();
/* Captrue screen implementation */
void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptued, const std::string& fileanme);
/** Scheduler associated with this director /** Scheduler associated with this director
@since v2.0 @since v2.0
*/ */

View File

@ -24,6 +24,12 @@ THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
#include "base/ccUtils.h" #include "base/ccUtils.h"
#include "base/CCDirector.h"
#include "renderer/CCCustomCommand.h"
#include "renderer/CCRenderer.h"
#include "platform/CCImage.h"
#include "platform/CCFileUtils.h"
#include "CCGLView.h"
NS_CC_BEGIN NS_CC_BEGIN
@ -38,4 +44,74 @@ int ccNextPOT(int x)
return x + 1; return x + 1;
} }
namespace Utilities
{
void captureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename)
{
static CustomCommand captureScreenCommand;
captureScreenCommand.init(std::numeric_limits<float>::max());
captureScreenCommand.func = std::bind(onCaptureScreen, afterCaptured, filename);
Director::getInstance()->getRenderer()->addCommand(&captureScreenCommand);
}
void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename)
{
auto glView = Director::getInstance()->getOpenGLView();
auto frameSize = glView->getFrameSize();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
frameSize = frameSize * glView->getFrameZoomFactor() * glView->getRetinaFactor();
#endif
int width = static_cast<int>(frameSize.width);
int height = static_cast<int>(frameSize.height);
bool succeed = false;
std::string outputFile = "";
do
{
std::shared_ptr<GLubyte> buffer(new GLubyte[width * height * 4], [](GLubyte* p){ CC_SAFE_DELETE_ARRAY(p); });
if (!buffer)
{
break;
}
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get());
std::shared_ptr<GLubyte> flippedBuffer(new GLubyte[width * height * 4], [](GLubyte* p) { CC_SAFE_DELETE_ARRAY(p); });
if (!flippedBuffer)
{
break;
}
for (int row = 0; row < height; ++row)
{
memcpy(flippedBuffer.get() + (height - row - 1) * width * 4, buffer.get() + row * width * 4, width * 4);
}
std::shared_ptr<Image> image(new Image);
if (image)
{
image->initWithRawData(flippedBuffer.get(), width * height * 4, width, height, 8);
if (FileUtils::getInstance()->isAbsolutePath(filename))
{
outputFile = filename;
}
else
{
CCASSERT(filename.find("/") == std::string::npos, "The existence of a relative path is not guaranteed!");
outputFile = FileUtils::getInstance()->getWritablePath() + filename;
}
succeed = image->saveToFile(outputFile);
}
}while(0);
if (afterCaptured)
{
afterCaptured(succeed, outputFile);
}
}
}
NS_CC_END NS_CC_END

View File

@ -47,7 +47,19 @@ Examples:
int ccNextPOT(int value); int ccNextPOT(int value);
namespace Utilities
{
/**
* Capture screen interface
*/
void captureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename);
/**
* The implementation of capturing screen
*/
void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename);
}
NS_CC_END NS_CC_END
#endif // __SUPPORT_CC_UTILS_H__ #endif // __SUPPORT_CC_UTILS_H__

View File

@ -60,6 +60,7 @@ THE SOFTWARE.
#include "base/CCUserDefault.h" #include "base/CCUserDefault.h"
#include "base/CCIMEDelegate.h" #include "base/CCIMEDelegate.h"
#include "base/CCIMEDispatcher.h" #include "base/CCIMEDispatcher.h"
#include "base/ccUtils.h"
// EventDispatcher // EventDispatcher
#include "base/CCEventType.h" #include "base/CCEventType.h"

View File

@ -609,7 +609,7 @@ void CaptureScreenTest::onCaptured(Ref*)
Director::getInstance()->getTextureCache()->removeTextureForKey(_filename); Director::getInstance()->getTextureCache()->removeTextureForKey(_filename);
removeChildByTag(childTag); removeChildByTag(childTag);
_filename = "CaptureScreenTest.png"; _filename = "CaptureScreenTest.png";
Director::getInstance()->captureScreen(CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), _filename); Utilities::captureScreen(CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), _filename);
} }
void CaptureScreenTest::afterCaptured(bool succeed, const std::string& outputFile) void CaptureScreenTest::afterCaptured(bool succeed, const std::string& outputFile)