diff --git a/src/Greenshot.Base/Core/ClipboardHelper.cs b/src/Greenshot.Base/Core/ClipboardHelper.cs index 286d6b0f1..b67d4a03a 100644 --- a/src/Greenshot.Base/Core/ClipboardHelper.cs +++ b/src/Greenshot.Base/Core/ClipboardHelper.cs @@ -867,11 +867,17 @@ EndSelection:<<<<<<<4 { // Create the stream for the clipboard dibStream = new MemoryStream(); - var dibBytes = ((Bitmap)imageToSave).ConvertToDib(); - dibStream.Write(dibBytes,0, dibBytes.Length); - // Set the DIB to the clipboard DataObject - dataObject.SetData(DataFormats.Dib, false, dibStream); + if (!FileFormatHandlerRegistry.TrySaveToStream((Bitmap)imageToSave, dibStream, DataFormats.Dib)) + { + dibStream.Dispose(); + dibStream = null; + } + else + { + // Set the DIB to the clipboard DataObject + dataObject.SetData(DataFormats.Dib, false, dibStream); + } } } catch (Exception dibEx) diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/DefaultFileFormatHandler.cs b/src/Greenshot.Base/Core/FileFormatHandlers/DefaultFileFormatHandler.cs index 866bc3f97..74d2e3573 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/DefaultFileFormatHandler.cs +++ b/src/Greenshot.Base/Core/FileFormatHandlers/DefaultFileFormatHandler.cs @@ -31,7 +31,7 @@ using Greenshot.Base.Interfaces.Drawing; namespace Greenshot.Base.Core.FileFormatHandlers { /// - /// THis is the default .NET bitmap file format handler + /// This is the default .NET bitmap file format handler /// public class DefaultFileFormatHandler : IFileFormatHandler { @@ -56,7 +56,7 @@ namespace Greenshot.Base.Core.FileFormatHandlers return false; } - return OurExtensions.Contains(extension); + return OurExtensions.Contains(extension?.ToLowerInvariant()); } /// diff --git a/src/Greenshot.Base/Core/DibHelper.cs b/src/Greenshot.Base/Core/FileFormatHandlers/DibFileFormatHandler.cs similarity index 74% rename from src/Greenshot.Base/Core/DibHelper.cs rename to src/Greenshot.Base/Core/FileFormatHandlers/DibFileFormatHandler.cs index 59af37414..79c78ef27 100644 --- a/src/Greenshot.Base/Core/DibHelper.cs +++ b/src/Greenshot.Base/Core/FileFormatHandlers/DibFileFormatHandler.cs @@ -1,48 +1,100 @@ /* * Greenshot - a free and open source screenshot tool * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom - * + * * For more information see: https://getgreenshot.org/ * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ using System; +using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; +using System.IO; +using System.Linq; using System.Runtime.InteropServices; +using Greenshot.Base.Interfaces; +using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.UnmanagedHelpers; -namespace Greenshot.Base.Core +namespace Greenshot.Base.Core.FileFormatHandlers { /// - /// Though Greenshot implements the specs for the DIB image format, - /// it seems to cause a lot of issues when using the clipboard. - /// There is some research done about the DIB on the clipboard, this code is based upon the information - /// here + /// This handles creating a DIB (Device Independent Bitmap) on the clipboard /// - internal static class DibHelper + public class DibFileFormatHandler : IFileFormatHandler { private const double DpiToPelsPerMeter = 39.3701; + private static readonly string [] OurExtensions = { "dib" }; + + /// + public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) + { + if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) + { + return Enumerable.Empty(); + } + + return OurExtensions; + } + + /// + public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension) + { + if (string.IsNullOrEmpty(extension) || fileFormatHandlerAction != FileFormatHandlerActions.SaveToStream) + { + return false; + } + + return OurExtensions.Contains(extension.ToLowerInvariant()); + } + + /// + public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension) + { + return int.MaxValue; + } + + /// + public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) + { + var dibBytes = ConvertToDib(bitmap); + destination.Write(dibBytes, 0, dibBytes.Length); + return true; + } + + /// + public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) + { + throw new NotImplementedException(); + } + + /// + public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface) + { + throw new NotImplementedException(); + } + /// /// Converts the Bitmap to a Device Independent Bitmap format of type BITFIELDS. /// /// Bitmap to convert to DIB /// byte{} with the image converted to DIB - public static byte[] ConvertToDib(this Bitmap sourceBitmap) + private static byte[] ConvertToDib(Bitmap sourceBitmap) { if (sourceBitmap == null) throw new ArgumentNullException(nameof(sourceBitmap)); diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs b/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs index 9d41f25e6..93db7f5d2 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs +++ b/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs @@ -20,6 +20,8 @@ */ using System.Collections.Generic; +using System.Drawing; +using System.IO; using System.Linq; using Greenshot.Base.Interfaces; @@ -27,7 +29,7 @@ namespace Greenshot.Base.Core.FileFormatHandlers { public static class FileFormatHandlerRegistry { - public static readonly IList FileFormatHandlers = new List(); + public static IList FileFormatHandlers { get; } = new List(); static FileFormatHandlerRegistry() { @@ -40,5 +42,29 @@ namespace Greenshot.Base.Core.FileFormatHandlers { return FileFormatHandlers.SelectMany(ffh => ffh.SupportedExtensions(fileFormatHandlerAction)).Distinct(); } + + /// + /// This wrapper method for TrySaveToStream will do: + /// Find all the IFileFormatHandler which support the action for the supplied extension. + /// Take the first, to call the TrySaveToStream on. + /// + /// Bitmap + /// Stream + /// string + /// bool + public static bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) + { + var fileFormatHandler = FileFormatHandlers + .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension)) + .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension)) + .FirstOrDefault(); + + if (fileFormatHandler == null) + { + return false; + } + + return fileFormatHandler.TrySaveToStream(bitmap, destination, extension); + } } } diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs b/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs index 93885cde0..5370f8934 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs +++ b/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs @@ -52,7 +52,7 @@ namespace Greenshot.Base.Core.FileFormatHandlers return false; } - return OurExtensions.Contains(extension); + return OurExtensions.Contains(extension?.ToLowerInvariant()); } diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/IconFileFormatHandler.cs b/src/Greenshot.Base/Core/FileFormatHandlers/IconFileFormatHandler.cs index 92a21a1ac..ab92f814e 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/IconFileFormatHandler.cs +++ b/src/Greenshot.Base/Core/FileFormatHandlers/IconFileFormatHandler.cs @@ -59,7 +59,7 @@ namespace Greenshot.Base.Core.FileFormatHandlers return false; } - return OurExtensions.Contains(extension); + return OurExtensions.Contains(extension?.ToLowerInvariant()); } /// diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs b/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs index c4ee2ec0f..84ed74c17 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs +++ b/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs @@ -55,7 +55,7 @@ namespace Greenshot.Base.Core.FileFormatHandlers return false; } - return OurExtensions.Contains(extension); + return OurExtensions.Contains(extension?.ToLowerInvariant()); } /// public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension)