[gdal-dev] GDALWarp API and paletted images

Even Rouault even.rouault at spatialys.com
Fri Jun 12 04:35:17 PDT 2015


Selon Thomas Sevaldrud <thomas at silentwings.no>:

> Thanks again! The problem was in the warper setup, it used only the first
> band of the image. This also revealed a bug in another part of my code
> related to VRT's and Warp, since I had added double sets of bands there as
> well. However, when fixing this, some old code stopped working :-)
>
> Basically, my problem is that I want to reproject an RGB image which may be
> the VRT I made above, or another RGB(A) image, into  an output RGBA. If I
> don't have an input alpha channel, I still want the output to have alpha,
> and I want any borders that result from the reprojection to have alpha = 0.
> What is the correct way of setting up this? Currently I set up the bands
> like this:
>
> warpOptions->nBandCount = srcNumBands;
>
> warpOptions->panSrcBands =
> (int*)CPLMalloc(warpOptions->nBandCount*sizeof(int));
> warpOptions->panDstBands =
> (int*)CPLMalloc(warpOptions->nBandCount*sizeof(int));
>
> warpOptions->padfSrcNoDataReal =
> (double*)CPLMalloc(warpOptions->nBandCount*sizeof(double));
> warpOptions->padfSrcNoDataImag =
> (double*)CPLMalloc(warpOptions->nBandCount*sizeof(double));
>
> warpOptions->padfDstNoDataReal =
> (double*)CPLMalloc(warpOptions->nBandCount*sizeof(double));
> warpOptions->padfDstNoDataImag =
> (double*)CPLMalloc(warpOptions->nBandCount*sizeof(double));
>
> for (int j = 0; j < warpOptions->nBandCount; j++)
> {
> warpOptions->panSrcBands[j] = j+1;
> warpOptions->panDstBands[j] = j+1;
>
> warpOptions->padfSrcNoDataReal[j] = _srcNodata;
> warpOptions->padfSrcNoDataImag[j] = 0.0;
>
> warpOptions->padfDstNoDataReal[j] = _nodata;
> warpOptions->padfDstNoDataImag[j] = 0.0;
> }
>
> if (srcNumBands == 4)
> warpOptions->nSrcAlphaBand = 4;
>
> if (dstNumBands == 4)
> warpOptions->nDstAlphaBand = 4;
>
> char **papszWarpOptions = NULL;
> papszWarpOptions = CSLSetNameValue(papszWarpOptions, "INIT_DEST", "NO_DATA"
> );
>
> In some cases this works, but in others I get only a black image after the
> warp. So my question is basically if the above code should have worked. My
> assumption here is that the GDAL Warper will regard all input pixels as
> having full opacity when no alpha channel is specified, and that output
> alpha is initialized to 0. Are these valid assumptions, or do I need to
> create an alpha channel in the input image as well?

I don't see anything fundamentally wrong in the above. If your source image is
fully opaque, you don't need to set padfSrcNoDataReal and padfSrcNoDataImag. And
if you have an output alpha channel, you don't need to set padfDstNoDataReal and
padfDstNoDataImag too. In that cas you would just do papszWarpOptions =
CSLSetNameValue(papszWarpOptions, "INIT_DEST", "0" ); I'm not sure this will
change the end result however.

>
> - Thomas
>
> On Thu, Jun 11, 2015 at 5:25 PM, Even Rouault <even.rouault at spatialys.com>
> wrote:
>
> > Selon Thomas Sevaldrud <thomas at silentwings.no>:
> >
> > > Great, thanks!
> > >
> > > I tried this, but got only a red image as result, so I guess only the
> > first
> > > channel was used.
> > >
> > > This is the relevant code, where _ds is the input paletted data set
> > >
> > > vrtDS = vrtDriver->Create("", origW, origH, 3, GDT_Byte, NULL);
> > > double geoTransform[6];
> > > _ds->GetGeoTransform(geoTransform);
> > > vrtDS->SetGeoTransform(geoTransform);
> > > GDALSetProjection(vrtDS, _srcProjectionWKT.c_str());
> > >
> > > GDALRasterBand* srcBand = _ds->GetRasterBand(1);
> > >
> > > vrtDS->AddBand(GDT_Byte, NULL);
> > > vrtDS->AddBand(GDT_Byte, NULL);
> > > vrtDS->AddBand(GDT_Byte, NULL);
> >
> > You don't need the above 3 AddBand() since you called Create() with 3
> > already
> >
> > > VRTSourcedRasterBand* vrtRBand =
> > > (VRTSourcedRasterBand*)vrtDS->GetRasterBand(1);
> > > VRTSourcedRasterBand* vrtGBand =
> > > (VRTSourcedRasterBand*)vrtDS->GetRasterBand(2);
> > > VRTSourcedRasterBand* vrtBBand =
> > > (VRTSourcedRasterBand*)vrtDS->GetRasterBand(3);
> > > vrtRBand->AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0,
> > > 1.0, VRT_NODATA_UNSET, 1);
> > > vrtGBand->AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0,
> > > 1.0, VRT_NODATA_UNSET, 2);
> > > vrtBBand->AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0,
> > > 1.0, VRT_NODATA_UNSET, 3);
> > >
> > > Is there anything I have missed in the setup here?
> >
> > Looks good otherwise. Did you check that you configured properly the
> > warper to
> > use the 3 bands of the VRT ?
> > >
> > > - Thomas
> > >
> > >
> > >
> > > On Tue, Jun 9, 2015 at 1:44 PM, Even Rouault <even.rouault at spatialys.com
> > >
> > > wrote:
> > >
> > > > Thomas,
> > > > >
> > > > > I'm using the GDALWarp api from C++ to reproject and cut various
> > input
> > > > > images. In general this works very well for my purposes, except that
> > for
> > > > > paletted images I have to use NearestNeighbour resampling,
> > > > >
> > > > > I would like to use Bilinear or higher order resampling, and wonder
> > if
> > > > > there is any way to expand a paletted image to true RGB during the
> > warp
> > > > > process, so I can use these resampling methods.
> > > >
> > > > No, you must use an intermediate step before.
> > > >
> > > > >
> > > > > Alternatively, is there a way to do this conversion (from code)
> > before
> > > > the
> > > > > warp without having to run through the entire image in memory?
> > > >
> > > > You can use a in-memory VRT dataset to do on-the-fly expansion to RGB.
> > > >
> > > > With the AddComplexSource() method of VRTSourcedRasterBand class:
> > > >
> > > >     CPLErr         AddComplexSource( GDALRasterBand *poSrcBand,
> > > >                                      int nSrcXOff=-1, int nSrcYOff=-1,
> > > >                                      int nSrcXSize=-1, int
> > nSrcYSize=-1,
> > > >                                      int nDstXOff=-1, int nDstYOff=-1,
> > > >                                      int nDstXSize=-1, int
> > nDstYSize=-1,
> > > >                                      double dfScaleOff=0.0,
> > > >                                      double dfScaleRatio=1.0,
> > > >                                      double dfNoDataValue =
> > > > VRT_NODATA_UNSET,
> > > >                                      int nColorTableComponent = 0);
> > > >
> > > > Set nColorTableComponent to 1,2,3 for respectively R,G,B. This is what
> > > > gdal_translate will do if you use "gdal_translate -of VRT -expand rgb
> > > > pct.tif
> > > > out.vrt"
> > > >
> > > > Even
> > > >
> > > > --
> > > > Spatialys - Geospatial professional services
> > > > http://www.spatialys.com
> > > >
> > >
> >
> >
> > --
> > Spatialys - Geospatial professional services
> > http://www.spatialys.com
> >
>


-- 
Spatialys - Geospatial professional services
http://www.spatialys.com


More information about the gdal-dev mailing list