序言
在一个项目中,需要输出osg仿真的图像结果,但是直接借用源码中的ScreenCaptureHandler无法实现咋指定目录下输出,且输出图像名称无法修改,默认使用按键的响应方式无法满足项目需求,在参考相关源码和帖子的基础上,以及方方的大力帮助下,有了下面的内容。
与现有网上大量内容相比,其只给出了代码,没有给出如何使用,让和我一样的超级菜鸟一头雾水。所以有了下面的内容。
a.h文件定义如下:
#pragma once
#ifndef A_H
#define A_H
#include <string>
#include <osgDB/WriteFile>
#include <osgViewer/ViewerEventHandlers>
class CScreenCapture : public osgViewer::ScreenCaptureHandler
{
public:
int il;
class WriteToImageFile : public osgViewer::ScreenCaptureHandler::CaptureOperation
{
public:
enum SavePolicy
{
OVERWRITE,
SEQUENTIAL_NUMBER
};
WriteToImageFile(const std::string& filename, const std::string& extension, SavePolicy savePolicy = SEQUENTIAL_NUMBER)
{
_filename = filename;
_extension = extension;
_savePolicy = savePolicy;
ik = 0;
}
virtual void operator()(const osg::Image& image, const unsigned int context_id)//仿函数实现图片保存
{
if (!_filename.empty())
{
std::string patch = _filename+"_"+std::to_string(ik)+"." + _extension;
osgDB::writeImageFile(image, patch);
ik++;
}
}
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;
int ik;
};
CScreenCapture(CaptureOperation* defaultOperation = 0, int numFrames = 1);
virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
//void setFileName();
};
#endif
//https://blog.csdn.net/xjujun/article/details/38986301
a.cpp如下:
/****************************************************************************
*
*
*
****************************************************************************/
//#include "stdafx.h"
#include "a.h"
CScreenCapture::CScreenCapture(CaptureOperation* defaultOperation /*= 0*/, int numFrames/* = 1*/):
ScreenCaptureHandler( defaultOperation, numFrames )
{
il = 0;
}
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):
{
addCallbackToViewer(*viewer);
if (getFramesToCapture() == 0)
{
setFramesToCapture(1);
}
break;
}
default:
break;
}
return false;
}
//void CScreenCapture::setFileName()
//{
// CScreenCapture::WriteToImageFile* wtf = dynamic_cast<CScreenCapture::WriteToImageFile*>(getCaptureOperation());
// //wtf->setFileName("11111111.jpg");
// //wtf->setSavePolicy(wtf->SEQUENTIAL_NUMBER);
// wtf->setFileName(std::to_string(il) + ".jpg");
//}
用法:
....
std::string path = "./1/IR123456789.jpg";
osg::ref_ptr<CScreenCapture::WriteToImageFile> wfi = new CScreenCapture::WriteToImageFile(
osgDB::getNameLessExtension(path),
osgDB::getFileExtension(path)
);
osg::ref_ptr<CScreenCapture >cs = new CScreenCapture(wfi.get());
viewer.addEventHandler(cs.get());
//外部控制时,使用 viewer.removeEventHandler(cs.get());//此处未测试
....
参考资料:
- https://blog.csdn.net/xjujun/article/details/38986301
- osg源码: D:\OSG\OSG_3.4.0\src\applications\present3D\present3D.cpp [line624]
// add the screen capture handler
std::string screenCaptureFilename = "screen_shot.jpg";
while(arguments.read("--screenshot", screenCaptureFilename)) {}
osg::ref_ptr<osgViewer::ScreenCaptureHandler::WriteToFile> writeFile = new osgViewer::ScreenCaptureHandler::WriteToFile(
osgDB::getNameLessExtension(screenCaptureFilename),
osgDB::getFileExtension(screenCaptureFilename) );
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler = new osgViewer::ScreenCaptureHandler(writeFile.get());
screenCaptureHandler->setKeyEventTakeScreenShot('m');//osgGA::GUIEventAdapter::KEY_Print);
screenCaptureHandler->setKeyEventToggleContinuousCapture('M');
viewer.addEventHandler(screenCaptureHandler.get());