[gdal-dev] Programmatically saving out a .tif file
Zermeno, Robert J CIV NAVAIR, 472100D
robert.zermeno at navy.mil
Wed Aug 4 10:46:46 EDT 2010
Hi everyone,
I know I am having a programming issues here because using GDAL apps provided, it outputs correctly. I am using the SVN daily build of 7-21-2010 in Borland C++.
My issue: First, I converted the file , world.jp2, taken from http://www.microimages.com/gallery/jp2/ to TIF format via GDAL apps. Programmatically, I can read in this RGB image correctly. The problem is saving it out programmatically. My output results in an image that appears to having either missing information or somehow horizontal scanlines of black are inserted. It looks like your looking at an old TV that visually shows the scan lines of the video feed. It is consistent throughout the image.
I wish I can put up the image for you to see. I do not have a host site or server to do so.
Solution: Instead of keeping default CSLSetNameValue( pzOptions, "INTERLEAVE", "PIXEL" ) , I change it to CSLSetNameValue( pzOptions, "INTERLEAVE", "BAND" ).
The output file is the same as the input file. Only problem now is Microsoft Windows Picture and Fax Viewer can no longer read the image format. I guess BAND interleave is a viable option, but not really used often.
Here are snippets of my code that will help explain what I am doing, and see if you guys can help me. The problem with my solution is when using gdalinfo.exe on the file, original image INTERLEAVE = PIXEL and not BAND, so I want to spit out the same file in the same format.
PROGRAM:
//Retrieve the RGB colors....
RedBand = GDALGetRasterBand(fileDataset, 1);
GreenBand = GDALGetRasterBand(fileDataset, 2);
BlueBand = GDALGetRasterBand(fileDataset, 3);
imageBits = (BYTE *) malloc(curGeoData->getImageWidth() *
curGeoData->getImageHeight() *
curGeoData->getBitsPerPixel());
//Read in whole image: This example is for 1 scanLine read. I have this in a For loop.
RedError = GDALRasterIO( RedBand, GF_Read,
0,
curRow,
curGeoData->getImageWidth(),
1,
RedStrip,
curGeoData->getImageWidth(),
1,
GDT_Byte,
0,
0 );
GreenError = GDALRasterIO( GreenBand, GF_Read,
0 ,
curRow,
curGeoData->getImageWidth(),
1,
GreenStrip,
curGeoData->getImageWidth(),
1,
GDT_Byte,
0,
0 );
BlueError = GDALRasterIO( BlueBand, GF_Read,
0,
curRow,
curGeoData->getImageWidth(),
1,
BlueStrip,
curGeoData->getImageWidth(),
1,
GDT_Byte,
0,
0 );
if(RedError != CE_None || GreenError != CE_None || BlueError != CE_None)
{
//Error occured, return nothing to show error reading in bits...
return NULL;
}
//save out to output image buffer...
//Grab pixel per pixel
for(int col =0; col < curGeoData->getImageWidth(); col++)
{
imageBits[rawLoc++] = BlueStrip[col];
imageBits[rawLoc++] = GreenStrip[col];
imageBits[rawLoc++] = RedStrip[col];
}
//NOTE: as you can see, I have to place the pixels in BGRBGRBGRBGR in order for my Bitmap canvas to properly display. Its not in RGBRGBRGB...
//NOW, Time to save out the FILE, this is just snippets not whole source...
GDALDriverH hDriver;
GDALDatasetH hDstDS;
if(imageBpp == 3)
{
//pzOptions = CSLSetNameValue( pzOptions, "INTERLEAVE", "PIXEL" );
pzOptions = CSLSetNameValue( pzOptions, "INTERLEAVE", "BAND" );
}
hDriver = GDALGetDriverByName( "GTiff");
hDstDS = GDALCreate( hDriver, newFileName.c_str(),
newImageWidth, newImageHeight,
imageBpp, GDT_Byte, pzOptions );
//Output Geo-referenced data if necessary...
if( hDstDS != NULL )
{
else if(imageBpp == 3)
{
//24-bpp (COLOR) RGB...
GDALRasterBandH Redout = GDALGetRasterBand( hDstDS, 1 );
GDALRasterBandH Blueout = GDALGetRasterBand( hDstDS, 2 );
GDALRasterBandH Greenout = GDALGetRasterBand( hDstDS, 3 );
//GDALRasterBandH hBandout = GDALGetRasterBand( hDstDS, 1 );
if(Redout == NULL || Blueout == NULL || Greenout == NULL)
{
//Oh no!!
curError = CE_Failure;
return false;
}
//NOTE: Solution to RGB...is Break up my interleaved array, RGBRGBRGBRGB, and separate into
//arrays so will be [0] = RRRRRRRRRR, [1] = GGGGGGGGGG, [2] = BBBBBBBBB...
//THen save to output like I did reading in...
CPLErr RedError = CE_None;
CPLErr BlueError = CE_None;
CPLErr GreenError = CE_None;
BlueError = GDALRasterIO( Blueout, GF_Write, 0, 0, newImageWidth, newImageHeight,
imageBits + 1, newImageWidth , newImageHeight , GDT_Byte, //GDT_Float32,
3, newImageWidth * 3);
GreenError = GDALRasterIO( Greenout, GF_Write, 0, 0, newImageWidth, newImageHeight,
imageBits + 0, newImageWidth , newImageHeight , GDT_Byte, //GDT_Float32,
3, newImageWidth * 3);
RedError = GDALRasterIO( Redout, GF_Write, 0, 0, newImageWidth, newImageHeight,
imageBits + 2, newImageWidth, newImageHeight, GDT_Byte, //GDT_Float32,
3, newImageWidth * 3);
GDALClose(Redout);
GDALClose(Greenout);
GDALClose(Blueout);
GDALClose( hDstDS );
Redout = NULL;
Greenout = NULL;
Blueout = NULL;
hDstDS = NULL;
if(RedError != CE_None)
{
//Error occured, return nothing to show error reading in bits...
curError = RedError;
return false;
}
else if(GreenError != CE_None)
{
//Error occured, return nothing to show error reading in bits...
curError = GreenError;
return false;
}
else if(BlueError != CE_None)
{
//Error occured, return nothing to show error reading in bits...
curError = BlueError;
return false;
}
}
Assume that newImageWidth, newImageHeight are the size of image I mentioned in beginning of message. Tell my what you think about the way I
Am approaching it. Does it seem correct or am I misinterpreting something? Any suggestions is a plus. It is a working solution, but since
My output file cannot be opened with native Microsoft programs, its not acceptable. I hope I have given enough information. I tried to keep it short.
Thanks in advance,
Robert
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5695 bytes
Desc: not available
Url : http://lists.osgeo.org/pipermail/gdal-dev/attachments/20100804/eb157bd7/smime-0001.bin
More information about the gdal-dev
mailing list