GNOME Bugzilla – Bug 70335
[TRACKING BUG] Incorrect RGBA resampling - color bleeding of transparent pixels
Last modified: 2018-05-24 10:39:45 UTC
Transparent area has color (Black: 0,0,0) in the layer. The color shouldn't affects in opacity area. Example: 1) Create new image, and fill BG Layer with While (default) 2) Create new transparent layer 3) Draw white line using Pencil or Paintbrush tool on transparent layer 4) Do some operations (e.g. Blur 5px or Smudge tool, etc) 5) We will see black color in transparent layer
You can also get the same effect with any other color. For example, after your first two steps, do the following: 2b) fill the transparent layer with any color (drag the color from the toolbox to fill everything) or with some patterns 2c) use Edit->Clear (Ctrl-K) to make the layer transparent again. Continue with steps 3, 4 and 5 and you will see the other color in the areas that should have been transparent. Explanation: in step 2c, the alpha channel is set to fully transparent but the color (RGB channels) is not modified. You can see that easily by using the color picker over the areas that should be transparent. This is fine, because the color should not be used if the alpha channel says that the pixel is fully transparent. But in step 4, the smudge tool or the blur filter takes some of this "hidden" color when mixing it with the other pixels. This should not happen. This bug affects these tools: - Convolver - Smudge It also affects most blur and noise plug-ins (except for Blur and Selective Gaussian Blur) as well as several other plug-ins: - Blur->Gaussian Blur (IIR) - Blur->Gaussian Blur (RLE) - Blur->Motion Blue - Blur->Pixelize - Colors->Map->Gradient Map (see bug #70964) - Noise->Hurl - Noise->Noisify - Noise->Pick - Noise->Slur - Enhance->Deinterlace - Enhance->Despeckle - Distorts->Curve Bend (barely visible) - Distorts->Emboss (the preview ignores all transparency!) - Distorts->IWarp - Distorts->Polar Coords - Distorts->Ripple - Distorts->Value Propagate - Distorts->Waves (the preview ignores all transparency!) - Distorts->Whirl and Pinch - Distorts->Wind (in "Wind" mode, not in "Blast" mode) - Artistic->GIMPressionist - Artistic->Oilify - Map->Fractal Trace - Map->Illusion - Map->Make Seamless - Map->Map Object - Map->Wrap It also affects the previews in the Layers dialog, although this is not a serious problem. The best way to see the problem with the filters that introduce some noise (Hurl, Noisify) is to use two different colors in step 2b: fill the top half of the layer with red and the bottom half with green, for example. Then you see that after applying the plug-in, there is an obvious color shift in each half of the image.
Created attachment 6776 [details] test.xcf.gz (4181 bytes) - test image showing alpha problems
I attached a small test image that can be used to see the problems very easily. Load this image and apply some of the filters (or use the smudge or blur tools) to the top layer. In theory, everything should still be white after the filter is applied. In practice, you see some red and green pixels appearing around the white circle (on the white background). The preview problems are very obvious with the Waves plug-in.
Although I haven't checked the code of all plug-ins, it seems that the problem comes from the fact that most of them are averaging pixels using a fast but incorrect method, instead of using a more complex but correct method when an alpha channel is present. Given two RGBA pixels (R1, G1, B1, A1) and (R2, G2, B2, A2), some plug-ins and tools compute the average (R, G, B, A) by using the average of the four channels separately. The formula is sometimes part of a more complex algorightm and sometimes hidden in a matrix, but for two pixels it looks basically like this: R = (R1 + R2) / 2 G = (G1 + G2) / 2 B = (B1 + B2) / 2 A = (A1 + A2) / 2 This works for fully opaque pixels, but this is incorrect if the alpha channel has different values for the two pixels. For example, if there is a fully transparent but previously red pixel (255, 0, 0, 0) and a fully opaque blue pixel (0, 0, 255, 255), the result will be a semi-transparent pink pixel (127, 0, 127, 127), which is obviously incorrect because the color of the fully transparent pixel should not be taken into account. The same problem occurs when the pixels are partially transparent, although it is not always visible if the difference in color or opacity is not large enough. The correct way to compute the average (if I am not mistaken) is to use a weighted sum in which the value of the alpha channel is taken as the weight: R = ((R1 * A1) + (R2 * A2)) / (A1 + A2) G = ((G1 * A1) + (G2 * A2)) / (A1 + A2) B = ((B1 * A1) + (B2 * A2)) / (A1 + A2) A = (A1 + A2) / 2 This is equivalent to working with pre-multiplied alpha while computing the average and converting the result back to post-multiplied alpha (this has to be done carefully, otherwise the result will be too dark). Applied to the previous example, this formula would give a semi-transparent blue pixel (0, 0, 255, 127), which is the correct result. Many plug-ins, tools and parts of the core do this correctly. But as we can see from the list included in my previous comment, there are many plug-ins (27) and two tools (Convolver and Smudge) that generate incorrect results.
Created attachment 6802 [details] test2.xcf.gz (99 KB) - another image for testing the bugs
Two other parts of the core affected by this bug are the navigation windows: both the one accessed by clicking on the cross in the bottom right corner of the image and the one accessed via the View menu. The effect is spectacular on the image included in the second attachment.
As proposed on the gimp-developers mailing list, I have turned this bug report into a "tracking bug". The bug affects many different parts of the code which are likely to be fixed separately, so they now have individual bug reports. This bug will only be closed when all of its dependencies are fixed.
Seems like the Bugzilla people prefix most of their tracking bugs with "[tracking bug]" or "[meta] tracking bug", so I am doing the same here for consistency. All dependencies are still open, unfortunately. :(
I'm not sure whether any of the plugins listed above does weighted averaging or not (it seems some probably do), but I already needed it in a plugin, so for reference, here's the formula for alpha: alpha = \sum_{i=1}^n alpha_i * weight_i and for channels (R, G, B or Gray) channel = ( \sum_{i=1}^n alpha_i * weight_i * channel_i ) / alpha provided \sum_{i=1}^n weight_i = 1 When alpha == 0, the color is arbitrary.
Also the Lighting Effects plug-in seems to suffer this problem. Once confirmed, bug #105496 should be added as a dependency here.
By the way, the formula that you gave in your previous comment is similar (but more general) than the formula that I listed above, using weight_i = 1/2. So I could have written the same formula in this way, to avoid computing the sum (A1 + A2) more than once: A = (A1 + A2) / 2 R = (((R1 * A1) + (R2 * A2)) / A) / 2 G = (((G1 * A1) + (G2 * A2)) / A) / 2 B = (((B1 * A1) + (B2 * A2)) / A) / 2 If you want to be a bit more efficient, you can try the following: Asum = (A1 + A2) R = ((R1 * A1) + (R2 * A2)) / Asum G = ((G1 * A1) + (G2 * A2)) / Asum B = ((B1 * A1) + (B2 * A2)) / Asum A = Asum / 2 We should of course add a test for A == 0 (or Atmp == 0), in which case R, G and B can be set to 0 or some arbitrary value.
It seems plug-ins ouput it merged incorrectly to the image when a fuzzy selection is present -- this breaks virtually all plug-ins. See bug #105568 for more.
Shouldn't bug #93856 be added to this tracking bug (and renamed while we are on it) ?
If I understood bug #93856 correctly, it describes a different problem related to the pixels around the selection border and how plug-ins should behave when they are told to work on a selection. So I don't think that we should link it to this tracking bug. If more plug-ins are affected by the same problem as in bug #93856, then I suggest opening a new tracking bug.
Changed target milestone of several bugs to 2.0 - these are not features, and don't look to me like blockers for a pre-release, but they have to be addressed before 2.0. Dave.
Bumping the milestone for this bug, and all that depend on it, to 2.2. In the absence of someone actively working on this, there is no point keeping it on the 2.0 milestone. If someone wants to work on this, fixes to this family would also be accepted on the stable branch. Dave.
Are those test images still available. I'm unable to download them.
If nobody works on the plug-in I could take up some. Looking trouhg the bug reports and looking at some plug-in's Ithink the first thing to do is check if the algorithm's are suitable for RGBA images. I tried changing the despeckle plug-in after several days of research and reading lot of documents I must conclude that there is not much to find about RGBA effects. The despeckle plugin handles RGBA images fairly well if using one of the vector soloutions (but they are very slow). In order to proceed I think a decision needs to be made for each plug-in are we going to support TGBA or not Stil to do : #72869 Propagate plug-in #72864 Emboss plug-in #72862 Despeckle plug-in
+ Trace 51249
Not all tracked bugs are on the 2.2 milestone. It doesn't make much sense to keep the tracking bug on the 2.2 milestone then.
This "feature" (bug, really) needs to be a user preference. I very often work with images that have fully valid RGB data in all areas of the image, including transparent and semi-transparent areas. So your fix is a bug for me. The default should obviously be the method that has: a. good performance b. no round-off error c. no data loss via squeezing 0..255 data into, say, 0..42 "the color is arbitrary" is an extreme case of issue "c" in my list, where you squeeze an 8-bit value into 0 bits. Eeeew. This is MASSIVE data loss, and you even burn CPU time to do it. Squeezing #807f7f (nearly grey) into 1 bit/channel makes red. Grey turns into pure and saturated red! This is dreadful, and you wasted CPU cycles to do it.
If you want to make some parts of an image transparent while still keeping the color data then you should use a layer mask, not the alpha channel. Using a mask ensures that the RGB channels will not be modified. But if a pixel is fully transparent (alpha channel = 0), then the contents of the RGB channels become unspecified: some operations may keep the color intact while some other operations may destroy it. There are examples of both in the GIMP and the GIMP does not make any promises that the current behaviour of some operations will not change in the future. As the color of these pixels is unspecified, using them in any operation is a bug. There has been a lot of debate about masks, alpha channels and transparency. So before you argue about this, I suggest that you read the related bug reports and the archives of the gimp-developer mailing list.
I'm afraid you'll be getting bug reports for this behaviour forever. Because: I have a simple PNG image. It has RGBA channels, all full of information, I want to edit it as such and save it as such at the end. In the instant I load to the Gimp, RGB info in pixels with A=0 may be destroyed (this does not happen today, but there's no promise). So I don't care there are layer masks, no matter how more powerful, because I have a PNG image to start with. The root of the problem is that you enforce a policy where you should provide a mechanism.
Well, the root of the problem is that many file formats do not specify how their transparency information is supposed to be handled. The only cases for which there is no ambiguity are the file formats that use pre-multiplied alpha or indexed transparency: in these cases, the color information is simply lost. Some file formats mention a policy regarding how the RGB values of transparent pixels should be handled. But even when the file format mentions that the RGB values are unspecified, this has been abused by some users or developers who assumed that they could use them. The PNG example is interesting because the PNG specification mentions that the alpha channel could be used for different purposes and if it is used for creating non-rectangular images, then: "fully transparent pixels should all be assigned the same colour value for best compression." You may be right about the policy vs. mechanism. IMHO, the mechanism for solving this problem should be in the file plug-ins: for the file formats supporting transparency, if there is any doubt about whether the RGB values of fully transparent pixels are meaningful or not, then the load plug-in for this file format should offer the option to load the transparency information into a mask instead of the alpha channel. Among the benefits of this solution, it would be easier for the user to see the color associated with the hidden pixels (disable the mask). It would also improve the consistency of the GIMP and it would help the users to have the right expectations about the various operations performed on the image.
This bug apparently still affects the Lighting Effects plug-in, which was supposedly fixed: "Bug 105496: Incorrect RGBA resampling in Lighting Effects plug-in". (See Comment #10 From Yeti 2003-02-07 10:50 above.) When following the "Golden Text" tutorial procedures (using WinGIMP 2.2.3), there are semitransparent colors in the "transparent" area around the text.
In discussion on #gimp, you showed what the odd effects looked like, and I believe you, but you were not able to give a complete recipe for reproducing them, so it is difficult to follow up on this. I have not myself been able to reproduce the problem that you showed.
*** Bug 602228 has been marked as a duplicate of this bug. ***
Hello guys, Can you tell me please what about this version? I didn't understand what it is this version. Is it 2.0.0 – 2.0.6 ??????? Merci
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/gimp/issues/17.