您的位置:首页 > 其它

OSG中抓取屏幕保存为图片

2016-07-26 18:13 936 查看
由于需要自动抓取OSG中的场景截图,对OSG掌握不好,花费了一些时间才算搞定。

首先,OSG在类osgViewer::ScreenCaptureHandler中默认情况下按下c(小写c)可以截取单张图片,而且实现得比较全面,在按下C(大写c)时可以连续截图;经过继承osgViewer::ScreenCaptureHandler类和osgViewer::ScreenCaptureHandler::CaptureOperation类,由于需要自动在某个时刻保存,所以些了一个自定义的事件,并将事件压入OSG的事件队列。

上代码:

ScreenCapture.h文件  

#pragma once

#ifndef SCREENCAPTURE_H

#define SCREENCAPTURE_H

#include <string>

#include <osgDB/WriteFile>

#include <osgViewer/ViewerEventHandlers>

class CScreenCapture : public osgViewer::ScreenCaptureHandler

{

public:
class  WriteToImageFile : public osgViewer::ScreenCaptureHandler::CaptureOperation
{
public:
enum SavePolicy
{
OVERWRITE,
SEQUENTIAL_NUMBER
// ... any others?
};
WriteToImageFile(const std::string& filename, const std::string& extension, SavePolicy savePolicy = SEQUENTIAL_NUMBER);
virtual void operator()(const osg::Image& image, const unsigned int context_id);
void setFileName(const std::string &filename){ _filename = filename; }
void setSavePolicy(SavePolicy savePolicy) { _savePolicy = savePolicy; }
SavePolicy getSavePolicy() const { return _savePolicy; }
protected:
WriteToImageFile& operator = (const WriteToImageFile&) { return *this; }
std::string _filename;
std::string _extension;
SavePolicy _savePolicy;
std::vector<unsigned int> _contextSaveCounter;
};
CScreenCapture(CaptureOperation* defaultOperation = 0, int numFrames = 1);
virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
void setFileName(const std::string& filename );

};

#endif // SCREENCAPTURE_H

ScreenCapture.cpp文件  

/****************************************************************************

*

*

*

****************************************************************************/

#include "stdafx.h"

#include "ScreenCapture.h"

CScreenCapture::CScreenCapture(CaptureOperation* defaultOperation /*= 0*/, int numFrames/* = 1*/):

ScreenCaptureHandler( defaultOperation, numFrames )

{

}

bool CScreenCapture::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )

{
osgViewer::ViewerBase* viewer = dynamic_cast<osgViewer::View*>(&aa)->getViewerBase();
if (!viewer) return false;
switch(ea.getEventType())
{
case (osgGA::GUIEventAdapter::FRAME):
{
// Booleans aren't the best way of doing this, but I want to do
// the actual adding here because I don't want to require
// startCapture() take a viewer as argument, which could not be
// the right one.
if (_startCapture)
{
// Start capturing with the currently set number of frames.
// If set to -1 it will capture continuously, if set to >0
// it will capture that number of frames.
_startCapture = false;
addCallbackToViewer(*viewer);
}
else if (_stopCapture)
{
_stopCapture = false;
removeCallbackFromViewer(*viewer);
}
break;
}

case ( osgGA::GUIEventAdapter::USER )://自定义的事件,需要进入OSG的事件队列
{
const OwnDefineEventAdpater* adpater= dynamic_cast< const MyEventAdpater *>(ea.getUserData());
switch(adpater->m_eventType)
{
case SAVE_IMAGE:// 保存图片的事件
{
if (getFramesToCapture() == 0)
{
setFramesToCapture(1);
}
addCallbackToViewer(*viewer);
return true;
}
default:
break;
}
//if (adpater->m_eventType == SaveImage )
//{
// // Check that we will capture at least one frame.
// // Just check for ==0, because >0 is means we're already
// // capturing and <0 means it will capture all frames.
// if (getFramesToCapture() == 0)
// {
// setFramesToCapture(1);
// }
// addCallbackToViewer(*viewer);
// return true;
//}
}
default:
break;
}
return false;

}

void CScreenCapture::setFileName( const std::string& filename )

{
CScreenCapture::WriteToImageFile* wtf =  dynamic_cast<CScreenCapture::WriteToImageFile*>(getCaptureOperation());
wtf->setFileName( filename );

}

void CScreenCapture::WriteToImageFile::operator()( const osg::Image& image, const unsigned int context_id )//仿函数实现图片保存

{
if ( !_filename.empty() )
{
osgDB::writeImageFile( image, _filename );
}

}

CScreenCapture::WriteToImageFile::WriteToImageFile( const std::string& filename, const std::string& extension, SavePolicy savePolicy /*= SEQUENTIAL_NUMBER*/ )

: _filename( filename ),

_extension( extension ),

_savePolicy( savePolicy )

{

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: