I have an RGBA foo.tif with NoData Value=0 on all 4 bands.

Unfortunately values that are transparent black (0 0 0 0), when converting to jpg, become black instead of no data becoming white like I would expect.

I am trying to work around it with a basic color = if R+G+B==0 then white else color for each band:

gdal_calc.py -R foo.tif --R_band=1 -G foo.tif --G_band=2 -B foo.tif --B_band=3 --outfile=result.tif \
  --calc="where(R+G+B,R,255)" --calc="G*where(R+G+B,G,255)" --calc="where(R+G+B,B,255)" --overwrite

Or this "arithmetic-only" variant

gdal_calc.py -R foo.tif --R_band=1 -G foo.tif --G_band=2 -B foo.tif --B_band=3 --outfile=result.tif \
  --calc='R*((R+G+B)!=0) + 255*((R+G+B)==0)' --calc='G*((R+G+B)!=0) + 255*((R+G+B)==0)' --calc='B*((R+G+B)!=0) + 255*((R+G+B)==0)' --overwrite

But the result is not as I expect: Input / Output

input output

Al lot of colors (orange...) have turned white, which is the output's nodata value. And if I add --NoDataValue=0 I get this:


Which makes me think the Blue Band 3 is somehow the only one impacted by the input "nodata" value of 0. How can I fix this? I have GDAL 3.2 without the new -hideNoData flag :-(

Or better, can I make a jpg with a white "bottom" with pure GDAL (like this answer, but without rasterio because I actually want mbtiles jpg in the end)

gdalinfo foo.tif
Band 1 Block=390x5 Type=Byte, ColorInterp=Red
  NoData Value=0
Band 2 Block=390x5 Type=Byte, ColorInterp=Green
  NoData Value=0
Band 3 Block=390x5 Type=Byte, ColorInterp=Blue
  NoData Value=0
Band 4 Block=390x5 Type=Byte, ColorInterp=Alpha
  NoData Value=0

1 Answer 1


If you absolutely need JPG output, read after the first example. But, in this specific case, you might be better off with PNG output if that works for you.

gdal_translate -q -of PNG -co WORLDFILE=YES foo.tif foo3.png


tif to png

Converting to JPG is not straightforward as for PNG but try setting the nodata for all bands to 255 first if you want a white background n JPG, i.e., "255, 255, 255, 255" employing an intermediate VRT file. Then convert the VRT to JPG.

gdalbuildvrt -hidenodata -vrtnodata "255 255 255 255" foo.vrt foo.tif
gdal_translate -q -of JPEG foo.vrt foo3.jpg

Output: tif to vrt to jpg

You may have to refine the above logic as some of the colors appear to have changed.

I guess these are the points where one of the RGBA values were "0" and set as nodata in your original TIF file (check using a TIF viewer or QGIS).

But this is the logic you want if you need JPG as output.

  • 1
    Yes, nodata is per-band so it's not actually an adequate mean of conveying the whole information. And indeed png is better, but bigger. I did manage to reduce png size with pngnq as postprocess, so I'll stick with that. Thx
    – eddygeek
    Mar 10, 2021 at 20:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.