Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify transparency in grids and images #8191

Closed
wants to merge 86 commits into from
Closed

Conversation

PaulWessel
Copy link
Member

@PaulWessel PaulWessel commented Dec 13, 2023

See forum post for some background and limitations. This PR does not implement code changes yet, but tries to describe via the documentation what we would like to have implemented in grdimage before 6.5 is released:

Q

This would let us handle RGBA files with alpha channel containing either transparency or opacity, either as a two-value 0 + 255 alphas, or a variable alpha from 0-255 (in which case we blend image color and fixed transparent color [white]). @joa, is anything missing from this proposal (apart from there being four not three schemes above)?

See forum post for some background and limitations.  This PR does not implement code changes yet, but tries to describe via the documentation what we would like to have implemented before 6.5 is released:
@PaulWessel PaulWessel added documentation Improve documentation enhancement Improving an existing feature labels Dec 13, 2023
@PaulWessel PaulWessel added this to the 6.5.0 milestone Dec 13, 2023
@PaulWessel PaulWessel self-assigned this Dec 13, 2023
@joa-quim
Copy link
Member

joa-quim commented Dec 13, 2023

4rth case is the more complex one. Current situation uses a blending mechanism that makes a weighted composition of the R,G,B,A and simulates transparency. That is, if plotting only the RGBA image, it looks transparent, but if we overlay it on another one we realize that it's actually opaque. This is what gave rise to the post in forum.

Now, if we want that a variable RGBA is truly transparent and PS provides only a all or nothing solution, we have a problem as only one of the RGB colors can be transparent.

Not completely sure but I think that is what you are proposing in the fourth case.

Related: #3477

Add new function grdimage_transparencies which determines what type of scenario we have regarding the alpha channel.
@PaulWessel
Copy link
Member Author

Yes, 4th case is approximating transparency since PS cannot do that on a per-pixel basis. So we need to explain that - I will add a Transparency Limitation section to grdimage man page.
Meanwhile, I added a new function to grdimage (grdimage_transparencies) that checks teh status of teh alpha band and returns 4 modes (If A is present):

1. "Image alpha channel: Constant transparency is %d.\n", Transp.value);
2. "Image alpha channel: Variable, but dominant transparency (%.1lf%%) is %d.\n", percent, Transp.value);
3. "Image alpha channel: 0 or 255, mostly (%.1lf%%) were 0.\n", percent);
4. "Image alpha channel: 0 or 255, mostly (%.1lf%%) were 255.\n", percent);

This info is now available via Conf->trans so we can take appropriate (and possibly new) action in the imaging functions doing transparency.

Then my suggestion of -Q +o|t modifiers can be used to select the single true transparency color or do the blending as we do now (but allow to replace white as the blend color).

Gotta go shopping now. Later.

@joa-quim
Copy link
Member

Fine, but there is more in the transparency land. Indexed images may also be set transparent by indicating which color in the CPT represents the transparency. There is code for that in the lib but likely that's information only to GDAL and since it was work previous to -Q it's probably ignored on the PS side. Needs digging.

@joa-quim
Copy link
Member

joa-quim commented Dec 14, 2023

Found things. In gmt_gdalwrite we have this

if (prhs->C.active) {
	/* Here we deal with contents of the prhs->C.cpt pointer. But there is the issue of the existence,
	   or not, of transparency. Because it's a pointer we cannot know if it holds a Mx3 or Mx4 array.
	   To know that the trick is to 'overload' the n_colors info. If it's > 2000 we interpret it as
	   an indication that we are in the Mx4 case. If, after divided by 1000, we have a decimal part, then
	   we assume that the decimal * 1000 is the number on the color matrix of the transparent color. And
	   then we use it to set prhs->nan_value. In gmt_gdalwrite it will be used by GDALSetRasterNoDataValue.
	*/

But this is only used by MEX & Julia, and is used to save indexed images with transparency.
On the other side, in gmt_gdalread we have

if (!got_noDataValue) {		/* May have been found if gmtgdalread_get_attrib_from_string() was acalled above */
	dfNoDataValue = GDALGetRasterNoDataValue(hBand, &status);
	if (status)
		Ctrl->nodata = dfNoDataValue;
	else
		Ctrl->nodata = GMT->session.d_NaN;
}

So, at least for a single transparency value, we have that info available but don't know if we make any use of it for images.

... Continuing. In gmtlib_read_image_info() that value is stored in

I->header->nan_value = from_gdalread->nodata;

but it doesn't seem to be used as a transparency info in grdimage/grdimage_img_byte_index()

@PaulWessel
Copy link
Member Author

Thanks, I will add the needed parsing of -Q to handle the new modifiers. We're having dinner guests today so may work for an hour and then later tonight.

@PaulWessel
Copy link
Member Author

Tried this to get a variable transparency RGBA but it actually crashed

gmt grdmix @earth_day_30m -Atr.nc -C -Grgba.tif

So will be working on fixing that bug (-C assumed we gave a grid, not an image for the -A operation. Need a test to test the above changes.

@joa-quim
Copy link
Member

@earth_days are indexed.

@PaulWessel
Copy link
Member Author

Yes, not a problem, but no A. Fixing grdmix now and it adds alpha to write RGBA tiff just fine.

add test
gmtlib_bcr_get_img sames the r,g,b values at given point, but did not also do tramsparency (unless it was coded as 4th band). This commit checks if alpha is not NULLand bands is 1 or 3 then we also compute the sampled transparency
If image header has wesn so that e>w and n> s we use that for domain
@PaulWessel
Copy link
Member Author

Figured out the strangeness by slowly building another branch and moving over smaller commits until I found why it broke: I had changed gmt_get_raster to take true instead of false since that would better return what the file was (image vs grids). For ex52 we read an image but the working version return GMT_IS_GRID and then do other things in grdimage.c. I will delete this branch and upload a new branch that has new stuff but is still passing all tests.

@PaulWessel PaulWessel closed this Dec 28, 2023
@joa-quim joa-quim deleted the transparency-improv branch April 12, 2024 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improve documentation enhancement Improving an existing feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants