From 9684295f06232e7d58bbe3c4c5aa70a10eed9ee6 Mon Sep 17 00:00:00 2001 From: TOMAS RADIL Date: Fri, 8 Mar 2024 10:55:18 +0100 Subject: [PATCH] GrayScaleMode support for WPF .NET Frameworks projects --- .../ColorMatrixs.cs | 23 ++++++ .../GMapControl.cs | 61 ++++++++++++++++ .../GMap.NET.WindowsPresentation/GMapImage.cs | 70 ++++++++++++++++++- 3 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 GMap.NET/GMap.NET.WindowsPresentation/ColorMatrixs.cs diff --git a/GMap.NET/GMap.NET.WindowsPresentation/ColorMatrixs.cs b/GMap.NET/GMap.NET.WindowsPresentation/ColorMatrixs.cs new file mode 100644 index 00000000..037bb5c3 --- /dev/null +++ b/GMap.NET/GMap.NET.WindowsPresentation/ColorMatrixs.cs @@ -0,0 +1,23 @@ +#if NETFRAMEWORK && !NET5_0_OR_GREATER +using System.Drawing.Imaging; +#endif + +namespace GMap.NET.WindowsPresentation +{ +#if NETFRAMEWORK && !NET5_0_OR_GREATER + public static class ColorMatrixs + { + public static readonly ColorMatrix GrayScale = new ColorMatrix(new[] + { + new[] {.3f, .3f, .3f, 0, 0}, new[] {.59f, .59f, .59f, 0, 0}, + new[] {.11f, .11f, .11f, 0, 0}, new float[] {0, 0, 0, 1, 0}, new float[] {0, 0, 0, 0, 1} + }); + + public static readonly ColorMatrix Negative = new ColorMatrix(new[] + { + new float[] {-1, 0, 0, 0, 0}, new float[] {0, -1, 0, 0, 0}, new float[] {0, 0, -1, 0, 0}, + new float[] {0, 0, 0, 1, 0}, new float[] {1, 1, 1, 0, 1} + }); + } +#endif +} diff --git a/GMap.NET/GMap.NET.WindowsPresentation/GMapControl.cs b/GMap.NET/GMap.NET.WindowsPresentation/GMapControl.cs index cb42681c..db10a16e 100644 --- a/GMap.NET/GMap.NET.WindowsPresentation/GMapControl.cs +++ b/GMap.NET/GMap.NET.WindowsPresentation/GMapControl.cs @@ -3,6 +3,9 @@ using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; +#if NETFRAMEWORK && !NET5_0_OR_GREATER +using System.Drawing.Imaging; +#endif using System.Globalization; using System.Linq; using System.Threading.Tasks; @@ -407,6 +410,64 @@ public bool TouchEnabled #endregion +#if NETFRAMEWORK && !NET5_0_OR_GREATER + private bool _grayScale; + + [Category("GMap.NET")] + public bool GrayScaleMode + { + get + { + return _grayScale; + } + set + { + _grayScale = value; + ColorMatrix = value ? ColorMatrixs.GrayScale : null; + } + } + + private bool _negative; + + [Category("GMap.NET")] + public bool NegativeMode + { + get + { + return _negative; + } + set + { + _negative = value; + ColorMatrix = value ? ColorMatrixs.Negative : null; + } + } + + ColorMatrix _colorMatrix; + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Browsable(false)] + public ColorMatrix ColorMatrix + { + get + { + return _colorMatrix; + } + set + { + _colorMatrix = value; + if (GMapProvider.TileImageProxy != null && GMapProvider.TileImageProxy is GMapImageProxy) + { + (GMapProvider.TileImageProxy as GMapImageProxy).ColorMatrix = value; + if (_core != null && _core.IsStarted) + { + ReloadMap(); + } + } + } + } +#endif + readonly Core _core = new Core(); PointLatLng _selectionStart; diff --git a/GMap.NET/GMap.NET.WindowsPresentation/GMapImage.cs b/GMap.NET/GMap.NET.WindowsPresentation/GMapImage.cs index 65b378d9..b0b67808 100644 --- a/GMap.NET/GMap.NET.WindowsPresentation/GMapImage.cs +++ b/GMap.NET/GMap.NET.WindowsPresentation/GMapImage.cs @@ -1,4 +1,9 @@ using System.Diagnostics; +#if NETFRAMEWORK && !NET5_0_OR_GREATER +using System.Drawing; +using System.Drawing.Imaging; +using GMap.NET.Internals; +#endif using System.IO; using System.Windows.Media; using System.Windows.Media.Imaging; @@ -44,22 +49,51 @@ public static void Enable() public static readonly GMapImageProxy Instance = new GMapImageProxy(); +#if NETFRAMEWORK && !NET5_0_OR_GREATER + internal ColorMatrix ColorMatrix; + + static readonly bool Win7OrLater = Stuff.IsRunningOnWin7OrLater(); +#endif + public override PureImage FromStream(Stream stream) { if (stream != null) { try { + GMapImage ret = null; +#if NETFRAMEWORK && !NET5_0_OR_GREATER + if (ColorMatrix == null) + { +#endif var m = BitmapFrame.Create(stream, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.OnLoad); - - var ret = new GMapImage {Img = m}; + ret = new GMapImage { Img = m }; +#if NETFRAMEWORK && !NET5_0_OR_GREATER + } + else + { + var m = Image.FromStream(stream, true, !Win7OrLater); + var bitmap = ApplyColorMatrix(m, ColorMatrix); + using (var memory = new MemoryStream()) + { + bitmap.Save(memory, ImageFormat.Png); + memory.Position = 0; + + var bitmapImage = new BitmapImage(); + bitmapImage.BeginInit(); + bitmapImage.StreamSource = memory; + bitmapImage.CacheOption = BitmapCacheOption.OnLoad; + bitmapImage.EndInit(); + ret = new GMapImage { Img = bitmapImage }; + } + } +#endif if (ret.Img.CanFreeze) { ret.Img.Freeze(); } - return ret; } catch @@ -95,6 +129,36 @@ public override bool Save(Stream stream, PureImage image) return false; } + +#if NETFRAMEWORK && !NET5_0_OR_GREATER + Bitmap ApplyColorMatrix(Image original, ColorMatrix matrix) + { + // create a blank bitmap the same size as original + var newBitmap = new Bitmap(original.Width, original.Height); + + using (original) // destroy original + { + // get a graphics object from the new image + using (var g = Graphics.FromImage(newBitmap)) + { + // set the color matrix attribute + using (var attributes = new ImageAttributes()) + { + attributes.SetColorMatrix(matrix); + g.DrawImage(original, + new Rectangle(0, 0, original.Width, original.Height), + 0, + 0, + original.Width, + original.Height, + GraphicsUnit.Pixel, + attributes); + } + } + } + return newBitmap; + } +#endif } //internal class TileVisual : FrameworkElement