Board index FlightGear Development

Anybody got any handy OSG image manipulation tips?  Topic is solved

FlightGear is opensource, so you can be the developer. In the need for help on anything? We are here to help you.
Forum rules
Core development is discussed on the official FlightGear-Devel development mailing list.

Bugs can be reported in the bug tracker.

Anybody got any handy OSG image manipulation tips?

Postby chriscalef » Mon May 20, 2013 5:38 am

Hi,

This is really an OSG question more than a FlightGear question, and I asked about it already over on the OSG forums, but while I'm awaiting approval over there I thought I'd just see if anybody over here had anything to say about it.

I'm still working on my "FlightGear World Server", and the current mission is to replace my (achingly slow) skybox generator. My previous method was to rotate the camera via PropertyTree changes, and save screenshots at each cardinal direction. I finally got through the literature on CameraGroups and Cameras, however, and managed to hook up a set of five cameras which simultaneously record all five desired directions, with the correct field of view.

I'm using viewports to keep these all in the same window, which allows them all to save out in the same screenshot as well, but this is where I run into trouble based on my very limited OpenSceneGraph knowledge. I'd like to open up that saved image, chop it up into five pieces and save them separately. This should be simple enough, I'd just like to verify a couple of assumptions first and see if I'm even close to doing this right.

Question number one: without even getting to the actual task at hand, when I simply try to load the image, as follows:

Code: Select all
osg::Image *image = osgDB::readImageFile(screenshotPath.c_str());
printf("loaded image! name %s file %s  size %d  width %d height %d\n",image->getName().c_str(),image->getFileName(),image->getImageSizeInBytes(),image->s(),image->t());


I get a valid filename, but garbage for getImageSizeInBytes as well as the width/height dimensions. Is there something wrong already with the way I'm using readImageFile? The image is present and valid, working fine in other applications. Not sure if my osg::Image is corrupt already or if there is just something wrong with the getImageSizeInBytes etc. functions.

Question number two: when I do get past this and have my image safely loaded, are there any OSG or SG/FG functions to help me copy subsections of this image into other images? Assuming not, does osg::Image::data() give me access to the raw bitmap data, with exactly width*height bytes present? (ie no compression or anything weird at this level?)

ie, could I safely loop through segments of data() on my source image and copy rows of bytes into a new, smaller destination image?

Thanks for any insights!

Cheers,
Chris
chriscalef
 
Posts: 279
Joined: Wed Feb 20, 2013 10:28 pm

Re: Anybody got any handy OSG image manipulation tips?  

Postby chriscalef » Mon May 20, 2013 7:14 pm

UPDATE: Figured it out! Here's some code in case anyone has similar needs.

I still don't know why getImageSizeInBytes() et al return garbage, but the image data is good, so my needs are met anyway.

Code: Select all
osg::Image *image = osgDB::readImageFile(screenshotPath.c_str());

int subWidth = 800;//FIX!! Get from client.
int subHeight = 800;
int srcWidth = 4000;
for (int i=0;i<5;i++)
{         
   osg::Vec3b* srcDataPtr = (osg::Vec3b*)image->data();
   osg::Image *subImage = new osg::Image;
   subImage->allocateImage(subWidth,subHeight,1,GL_RGB,GL_UNSIGNED_BYTE);
   subImage->setInternalTextureFormat(GL_RGB);
   osg::Vec3b* dataPtr = (osg::Vec3b*)subImage->data();
   for (int y=0;y<subHeight;y++)
   {
      memcpy(dataPtr,srcDataPtr+(i*subWidth),subWidth*3);
      dataPtr += subWidth;
      srcDataPtr += srcWidth;
   }
   skyboxPath = resourcePath + screenshot_files[i];
   subImage->setFileName(skyboxPath);
   osgDB::writeImageFile(*subImage,skyboxPath);
        subImage->unref();
}
remove(screenshotPath.c_str());//(delete original screenshot file, we don't need it anymore.)
image->unref();//I'm assuming this is necessary for memory cleanup, but I really don't know. (?)


EDIT: Oh yeah, to make this work, you need the following header files included:
Code: Select all
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
chriscalef
 
Posts: 279
Joined: Wed Feb 20, 2013 10:28 pm


Return to Development

Who is online

Users browsing this forum: No registered users and 7 guests