Captura y Almacenamiento de Imágenes en Aplicaciones con OSG

1. Almacenamiento de Imágenes en Memoria

Para capturar los datos del fotograma actual, se implementa una clase derivada de osg::Camera::DrawCallback. Esta clase se ejecuta después del dibujado de cada fotograma y almacena la información de los píxeles en un objeto osg::Image.

class FrameGrabber : public osg::Camera::DrawCallback
{
public:
    FrameGrabber(osg::Image* imageBuffer) : buffer(imageBuffer) {}
    FrameGrabber() : buffer(new osg::Image) {}
    
    virtual void operator()(const osg::Camera& camera) const
    {
        if (!camera.getViewport()) return;
        
        unsigned int imgWidth = camera.getViewport()->width();
        unsigned int imgHeight = camera.getViewport()->height();
        
        buffer->allocateImage(imgWidth, imgHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE);
        buffer->readPixels(0, 0, imgWidth, imgHeight, GL_RGBA, GL_UNSIGNED_BYTE);
    }
    
    osg::Image* getStoredImage() const { return buffer.get(); }
    
private:
    osg::ref_ptr<osg::Image> buffer;
};

2. Evento de Captura y Guardado en Archivo

Se crea un manejador de eventos GUI para detectar la pulsación de teclas y activar el guardado de la imagen capturada. Al presionar la tecla 's', se escribe el contenido almacenado en un archivo de imagen.

class ScreenshotHandler : public osgGA::GUIEventHandler
{
public:
    ScreenshotHandler(FrameGrabber* grabber) : captureTarget(grabber), fileCounter(0) {}
    
    bool handle(const osgGA::GUIEventAdapter& event, osgGA::GUIActionAdapter& action)
    {
        osgViewer::View* currentView = dynamic_cast<osgViewer::View*>(&action);
        if (!currentView) return false;
        
        if (event.getEventType() == osgGA::GUIEventAdapter::KEYUP)
        {
            if (event.getKey() == 's' || event.getKey() == 'S')
            {
                std::string filename = "capture_" + std::to_string(++fileCounter) + ".png";
                osgDB::writeImageFile(*captureTarget->getStoredImage(), filename);
                return true;
            }
        }
        return false;
    }
    
private:
    FrameGrabber* captureTarget;
    unsigned int fileCounter;
};

3. Integración en la Aplicación

Los componentes se configuran durante la inicialización del visor. El callback de captura se asocia a la cámara, y el manejador de eventos se añade al visor para reaccionar a las interacciones del usuario.

// Instanciar componentes
osg::ref_ptr<FrameGrabber> grabber = new FrameGrabber();
osg::ref_ptr<ScreenshotHandler> handler = new ScreenshotHandler(grabber.get());

// Configurar visor
viewer->getCamera()->setFinalDrawCallback(grabber);
viewer->addEventHandler(handler);
viewer->setSceneData(rootNode);

Etiquetas: OSG OpenSceneGraph C++ captura de pantalla Renderizado 3D

Publicado el 7-14 10:37