This commit is contained in:
Jan Klass 2025-08-19 00:47:43 +08:00 committed by GitHub
commit 681fbd5cf2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 41 additions and 6 deletions

View file

@ -410,7 +410,9 @@ namespace Greenshot.Editor.Drawing
{ {
if (clipRectangle.Width != 0 && clipRectangle.Height != 0) 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) if (filter.Invert)
{ {

View file

@ -34,6 +34,7 @@ using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Configuration; using Greenshot.Editor.Configuration;
using Greenshot.Editor.Drawing.Fields; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Editor.Drawing.Filters;
using Greenshot.Editor.Forms; using Greenshot.Editor.Forms;
using Greenshot.Editor.Memento; using Greenshot.Editor.Memento;
@ -328,9 +329,12 @@ namespace Greenshot.Editor.Drawing
return; return;
} }
foreach (var drawableContainer in this) var drawableContainers = this.Cast<DrawableContainer>();
ApplyGrayscaleFilters(g, drawableContainers, bitmap);
foreach (var dc in drawableContainers)
{ {
var dc = (DrawableContainer) drawableContainer;
if (dc.Parent == null) if (dc.Parent == null)
{ {
continue; continue;
@ -341,6 +345,30 @@ namespace Greenshot.Editor.Drawing
dc.DrawContent(g, bitmap, renderMode, clipRectangle); dc.DrawContent(g, bitmap, renderMode, clipRectangle);
} }
} }
// To support multiple grayscale filters we merge them before applying them
static void ApplyGrayscaleFilters(Graphics g, IEnumerable<DrawableContainer> drawableContainers, Bitmap bitmap)
{
if (bitmap is null) return;
var grayFilters = drawableContainers.SelectMany(x => x.Filters.Where(filter => filter is GrayscaleFilter).Cast<GrayscaleFilter>());
// 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);
}
} }
/// <summary> /// <summary>

View file

@ -56,6 +56,13 @@ namespace Greenshot.Editor.Drawing.Filters
graphics.ExcludeClip(rect); graphics.ExcludeClip(rect);
} }
DrawGray(graphics, applyBitmap, applyRect);
graphics.Restore(state);
}
public static void DrawGray(Graphics graphics, Bitmap applyBitmap, NativeRect applyRect)
{
ColorMatrix grayscaleMatrix = new ColorMatrix(new[] ColorMatrix grayscaleMatrix = new ColorMatrix(new[]
{ {
new[] new[]
@ -84,8 +91,6 @@ namespace Greenshot.Editor.Drawing.Filters
ia.SetColorMatrix(grayscaleMatrix); ia.SetColorMatrix(grayscaleMatrix);
graphics.DrawImage(applyBitmap, applyRect, applyRect.X, applyRect.Y, applyRect.Width, applyRect.Height, GraphicsUnit.Pixel, ia); graphics.DrawImage(applyBitmap, applyRect, applyRect.X, applyRect.Y, applyRect.Width, applyRect.Height, GraphicsUnit.Pixel, ia);
} }
graphics.Restore(state);
} }
} }
} }