[Freegis-list] Creating JPEG images with gdal
Frank Warmerdam
warmerdam at pobox.com
Tue Oct 31 22:10:52 CET 2006
Tomas Zajc wrote:
> Correctme if I'm wrong. I can't use gdal to export an image I have on memory
> (ie. on an array). I want to open an existin file usin gda or reading a raw
> data (manualy) make some modifications (filtering, resampling, etc) and
> export as JPEG. Maybe I should just use the plain jpg library to dump my
> array on a file.
Tomas,
First, I should likely have mentioned last time that the gdal-dev mailing
list would be a more appropriate place for this discussion.
It is possible to use CreateCopy() with a memory array as the input,
though it is somewhat involved since you need to create a "virtual dataset"
wrapper for your memory array. I have included an example of how this is
accomplished in mapserver below if you would like an example.
Of course it may well be easier to just write it using the jpeg library
if that is all you want to do.
Best regards,
--
---------------------------------------+--------------------------------------
I set the clouds in motion - turn up | Frank Warmerdam, warmerdam at pobox.com
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush | President OSGeo, http://osgeo.org
/************************************************************************/
/* msSaveImageGDAL() */
/************************************************************************/
int msSaveImageGDAL( mapObj *map, imageObj *image, char *filename )
{
int bFileIsTemporary = MS_FALSE;
GDALDatasetH hMemDS, hOutputDS;
GDALDriverH hMemDriver, hOutputDriver;
int nBands = 1;
int iLine;
GByte *pabyAlphaLine = NULL;
char **papszOptions = NULL;
outputFormatObj *format = image->format;
GDALDataType eDataType = GDT_Byte;
msGDALInitialize();
/* -------------------------------------------------------------------- */
/* We will need to write the output to a temporary file and */
/* then stream to stdout if no filename is passed. */
/* -------------------------------------------------------------------- */
if( filename == NULL )
{
const char *pszExtension = format->extension;
if( pszExtension == NULL )
pszExtension = "img.tmp";
if( map != NULL && map->web.imagepath != NULL )
filename = msTmpFile(map->mappath,map->web.imagepath,pszExtension);
else
{
#ifndef _WIN32
filename = msTmpFile(NULL, "/tmp/", pszExtension );
#else
filename = msTmpFile(NULL, "C:\\", pszExtension );
#endif
}
bFileIsTemporary = MS_TRUE;
}
/* -------------------------------------------------------------------- */
/* Establish the characteristics of our memory, and final */
/* dataset. */
/* -------------------------------------------------------------------- */
if( format->imagemode == MS_IMAGEMODE_RGB )
{
nBands = 3;
assert( gdImageTrueColor( image->img.gd ) );
}
else if( format->imagemode == MS_IMAGEMODE_RGBA )
{
pabyAlphaLine = (GByte *) calloc(image->width,1);
nBands = 4;
assert( gdImageTrueColor( image->img.gd ) );
}
else if( format->imagemode == MS_IMAGEMODE_INT16 )
{
nBands = format->bands;
eDataType = GDT_Int16;
}
else if( format->imagemode == MS_IMAGEMODE_FLOAT32 )
{
nBands = format->bands;
eDataType = GDT_Float32;
}
else if( format->imagemode == MS_IMAGEMODE_BYTE )
{
nBands = format->bands;
eDataType = GDT_Byte;
}
else
{
assert( format->imagemode == MS_IMAGEMODE_PC256
&& !gdImageTrueColor( image->img.gd ) );
}
/* -------------------------------------------------------------------- */
/* Create a memory dataset which we can use as a source for a */
/* CreateCopy(). */
/* -------------------------------------------------------------------- */
msAcquireLock( TLOCK_GDAL );
hMemDriver = GDALGetDriverByName( "MEM" );
if( hMemDriver == NULL )
{
msReleaseLock( TLOCK_GDAL );
msSetError( MS_MISCERR, "Failed to find MEM driver.",
"msSaveImageGDAL()" );
return MS_FAILURE;
}
hMemDS = GDALCreate( hMemDriver, "msSaveImageGDAL_temp",
image->width, image->height, nBands,
eDataType, NULL );
if( hMemDS == NULL )
{
msReleaseLock( TLOCK_GDAL );
msSetError( MS_MISCERR, "Failed to create MEM dataset.",
"msSaveImageGDAL()" );
return MS_FAILURE;
}
/* -------------------------------------------------------------------- */
/* Copy the gd image into the memory dataset. */
/* -------------------------------------------------------------------- */
for( iLine = 0; iLine < image->height; iLine++ )
{
int iBand;
for( iBand = 0; iBand < nBands; iBand++ )
{
GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 );
if( format->imagemode == MS_IMAGEMODE_INT16 )
{
GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
image->img.raw_16bit + iLine * image->width
+ iBand * image->width * image->height,
image->width, 1, GDT_Int16, 2, 0 );
}
else if( format->imagemode == MS_IMAGEMODE_FLOAT32 )
{
GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
image->img.raw_float + iLine * image->width
+ iBand * image->width * image->height,
image->width, 1, GDT_Float32, 4, 0 );
}
else if( format->imagemode == MS_IMAGEMODE_BYTE )
{
GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
image->img.raw_byte + iLine * image->width
+ iBand * image->width * image->height,
image->width, 1, GDT_Byte, 1, 0 );
}
#if GD2_VERS > 1
else if( nBands > 1 && iBand < 3 )
{
GByte *pabyData;
#ifdef CPL_MSB
pabyData = ((GByte *) image->img.gd->tpixels[iLine])+iBand+1;
#else
pabyData = ((GByte *) image->img.gd->tpixels[iLine])+(2-iBand);
#endif
GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
pabyData, image->width, 1, GDT_Byte, 4, 0 );
}
else if( nBands > 1 && iBand == 3 ) /* Alpha band */
{
int x;
#ifdef CPL_MSB
GByte *pabySrc = ((GByte *) image->img.gd->tpixels[iLine]);
#else
GByte *pabySrc = ((GByte *) image->img.gd->tpixels[iLine])+3;
#endif
for( x = 0; x < image->width; x++ )
{
if( *pabySrc == 127 )
pabyAlphaLine[x] = 0;
else
pabyAlphaLine[x] = 255 - 2 * *pabySrc;
pabySrc += 4;
}
GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
pabyAlphaLine, image->width, 1, GDT_Byte, 1, 0 );
}
#endif
else
{
GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
image->img.gd->pixels[iLine],
image->width, 1, GDT_Byte, 0, 0 );
}
}
}
if( pabyAlphaLine != NULL )
free( pabyAlphaLine );
/* -------------------------------------------------------------------- */
/* Attach the palette if appropriate. */
/* -------------------------------------------------------------------- */
if( format->imagemode == MS_IMAGEMODE_PC256 )
{
GDALColorEntry sEntry;
int iColor;
GDALColorTableH hCT;
hCT = GDALCreateColorTable( GPI_RGB );
for( iColor = 0; iColor < image->img.gd->colorsTotal; iColor++ )
{
sEntry.c1 = image->img.gd->red[iColor];
sEntry.c2 = image->img.gd->green[iColor];
sEntry.c3 = image->img.gd->blue[iColor];
if( iColor == gdImageGetTransparent( image->img.gd ) )
sEntry.c4 = 0;
else if( iColor == 0
&& gdImageGetTransparent( image->img.gd ) == -1
&& format->transparent )
sEntry.c4 = 0;
else
sEntry.c4 = 255;
GDALSetColorEntry( hCT, iColor, &sEntry );
}
GDALSetRasterColorTable( GDALGetRasterBand( hMemDS, 1 ), hCT );
GDALDestroyColorTable( hCT );
}
#if GDAL_VERSION_NUM > 1170
else if( format->imagemode == MS_IMAGEMODE_RGB )
{
GDALSetRasterColorInterpretation(
GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand );
GDALSetRasterColorInterpretation(
GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand );
GDALSetRasterColorInterpretation(
GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand );
}
else if( format->imagemode == MS_IMAGEMODE_RGBA )
{
GDALSetRasterColorInterpretation(
GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand );
GDALSetRasterColorInterpretation(
GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand );
GDALSetRasterColorInterpretation(
GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand );
GDALSetRasterColorInterpretation(
GDALGetRasterBand( hMemDS, 4 ), GCI_AlphaBand );
}
#endif
/* -------------------------------------------------------------------- */
/* Assign the projection and coordinate system to the memory */
/* dataset. */
/* -------------------------------------------------------------------- */
if( map != NULL )
{
char *pszWKT;
GDALSetGeoTransform( hMemDS, map->gt.geotransform );
pszWKT = msProjectionObjToWKT( &(map->projection) );
if( pszWKT != NULL )
{
GDALSetProjection( hMemDS, pszWKT );
CPLFree( pszWKT );
}
}
/* -------------------------------------------------------------------- */
/* Create a disk image in the selected output format from the */
/* memory image. */
/* -------------------------------------------------------------------- */
hOutputDriver = GDALGetDriverByName( format->driver+5 );
if( hOutputDriver == NULL )
{
GDALClose( hMemDS );
msReleaseLock( TLOCK_GDAL );
msSetError( MS_MISCERR, "Failed to find %s driver.",
"msSaveImageGDAL()", format->driver+5 );
return MS_FAILURE;
}
papszOptions = (char**)calloc(sizeof(char *),(format->numformatoptions+1));
memcpy( papszOptions, format->formatoptions,
sizeof(char *) * format->numformatoptions );
hOutputDS = GDALCreateCopy( hOutputDriver, filename, hMemDS, FALSE,
papszOptions, NULL, NULL );
free( papszOptions );
if( hOutputDS == NULL )
{
GDALClose( hMemDS );
msReleaseLock( TLOCK_GDAL );
msSetError( MS_MISCERR, "Failed to create output %s file.\n%s",
"msSaveImageGDAL()", format->driver+5,
CPLGetLastErrorMsg() );
return MS_FAILURE;
}
/* closing the memory DS also frees all associated resources. */
GDALClose( hMemDS );
GDALClose( hOutputDS );
msReleaseLock( TLOCK_GDAL );
/* -------------------------------------------------------------------- */
/* Is this supposed to be a temporary file? If so, stream to */
/* stdout and delete the file. */
/* -------------------------------------------------------------------- */
if( bFileIsTemporary )
{
FILE *fp;
unsigned char block[4000];
int bytes_read;
if( msIO_needBinaryStdout() == MS_FAILURE )
return MS_FAILURE;
fp = fopen( filename, "rb" );
if( fp == NULL )
{
msSetError( MS_MISCERR,
"Failed to open %s for streaming to stdout.",
"msSaveImageGDAL()", filename );
return MS_FAILURE;
}
while( (bytes_read = fread(block, 1, sizeof(block), fp)) > 0 )
msIO_fwrite( block, 1, bytes_read, stdout );
fclose( fp );
unlink( filename );
free( filename );
}
return MS_SUCCESS;
}
More information about the Freegis-list
mailing list
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)