From 52c042572f3a0593d4abd04888f4e5afb531c222 Mon Sep 17 00:00:00 2001 From: Robin Krom Date: Wed, 16 Feb 2022 21:21:24 +0100 Subject: [PATCH] Added the SurfaceOutputSettings to the IFileFormatHandler, changed the TryLoad to LoadDrawablesFromStream to enable returning multiple values. --- src/Greenshot.Base/Core/ClipboardHelper.cs | 37 ++-- .../FileFormatHandlerExtensions.cs | 15 +- src/Greenshot.Base/Core/ImageOutput.cs | 177 +----------------- src/Greenshot.Base/Core/NetworkHelper.cs | 9 +- .../Interfaces/IFileFormatHandler.cs | 11 +- .../Plugin/SurfaceOutputSettings.cs | 23 ++- .../AbstractFileFormatHandler.cs | 20 +- .../DefaultFileFormatHandler.cs | 9 +- .../DibFileFormatHandler.cs | 5 +- .../GreenshotFileFormatHandler.cs | 11 +- .../IconFileFormatHandler.cs | 5 +- .../MetaFileFormatHandler.cs | 13 +- .../SvgFileFormatHandler.cs | 21 +-- .../WpfFileFormatHandler.cs | 11 +- src/Greenshot/Forms/SettingsForm.Designer.cs | 2 +- 15 files changed, 108 insertions(+), 261 deletions(-) diff --git a/src/Greenshot.Base/Core/ClipboardHelper.cs b/src/Greenshot.Base/Core/ClipboardHelper.cs index c3c2a9805..6030ecf16 100644 --- a/src/Greenshot.Base/Core/ClipboardHelper.cs +++ b/src/Greenshot.Base/Core/ClipboardHelper.cs @@ -303,11 +303,11 @@ EndSelection:<<<<<<<4 } var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances(); var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList(); - foreach (var fileData in IterateClipboardContent(dataObject)) + foreach (var (stream, filename) in IterateClipboardContent(dataObject)) { try { - var extension = Path.GetExtension(fileData.filename)?.ToLowerInvariant(); + var extension = Path.GetExtension(filename)?.ToLowerInvariant(); if (supportedExtensions.Contains(extension)) { return true; @@ -319,7 +319,7 @@ EndSelection:<<<<<<<4 } finally { - fileData.stream?.Dispose(); + stream?.Dispose(); } } @@ -609,15 +609,10 @@ EndSelection:<<<<<<<4 continue; } - IDrawableContainer drawableContainer = null; - + IEnumerable drawableContainers; try { - if (!fileFormatHandlers.TryLoadDrawableFromStream(fileData.stream, extension, out drawableContainer)) - { - continue; - } - + drawableContainers = fileFormatHandlers.LoadDrawablesFromStream(fileData.stream, extension); } catch (Exception ex) { @@ -629,7 +624,10 @@ EndSelection:<<<<<<<4 fileData.stream?.Dispose(); } // If we get here, there is an image - yield return drawableContainer; + foreach (var container in drawableContainers) + { + yield return container; + } } // check if files are supplied @@ -643,12 +641,10 @@ EndSelection:<<<<<<<4 IDrawableContainer drawableContainer = null; using FileStream fileStream = new FileStream(imageFile, FileMode.Open, FileAccess.Read, FileShare.Read); + IEnumerable drawableContainers; try { - if (!fileFormatHandlers.TryLoadDrawableFromStream(fileStream, extension, out drawableContainer)) - { - continue; - } + drawableContainers = fileFormatHandlers.LoadDrawablesFromStream(fileStream, extension); } catch (Exception ex) { @@ -656,7 +652,10 @@ EndSelection:<<<<<<<4 continue; } // If we get here, there is an image - yield return drawableContainer; + foreach (var container in drawableContainers) + { + yield return container; + } } } @@ -884,11 +883,7 @@ EndSelection:<<<<<<<4 // From here, imageStream is a valid stream var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances(); - if (!fileFormatHandlers.TryLoadDrawableFromStream(imageStream, format, out drawableContainer)) - { - return drawableContainer; - } - return null; + return fileFormatHandlers.LoadDrawablesFromStream(imageStream, format).FirstOrDefault(); } /// diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerExtensions.cs b/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerExtensions.cs index d6310692d..54eed9762 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerExtensions.cs +++ b/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerExtensions.cs @@ -25,6 +25,7 @@ using System.IO; using System.Linq; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Drawing; +using Greenshot.Base.Interfaces.Plugin; namespace Greenshot.Base.Core.FileFormatHandlers { @@ -84,7 +85,7 @@ namespace Greenshot.Base.Core.FileFormatHandlers /// string /// ISurface /// bool - public static bool TrySaveToStream(this IEnumerable fileFormatHandlers, Bitmap bitmap, Stream destination, string extension, ISurface surface = null) + public static bool TrySaveToStream(this IEnumerable fileFormatHandlers, Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null) { extension = NormalizeExtension(extension); @@ -114,10 +115,9 @@ namespace Greenshot.Base.Core.FileFormatHandlers /// IEnumerable{IFileFormatHandler} /// Stream /// string - /// IDrawableContainer out /// ISurface - /// bool true if it was successful - public static bool TryLoadDrawableFromStream(this IEnumerable fileFormatHandlers, Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parentSurface = null) + /// IEnumerable{IDrawableContainer} + public static IEnumerable LoadDrawablesFromStream(this IEnumerable fileFormatHandlers, Stream stream, string extension, ISurface parentSurface = null) { extension = NormalizeExtension(extension); @@ -126,13 +126,12 @@ namespace Greenshot.Base.Core.FileFormatHandlers .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadDrawableFromStream, extension)) .FirstOrDefault(); - if (loadfileFormatHandler == null) + if (loadfileFormatHandler != null) { - drawableContainer = null; - return false; + return loadfileFormatHandler.LoadDrawablesFromStream(stream, extension, parentSurface); } - return loadfileFormatHandler.TryLoadDrawableFromStream(stream, extension, out drawableContainer, parentSurface); + return Enumerable.Empty(); } /// diff --git a/src/Greenshot.Base/Core/ImageOutput.cs b/src/Greenshot.Base/Core/ImageOutput.cs index 9a8695b0d..e722921f1 100644 --- a/src/Greenshot.Base/Core/ImageOutput.cs +++ b/src/Greenshot.Base/Core/ImageOutput.cs @@ -20,8 +20,6 @@ */ using System; -using System.Collections.Generic; -using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; @@ -124,7 +122,7 @@ namespace Greenshot.Base.Core try { - // Check if we want to use a memory stream, to prevent issues with non seakable streams + // Check if we want to use a memory stream, to prevent issues with non seekable streams // The save is made to the targetStream, this is directed to either the MemoryStream or the original Stream targetStream = stream; if (!stream.CanSeek) @@ -136,7 +134,7 @@ namespace Greenshot.Base.Core } var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances(); - if (!fileFormatHandlers.TrySaveToStream(imageToSave as Bitmap, targetStream, outputSettings.Format.ToString(), surface)) + if (!fileFormatHandlers.TrySaveToStream(imageToSave as Bitmap, targetStream, outputSettings.Format.ToString(), surface, outputSettings)) { return; } @@ -153,89 +151,6 @@ namespace Greenshot.Base.Core } } - /// - /// Write the passed Image to a tmp-file and call an external process, than read the file back and write it to the targetStream - /// - /// Image to pass to the external process - /// stream to write the processed image to - /// - private static bool ProcessPngImageExternally(Image imageToProcess, Stream targetStream) - { - if (string.IsNullOrEmpty(CoreConfig.OptimizePNGCommand)) - { - return false; - } - - if (!File.Exists(CoreConfig.OptimizePNGCommand)) - { - Log.WarnFormat("Can't find 'OptimizePNGCommand' {0}", CoreConfig.OptimizePNGCommand); - return false; - } - - string tmpFileName = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + ".png"); - try - { - using (FileStream tmpStream = File.Create(tmpFileName)) - { - Log.DebugFormat("Writing png to tmp file: {0}", tmpFileName); - imageToProcess.Save(tmpStream, ImageFormat.Png); - if (Log.IsDebugEnabled) - { - Log.DebugFormat("File size before processing {0}", new FileInfo(tmpFileName).Length); - } - } - - if (Log.IsDebugEnabled) - { - Log.DebugFormat("Starting : {0}", CoreConfig.OptimizePNGCommand); - } - - ProcessStartInfo processStartInfo = new ProcessStartInfo(CoreConfig.OptimizePNGCommand) - { - Arguments = string.Format(CoreConfig.OptimizePNGCommandArguments, tmpFileName), - CreateNoWindow = true, - RedirectStandardOutput = true, - RedirectStandardError = true, - UseShellExecute = false - }; - using Process process = Process.Start(processStartInfo); - if (process != null) - { - process.WaitForExit(); - if (process.ExitCode == 0) - { - if (Log.IsDebugEnabled) - { - Log.DebugFormat("File size after processing {0}", new FileInfo(tmpFileName).Length); - Log.DebugFormat("Reading back tmp file: {0}", tmpFileName); - } - - byte[] processedImage = File.ReadAllBytes(tmpFileName); - targetStream.Write(processedImage, 0, processedImage.Length); - return true; - } - - Log.ErrorFormat("Error while processing PNG image: {0}", process.ExitCode); - Log.ErrorFormat("Output: {0}", process.StandardOutput.ReadToEnd()); - Log.ErrorFormat("Error: {0}", process.StandardError.ReadToEnd()); - } - } - catch (Exception e) - { - Log.Error("Error while processing PNG image: ", e); - } - finally - { - if (File.Exists(tmpFileName)) - { - Log.DebugFormat("Cleaning up tmp file: {0}", tmpFileName); - File.Delete(tmpFileName); - } - } - - return false; - } - /// /// Create an image from a surface with the settings from the output settings applied /// @@ -607,93 +522,5 @@ namespace Greenshot.Base.Core File.Delete(path); } } - - /// - /// Write the images to the stream as icon - /// Every image is resized to 256x256 (but the content maintains the aspect ratio) - /// - /// Stream to write to - /// List of images - public static void WriteIcon(Stream stream, IList images) - { - var binaryWriter = new BinaryWriter(stream); - // - // ICONDIR structure - // - binaryWriter.Write((short) 0); // reserved - binaryWriter.Write((short) 1); // image type (icon) - binaryWriter.Write((short) images.Count); // number of images - - IList imageSizes = new List(); - IList encodedImages = new List(); - foreach (var image in images) - { - // Pick the best fit - var sizes = new[] - { - 16, 32, 48 - }; - int size = 256; - foreach (var possibleSize in sizes) - { - if (image.Width <= possibleSize && image.Height <= possibleSize) - { - size = possibleSize; - break; - } - } - - var imageStream = new MemoryStream(); - if (image.Width == size && image.Height == size) - { - using var clonedImage = ImageHelper.Clone(image, PixelFormat.Format32bppArgb); - clonedImage.Save(imageStream, ImageFormat.Png); - imageSizes.Add(new Size(size, size)); - } - else - { - // Resize to the specified size, first make sure the image is 32bpp - using var clonedImage = ImageHelper.Clone(image, PixelFormat.Format32bppArgb); - using var resizedImage = ImageHelper.ResizeImage(clonedImage, true, true, Color.Empty, size, size, null); - resizedImage.Save(imageStream, ImageFormat.Png); - imageSizes.Add(resizedImage.Size); - } - - imageStream.Seek(0, SeekOrigin.Begin); - encodedImages.Add(imageStream); - } - - // - // ICONDIRENTRY structure - // - const int iconDirSize = 6; - const int iconDirEntrySize = 16; - - var offset = iconDirSize + (images.Count * iconDirEntrySize); - for (int i = 0; i < images.Count; i++) - { - var imageSize = imageSizes[i]; - // Write the width / height, 0 means 256 - binaryWriter.Write(imageSize.Width == 256 ? (byte) 0 : (byte) imageSize.Width); - binaryWriter.Write(imageSize.Height == 256 ? (byte) 0 : (byte) imageSize.Height); - binaryWriter.Write((byte) 0); // no pallete - binaryWriter.Write((byte) 0); // reserved - binaryWriter.Write((short) 0); // no color planes - binaryWriter.Write((short) 32); // 32 bpp - binaryWriter.Write((int) encodedImages[i].Length); // image data length - binaryWriter.Write(offset); - offset += (int) encodedImages[i].Length; - } - - binaryWriter.Flush(); - // - // Write image data - // - foreach (var encodedImage in encodedImages) - { - encodedImage.WriteTo(stream); - encodedImage.Dispose(); - } - } } } \ No newline at end of file diff --git a/src/Greenshot.Base/Core/NetworkHelper.cs b/src/Greenshot.Base/Core/NetworkHelper.cs index e12a63712..15a964f5b 100644 --- a/src/Greenshot.Base/Core/NetworkHelper.cs +++ b/src/Greenshot.Base/Core/NetworkHelper.cs @@ -106,7 +106,9 @@ namespace Greenshot.Base.Core using var memoryStream = GetAsMemoryStream(url); try { - if (fileFormatHandlers.TryLoadDrawableFromStream(memoryStream, match.Success ? match.Groups["extension"]?.Value : null, out var drawableContainer)) + var extension = match.Success ? match.Groups["extension"]?.Value : null; + var drawableContainer = fileFormatHandlers.LoadDrawablesFromStream(memoryStream, extension).FirstOrDefault(); + if (drawableContainer != null) { return drawableContainer; } @@ -132,7 +134,10 @@ namespace Greenshot.Base.Core } using var memoryStream2 = GetAsMemoryStream(match.Value); - if (fileFormatHandlers.TryLoadDrawableFromStream(memoryStream2, match.Success ? match.Groups["extension"]?.Value : null, out var drawableContainer)) + + var extension = match.Success ? match.Groups["extension"]?.Value : null; + var drawableContainer = fileFormatHandlers.LoadDrawablesFromStream(memoryStream2, extension).FirstOrDefault(); + if (drawableContainer != null) { return drawableContainer; } diff --git a/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs b/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs index 934d8fb4d..bd5558857 100644 --- a/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs +++ b/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs @@ -23,6 +23,7 @@ using System.Collections.Generic; using System.Drawing; using System.IO; using Greenshot.Base.Interfaces.Drawing; +using Greenshot.Base.Interfaces.Plugin; namespace Greenshot.Base.Interfaces { @@ -44,7 +45,7 @@ namespace Greenshot.Base.Interfaces /// /// Registry for all the extensions this IFileFormatHandler support /// - IDictionary> SupportedExtensions { get; } + IDictionary> SupportedExtensions { get; } /// /// Priority (from high int.MinValue, low int.MaxValue) of this IFileFormatHandler for the specified action and extension @@ -62,8 +63,9 @@ namespace Greenshot.Base.Interfaces /// Stream /// extension /// ISurface with the elements for those file types which can store a surface (.greenshot) + /// SurfaceOutputSettings /// bool true if it was successful - public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null); + public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null); /// /// @@ -79,9 +81,8 @@ namespace Greenshot.Base.Interfaces /// /// Stream /// string - /// IDrawableContainer out /// ISurface - /// bool true if it was successful - public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parentSurface = null); + /// IEnumerable{IDrawableContainer} + public IEnumerable LoadDrawablesFromStream(Stream stream, string extension, ISurface parentSurface = null); } } diff --git a/src/Greenshot.Base/Interfaces/Plugin/SurfaceOutputSettings.cs b/src/Greenshot.Base/Interfaces/Plugin/SurfaceOutputSettings.cs index ef2a58e2f..efce47bbb 100644 --- a/src/Greenshot.Base/Interfaces/Plugin/SurfaceOutputSettings.cs +++ b/src/Greenshot.Base/Interfaces/Plugin/SurfaceOutputSettings.cs @@ -1,4 +1,25 @@ -using System.Collections.Generic; +/* + * 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.Collections.Generic; using Greenshot.Base.Core; using Greenshot.Base.Core.Enums; using Greenshot.Base.Effects; diff --git a/src/Greenshot.Editor/FileFormatHandlers/AbstractFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/AbstractFileFormatHandler.cs index eee9fb130..fff576267 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/AbstractFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/AbstractFileFormatHandler.cs @@ -24,6 +24,7 @@ using System.Drawing; using System.IO; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Drawing; +using Greenshot.Base.Interfaces.Plugin; using Greenshot.Editor.Drawing; namespace Greenshot.Editor.FileFormatHandlers @@ -31,7 +32,7 @@ namespace Greenshot.Editor.FileFormatHandlers public abstract class AbstractFileFormatHandler : IFileFormatHandler { /// - public IDictionary> SupportedExtensions { get; } = new Dictionary>(); + public IDictionary> SupportedExtensions { get; } = new Dictionary>(); /// public virtual int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension) @@ -39,7 +40,7 @@ namespace Greenshot.Editor.FileFormatHandlers return 0; } - public abstract bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null); + public abstract bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null); public abstract bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap); @@ -48,23 +49,18 @@ namespace Greenshot.Editor.FileFormatHandlers /// /// Stream /// string - /// IDrawableContainer out - /// ISurface - /// bool - public virtual bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parentSurface = null) + /// ISurface + /// IEnumerable{IDrawableContainer} + public virtual IEnumerable LoadDrawablesFromStream(Stream stream, string extension, ISurface parent = null) { if (TryLoadFromStream(stream, extension, out var bitmap)) { - var imageContainer = new ImageContainer(parentSurface) + var imageContainer = new ImageContainer(parent) { Image = bitmap }; - drawableContainer = imageContainer; - return true; + yield return imageContainer; } - - drawableContainer = null; - return true; } } } diff --git a/src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs index d5dc39e14..e5b8c3e2a 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs @@ -28,6 +28,7 @@ using System.Linq; using Greenshot.Base.Core; using Greenshot.Base.IniFile; using Greenshot.Base.Interfaces; +using Greenshot.Base.Interfaces.Plugin; using log4net; namespace Greenshot.Editor.FileFormatHandlers @@ -38,7 +39,7 @@ namespace Greenshot.Editor.FileFormatHandlers public class DefaultFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { private static readonly ILog Log = LogManager.GetLogger(typeof(DefaultFileFormatHandler)); - private readonly List _ourExtensions = new() { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff", ".tif" }; + private readonly IReadOnlyCollection _ourExtensions = new[] { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff", ".tif" }; private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection(); public DefaultFileFormatHandler() { @@ -48,7 +49,7 @@ namespace Greenshot.Editor.FileFormatHandlers } /// - public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null) + public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null) { ImageFormat imageFormat = extension switch { @@ -66,7 +67,7 @@ namespace Greenshot.Editor.FileFormatHandlers { return false; } - + surfaceOutputSettings ??= new SurfaceOutputSettings(); var imageEncoder = ImageCodecInfo.GetImageEncoders().FirstOrDefault(ie => ie.FilenameExtension.ToLowerInvariant().Contains(extension)); if (imageEncoder == null) { @@ -76,7 +77,7 @@ namespace Greenshot.Editor.FileFormatHandlers { Param = { - [0] = new EncoderParameter(Encoder.Quality, CoreConfig.OutputFileJpegQuality) + [0] = new EncoderParameter(Encoder.Quality, surfaceOutputSettings.JPGQuality) } }; // For those images which are with Alpha, but the format doesn't support this, change it to 24bpp diff --git a/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs index a61edf8ff..3a664051a 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs @@ -27,6 +27,7 @@ using System.IO; using System.Runtime.InteropServices; using Greenshot.Base.Core; using Greenshot.Base.Interfaces; +using Greenshot.Base.Interfaces.Plugin; using Greenshot.Base.UnmanagedHelpers; using log4net; @@ -40,7 +41,7 @@ namespace Greenshot.Editor.FileFormatHandlers private const double DpiToPelsPerMeter = 39.3701; private static readonly ILog Log = LogManager.GetLogger(typeof(DibFileFormatHandler)); - private readonly List _ourExtensions = new() { ".dib", ".format17" }; + private readonly IReadOnlyCollection _ourExtensions = new[] { ".dib", ".format17" }; public DibFileFormatHandler() { @@ -50,7 +51,7 @@ namespace Greenshot.Editor.FileFormatHandlers } /// - public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null) + public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null) { var dibBytes = ConvertToDib(bitmap); destination.Write(dibBytes, 0, dibBytes.Length); diff --git a/src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs index abfb507f7..0b956c001 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs @@ -28,6 +28,7 @@ using System.Reflection; using System.Text; using Greenshot.Base.Core; using Greenshot.Base.Interfaces; +using Greenshot.Base.Interfaces.Plugin; using log4net; namespace Greenshot.Editor.FileFormatHandlers @@ -35,7 +36,7 @@ namespace Greenshot.Editor.FileFormatHandlers public class GreenshotFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { private static readonly ILog Log = LogManager.GetLogger(typeof(GreenshotFileFormatHandler)); - private readonly List _ourExtensions = new() { ".greenshot" }; + private readonly IReadOnlyCollection _ourExtensions = new [] { ".greenshot" }; public GreenshotFileFormatHandler() { SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions; @@ -43,7 +44,7 @@ namespace Greenshot.Editor.FileFormatHandlers SupportedExtensions[FileFormatHandlerActions.SaveToStream] = _ourExtensions; } - public override bool TrySaveToStream(Bitmap bitmap, Stream stream, string extension, ISurface surface = null) + public override bool TrySaveToStream(Bitmap bitmap, Stream stream, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null) { if (surface == null) { @@ -112,11 +113,11 @@ namespace Greenshot.Editor.FileFormatHandlers } Log.InfoFormat("Greenshot file format: {0}", greenshotMarker); - const int filesizeLocation = 8 + markerSize; - surfaceFileStream.Seek(-filesizeLocation, SeekOrigin.End); + const int fileSizeLocation = 8 + markerSize; + surfaceFileStream.Seek(-fileSizeLocation, SeekOrigin.End); using BinaryReader reader = new BinaryReader(surfaceFileStream); long bytesWritten = reader.ReadInt64(); - surfaceFileStream.Seek(-(bytesWritten + filesizeLocation), SeekOrigin.End); + surfaceFileStream.Seek(-(bytesWritten + fileSizeLocation), SeekOrigin.End); returnSurface.LoadElementsFromStream(surfaceFileStream); } diff --git a/src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs index 0b08f85a4..d2769d5f0 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs @@ -26,6 +26,7 @@ using System.Drawing.Imaging; using System.IO; using Greenshot.Base.Core; using Greenshot.Base.Interfaces; +using Greenshot.Base.Interfaces.Plugin; using log4net; namespace Greenshot.Editor.FileFormatHandlers @@ -37,7 +38,7 @@ namespace Greenshot.Editor.FileFormatHandlers { private static readonly ILog Log = LogManager.GetLogger(typeof(IconFileFormatHandler)); - private readonly List _ourExtensions = new() { ".ico" }; + private readonly IReadOnlyCollection _ourExtensions = new[] { ".ico" }; public IconFileFormatHandler() { @@ -46,7 +47,7 @@ namespace Greenshot.Editor.FileFormatHandlers SupportedExtensions[FileFormatHandlerActions.SaveToStream] = _ourExtensions; } - public override bool TrySaveToStream(Bitmap bitmap, Stream stream, string extension, ISurface surface = null) + public override bool TrySaveToStream(Bitmap bitmap, Stream stream, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null) { IList images = new List { diff --git a/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs index 6963266a2..04c3825b3 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs @@ -26,6 +26,7 @@ using System.IO; using Greenshot.Base.Core; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Drawing; +using Greenshot.Base.Interfaces.Plugin; using Greenshot.Editor.Drawing; namespace Greenshot.Editor.FileFormatHandlers @@ -35,7 +36,7 @@ namespace Greenshot.Editor.FileFormatHandlers /// public class MetaFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { - private readonly List _ourExtensions = new (){ ".wmf", ".emf" }; + private readonly IReadOnlyCollection _ourExtensions = new[] { ".wmf", ".emf" }; public MetaFileFormatHandler() { @@ -44,7 +45,7 @@ namespace Greenshot.Editor.FileFormatHandlers } /// - public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null) + public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null) { return false; } @@ -69,16 +70,12 @@ namespace Greenshot.Editor.FileFormatHandlers } /// - public override bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface = null) + public override IEnumerable LoadDrawablesFromStream(Stream stream, string extension, ISurface surface = null) { if (Image.FromStream(stream, true, true) is Metafile metaFile) { - drawableContainer = new MetafileContainer(metaFile, surface); - return true; + yield return new MetafileContainer(metaFile, surface); } - - drawableContainer = null; - return false; } } } diff --git a/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs index 0a7938c8d..14a33246e 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs @@ -25,6 +25,7 @@ using System.Drawing; using System.IO; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Drawing; +using Greenshot.Base.Interfaces.Plugin; using Greenshot.Editor.Drawing; using log4net; using Svg; @@ -37,7 +38,7 @@ namespace Greenshot.Editor.FileFormatHandlers public class SvgFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { private static readonly ILog Log = LogManager.GetLogger(typeof(SvgFileFormatHandler)); - private readonly List _ourExtensions = new() { ".svg" }; + private readonly IReadOnlyCollection _ourExtensions = new[] { ".svg" }; public SvgFileFormatHandler() { @@ -62,29 +63,27 @@ namespace Greenshot.Editor.FileFormatHandlers return false; } - public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null) + public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null) { // TODO: Implement this return false; } - public override bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent = null) + public override IEnumerable LoadDrawablesFromStream(Stream stream, string extension, ISurface parent = null) { + SvgDocument svgDocument = null; try { - var svgDocument = SvgDocument.Open(stream); - if (svgDocument != null) - { - drawableContainer = new SvgContainer(svgDocument, parent); - return true; - } + svgDocument = SvgDocument.Open(stream); } catch (Exception ex) { Log.Error("Can't load SVG", ex); } - drawableContainer = null; - return true; + if (svgDocument != null) + { + yield return new SvgContainer(svgDocument, parent); + } } } } diff --git a/src/Greenshot.Editor/FileFormatHandlers/WpfFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/WpfFileFormatHandler.cs index 00393e166..46b414197 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/WpfFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/WpfFileFormatHandler.cs @@ -21,11 +21,13 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Drawing; using System.IO; using System.Windows.Media.Imaging; using Greenshot.Base.Interfaces; using Greenshot.Base.Core; +using Greenshot.Base.Interfaces.Plugin; using log4net; namespace Greenshot.Editor.FileFormatHandlers @@ -36,8 +38,8 @@ namespace Greenshot.Editor.FileFormatHandlers public class WpfFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { private static readonly ILog Log = LogManager.GetLogger(typeof(WpfFileFormatHandler)); - private List LoadFromStreamExtensions { get; } = new() { ".jxr", ".wdp", ".wmp", ".heic", ".heif" }; - private List SaveToStreamExtensions { get; } = new() { ".jxr" }; + private IReadOnlyCollection LoadFromStreamExtensions { get; } = new []{ ".jxr", ".wdp", ".wmp", ".heic", ".heif" }; + private IReadOnlyCollection SaveToStreamExtensions { get; } = new[] { ".jxr" }; public WpfFileFormatHandler() { @@ -47,8 +49,9 @@ namespace Greenshot.Editor.FileFormatHandlers } /// - public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null) + public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null) { + surfaceOutputSettings ??= new SurfaceOutputSettings(); try { var bitmapSource = bitmap.ToBitmapSource(); @@ -56,7 +59,7 @@ namespace Greenshot.Editor.FileFormatHandlers var jpegXrEncoder = new WmpBitmapEncoder(); jpegXrEncoder.Frames.Add(bitmapFrame); // TODO: Support supplying a quality - //jpegXrEncoder.ImageQualityLevel = quality / 100f; + jpegXrEncoder.ImageQualityLevel = surfaceOutputSettings.JPGQuality / 100f; jpegXrEncoder.Save(destination); return true; } diff --git a/src/Greenshot/Forms/SettingsForm.Designer.cs b/src/Greenshot/Forms/SettingsForm.Designer.cs index e8f284850..a48e4b8b0 100644 --- a/src/Greenshot/Forms/SettingsForm.Designer.cs +++ b/src/Greenshot/Forms/SettingsForm.Designer.cs @@ -1257,7 +1257,7 @@ namespace Greenshot.Forms { // // SettingsForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 14F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(451, 431); this.Controls.Add(this.tabcontrol);