The advantage of using OpenCV is that you'll be able save you image in a variety of formats using just one or two lines.
If you want to avoid using OpenCV then you either have to roll your own code for saving an image in your chosen format, or use one of the standard libraries such as libJPEG. The choice you make depends upon the amount of time you have to write, test and debug your own code versus any aversion you may have to linking in another library.
A quick and dirty solution that I sometimes use when I just want to dump an image out is to use one of the Netpbm ASCII formats. This will result in huge files, but it's not meant to be an elegant solution. ;)
Something like this should work for you. Use a filename with a .ppm extension and Ubuntu or the GIMP will be able to open it.
void SaveImageAsPPM( const sensor_msgs::ImageConstPtr& msg, const char* filename )
{
if ( msg->encoding != "rgb8" )
{
return; // Can only handle the rgb8 encoding
}
FILE* file = fopen( filename, "w" );
fprintf( file, "P3\n" );
fprintf( file, "%i %i\n", msg->width, msg->height );
fprintf( file, "255\n" );
for ( uint32_t y = 0; y < msg->height; y++ )
{
for ( uint32_t x = 0; x < msg->width; x++ )
{
// Get indices for the pixel components
uint32_t redByteIdx = y*msg->step + 3*x;
uint32_t greenByteIdx = redByteIdx + 1;
uint32_t blueByteIdx = redByteIdx + 2;
fprintf( file, "%i %i %i ",
msg->data[ redByteIdx ],
msg->data[ greenByteIdx ],
msg->data[ blueByteIdx ] );
}
fprintf( file, "\n" );
}
fclose( file );
}