OSG中抓取屏幕保存为图片

来源:互联网 发布:mysql 导入数据乱码 编辑:程序博客网 时间:2024/05/22 12:43

由于需要自动抓取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 ){}



1 0
原创粉丝点击