static void onCaptureScreen(const CapturedCallback &afterCaptured) { 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 const int width = static_cast<int>(frameSize.width); const int height = static_cast<int>(frameSize.height); Image *image = nullptr; 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); #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) // The frame buffer is always created with portrait orientation on WP8. // So if the current device orientation is landscape, we need to rotate the frame buffer. auto renderTargetSize = glView->getRenerTargetSize(); CCASSERT(width * height == static_cast<int>(renderTargetSize.width * renderTargetSize.height), "The frame size is not matched"); glReadPixels(0, 0, (int)renderTargetSize.width, (int)renderTargetSize.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get()); #else glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get()); #endif std::shared_ptr<GLubyte> flippedBuffer(new GLubyte[width * height * 4], [](GLubyte* p) { CC_SAFE_DELETE_ARRAY(p); }); if (!flippedBuffer) { break; } #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) if (width == static_cast<int>(renderTargetSize.width)) { // The current device orientation is portrait. for (int row = 0; row < height; ++row) { memcpy(flippedBuffer.get() + (height - row - 1) * width * 4, buffer.get() + row * width * 4, width * 4); } } else { // The current device orientation is landscape. for (int row = 0; row < width; ++row) { for (int col = 0; col < height; ++col) { *(int*)(flippedBuffer.get() + (height - col - 1) * width * 4 + row * 4) = *(int*)(buffer.get() + row * height * 4 + col * 4); } } } #else for (int row = 0; row < height; ++row) { memcpy(flippedBuffer.get() + (height - row - 1) * width * 4, buffer.get() + row * width * 4, width * 4); } #endif image = new Image(); if (image) { image->initWithRawData(flippedBuffer.get(), width * height * 4, width, height, 8); image->autorelease(); } }while(0); if (afterCaptured) { afterCaptured(image); } }
void captureBlurScreen(const std::function<void(bool, Dialog*&)>& afterCaptured, Dialog* layer) { static bool startedCapture = false; if (startedCapture) { CCLOG("Screen capture is already working"); if (afterCaptured) { afterCaptured(false, layer); } return; } else { startedCapture = true; } cocos2d::Size s = cocos2d::Director::getInstance()->getWinSize(); 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); // double ct1 ,ct2 ; // ct1 = ct2 = AbsoluteTimeGetCurrent(); bool succeed = false; int scale = 4; int dst_width = width / scale; int dst_height = height / scale; 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()); // CCLOG("First read %f", (ct2 = AbsoluteTimeGetCurrent()) - ct1); ct1 = ct2; std::shared_ptr<GLubyte> flippedBuffer(new GLubyte[(int)ceil(width / (float)scale) * (int)ceil(height/(float)scale) * 4 ], [](GLubyte* p) { CC_SAFE_DELETE_ARRAY(p); }); if (!flippedBuffer) { break; } HaypiFrameworkCPP::HaypiData::Gossip_blur(buffer, flippedBuffer, width, height, 4, 2, scale, true); // SpriteBlur::Gossip_blur(buffer, flippedBuffer, width, height, 4, 2, scale, true); Image* image = new (std::nothrow) Image; if (image) { image->initWithRawData(flippedBuffer.get(), dst_width * dst_height * 4, dst_width, dst_height, 8); Texture2D* text = new Texture2D(); text->initWithImage(image); startedCapture = false; auto blur = new Sprite(); blur->initWithTexture(text, cocos2d::Rect(0,0,dst_width,dst_height)); blur->setPosition(s/2); blur->setAnchorPoint(cocos2d::Vec2(0.5,0.5)); blur->setScale(s.height / dst_height); layer->addChild(blur, -99999); auto layerBk = LayerColor::create(Color4B::WHITE); layer->addChild(layerBk, -100000); blur->autorelease(); text->autorelease(); delete image; } else { CCLOG("Malloc Image memory failed!"); if (afterCaptured) { afterCaptured(succeed, layer); } startedCapture = false; } } while (0); }