diff --git a/src/Greenshot.Editor/Drawing/DrawableContainer.cs b/src/Greenshot.Editor/Drawing/DrawableContainer.cs index cac23dc3a..bed1d7618 100644 --- a/src/Greenshot.Editor/Drawing/DrawableContainer.cs +++ b/src/Greenshot.Editor/Drawing/DrawableContainer.cs @@ -410,7 +410,9 @@ namespace Greenshot.Editor.Drawing { if (clipRectangle.Width != 0 && clipRectangle.Height != 0) { - foreach (IFilter filter in Filters) + // GrayscaleFilter is an inverted filter. Combining two makes the entire image greyscale. + // Skip any GrayscaleFilter here so outer drawing logic can handle them to combine multiple + foreach (IFilter filter in Filters.Where(x => x is not GrayscaleFilter)) { if (filter.Invert) { diff --git a/src/Greenshot.Editor/Drawing/DrawableContainerList.cs b/src/Greenshot.Editor/Drawing/DrawableContainerList.cs index 642c4ca05..a3027808e 100644 --- a/src/Greenshot.Editor/Drawing/DrawableContainerList.cs +++ b/src/Greenshot.Editor/Drawing/DrawableContainerList.cs @@ -331,6 +331,8 @@ namespace Greenshot.Editor.Drawing var drawableContainers = this.Cast(); + ApplyGrayscaleFilters(g, drawableContainers, bitmap); + foreach (var dc in drawableContainers) { if (dc.Parent == null) @@ -343,6 +345,30 @@ namespace Greenshot.Editor.Drawing dc.DrawContent(g, bitmap, renderMode, clipRectangle); } } + + // To support multiple grayscale filters we merge them before applying them + static void ApplyGrayscaleFilters(Graphics g, IEnumerable drawableContainers, Bitmap bitmap) + { + if (bitmap is null) return; + + var grayFilters = drawableContainers.SelectMany(x => x.Filters.Where(filter => filter is GrayscaleFilter).Cast()); + // These rects shall not be grayed out + var rects = grayFilters.Select(x => x.Parent.Bounds); + + // full bitmap size because the GrayscaleFilter is an inverted filter covering the full bitmap + var applyRect = new NativeRect(0, 0, bitmap.Width, bitmap.Height); + + GraphicsState state = g.Save(); + // Set a clipping region and then exclude the highlight areas so only "everything else" gets greyed out + g.SetClip(applyRect); + foreach (var rect in rects) + { + g.ExcludeClip(rect); + } + GrayscaleFilter.DrawGray(g, bitmap, applyRect); + + g.Restore(state); + } } ///