When using grdimage with a GeoTIFF, it appears in my testing that the alpha channel is ignored - transparent pixels just show up as white. I can work around this by setting the -Q option to "white" (-Qwhite), such that the now-white pixels are now made transparent, but this is less than ideal as there could be white pixels that are not transparent - and the user would have to know that with this GeoTIFF, transparent pixels are white, which doesn’t seem to be default (NaN or “black” being the “standard”, apparently).
Is there a way to get grdimage to recognize/use the alpha channel?
Alternately, the GoTIFFs in question are being created by converting a PNG with transparency to GeoTIFF format using gdal_translate. While it isn’t really a GMT question, would anyone know of there is a way to convert transparent pixels to NaN, such that one could just use the -Q option “normally”, as part of the conversion process?
Thanks.
EDIT: replaced PyGMT option names with equivalent command-line GMT options.
Yes, it should apply. But we need some examples to reproduce. Transparency is tricky but I’m sure we got some variations working (though maybe not all cases). Anyway, if you are converting from png to Geotiff, you can’t use the NaNs as a fall back. NaNs are floats and images are integers (8 bits unsigned integers). The distinction between grids and images is important in GMT.
As is, the alpha channel is ignored, making the transparent pixels solid white. As mentioned, adding white to the -Q argument can make them transparent again, with the caveat that a) whoever got this GeoTIFF would need to know to do that, and b) any other pixels in the image that may be white (not many, if any, in this case) would also be made transparent.
Huh?
If you only do the GeoTIFF - as appears to be the case here - you would have no way of knowing if it was drawn with transparency or not, as the transparent areas would just look white regardless.
Just for kicks, I changed your CLI command to save as a png (which supports transparency) instead of a jpg, and opened it in an image editor, which showed that the white areas are just that - white, not transparent.
I’m afraid you are right. The image is correctly read as with transparency. The Mem layout: BRPA means it is a pixel interleaved with an alpha layer (the A) and indeed
first pixel is black but shows up as white. The -Q option of grdimage should work for images too in GMT6.5. Man says
-Q[+zvalue][color]
Make grid nodes with NaN values transparent, using the color-masking feature in PostScript Level 3 (the PS device must support PS Level 3). If the input is a grid, use +z to select another grid value than NaN. If input is instead an image, append an alternate color to select another pixel value to be transparent [Default is black].
but the result image still has transparent pixels as white. And oddly, the PNG (the one that supports the transparency) seems to apply it to the outside of the image. i.e., no annotations are visible with
After a couple of emails with Paul, we found that transparency is in fact working. The trick is to use -Qwhite. Confess that this part puzzles me and may indicate some issue, but it works
gmt begin t png
gmt grdimage @earth_relief_06m -R-169.765/-165.3727/52.3948/54.6188 -JX15c/0 -Baf -BWSen
gmt grdimage RandomGeoTIFFWithAlpha.tiff -Qwhite
gmt end show
Oddly, using gmt begin t PNG extends the transparency to the outside of the frame
I’m thinking the best path forward at this point is to load the image, change any black pixels to almost black, then change the transparent pixels to solid black and drop the Alpha channel.
In theory then the default of “black” with images should kick in and make things work as desired without any workarounds.
Clearly something isn’t behaving as expected when the Alpha channel is present, and that’s not something my end users should have to deal with (or with having to remember that with my GeoTIFFs they have to use -Qwhite rather than just -Q). So this might be an ugly solution, but at least it should work (in theory).
I have a vague recollection that I’ve run into that before. Don’t recall what I did to fix it though - Perhaps it has to do with plotting the earth_relief and frame in the same command, rather than using basemap first to get the frame/bounds/etc and then plotting grdimage on top of that? Dunno.
Looking at your RGBA image I found that all 731894 A values are 0. So what is it you expect to happen? Every pixel shall be transparent at 0 (opaque) or 255 (see through)?
I’m not sure where you are getting your information, but:
If what you say was true, the image would be fully transparent (when opened normally). It is not.
In an RGBA image, for the A channel, 0 is transparent, and 255 is opaque. This is reversed from the GMT definition of -t (transparency) which sets the transparency percentage.
If I look at the various pixels of the image, I find that MANY A values are NOT zero. For example, using the following python code:
We can see that while the pixel at (0,0) is transparent (A value of 0), the pixel at (1024,500) -roughly the center of the image - is fully opaque (A value of 255)
Also, the GeoTIFF image is 2048x1037, which gives 2,123,776 A values, not 731,894
I expect that the pixels with an Alpha value of 0 (transparent) will be transparent (allow the previous layers to be visible), while the pixels with an Alpha value of 255 (opaque) will cover the previous layers.
Yep, I just confirmed that setting all the transparent pixels to black and dropping the Alpha channel does the trick - simply specifying -Q at that point works as expected. So I guess this can be considered “solved”, unless someone wanted to look into why the Alpha channel isn’t behaving as one would expect.
Sorry, too quick coding error. Yes, not all are 0, either 0 or 255. So seems to me there are many different ways to consider transparency and GMT should be enhanced to do any of them:
Like your image, the alpha is either 0 or 255, where you say 0 should be transparent. OK, but that means it stores opacity (0 is no opacity but 100% transparency).
If alpha has a distribution from 0-255 then that is a continuously changing transparency. Or opacity?
Perhaps -Q can take a modifier +t for alpha = transparency while the default is alpha = opacity. Alternatively we do +o for opacity instead.
Need @Joaquim to get back from dinner since he coded the current decision.
Yes, technically Alpha is “Opacity”. This is a standard, in case there was any confusion on that front. From Difference between RGB vs RGBA color format - GeeksforGeeks for example: “…alpha channel that specifies the opacity of the color” (Note that that page specifically mentions CSS, where the value is 0 to 1, but in an 8bit image it is 0-255)
The either 0 or 255 distribution is specific to this image, as you mention here:
This statement is correct, in that alpha can be any value from 0-255 (in a standard 8 bit image, of course).