diff --git a/src/Greenshot.Base/Core/ClipboardHelper.cs b/src/Greenshot.Base/Core/ClipboardHelper.cs index 6276e9c6e..a6e1da2a0 100644 --- a/src/Greenshot.Base/Core/ClipboardHelper.cs +++ b/src/Greenshot.Base/Core/ClipboardHelper.cs @@ -332,7 +332,7 @@ EndSelection:<<<<<<<4 if (IsValidStream(imageStream)) { // TODO: How to check if we support "just a stream"? - using (ImageHelper.FromStream(imageStream)) + using (ImageIO.FromStream(imageStream)) { // If we get here, there is an image return true; @@ -967,7 +967,7 @@ EndSelection:<<<<<<<4 { SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); // Create the image which is going to be saved so we don't create it multiple times - disposeImage = ImageOutput.CreateImageFromSurface(surface, outputSettings, out imageToSave); + disposeImage = ImageIO.CreateImageFromSurface(surface, outputSettings, out imageToSave); try { // Create PNG stream @@ -976,7 +976,7 @@ EndSelection:<<<<<<<4 pngStream = new MemoryStream(); // PNG works for e.g. Powerpoint SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); - ImageOutput.SaveToStream(imageToSave, null, pngStream, pngOutputSettings); + ImageIO.SaveToStream(imageToSave, null, pngStream, pngOutputSettings); pngStream.Seek(0, SeekOrigin.Begin); // Set the PNG stream dataObject.SetData(FORMAT_PNG, false, pngStream); @@ -1058,7 +1058,7 @@ EndSelection:<<<<<<<4 // Set the HTML if (CoreConfig.ClipboardFormats.Contains(ClipboardFormat.HTML)) { - string tmpFile = ImageOutput.SaveToTmpFile(surface, new SurfaceOutputSettings(OutputFormat.png, 100, false), null); + string tmpFile = ImageIO.SaveToTmpFile(surface, new SurfaceOutputSettings(OutputFormat.png, 100, false), null); string html = GetHtmlString(surface, tmpFile); dataObject.SetText(html, TextDataFormat.Html); } @@ -1076,11 +1076,11 @@ EndSelection:<<<<<<<4 // Check if we can use the previously used image if (imageToSave.PixelFormat != PixelFormat.Format8bppIndexed) { - ImageOutput.SaveToStream(imageToSave, surface, tmpPngStream, pngOutputSettings); + ImageIO.SaveToStream(imageToSave, surface, tmpPngStream, pngOutputSettings); } else { - ImageOutput.SaveToStream(surface, tmpPngStream, pngOutputSettings); + ImageIO.SaveToStream(surface, tmpPngStream, pngOutputSettings); } html = GetHtmlDataUrlString(surface, tmpPngStream); diff --git a/src/Greenshot.Base/Core/ImageHelper.cs b/src/Greenshot.Base/Core/ImageHelper.cs index da5e45de4..a4055f2c9 100644 --- a/src/Greenshot.Base/Core/ImageHelper.cs +++ b/src/Greenshot.Base/Core/ImageHelper.cs @@ -24,16 +24,12 @@ using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; -using System.IO; -using System.Linq; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; using Greenshot.Base.Core.Enums; -using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.Effects; using Greenshot.Base.IniFile; -using Greenshot.Base.Interfaces; using Greenshot.Base.UnmanagedHelpers; using log4net; using Brush = System.Drawing.Brush; @@ -294,127 +290,6 @@ namespace Greenshot.Base.Core return cropRectangle; } - /// - /// Load an image from file - /// - /// - /// - public static Image LoadImage(string filename) - { - if (string.IsNullOrEmpty(filename)) - { - return null; - } - - if (!File.Exists(filename)) - { - return null; - } - - Image fileImage; - Log.InfoFormat("Loading image from file {0}", filename); - // Fixed lock problem Bug #3431881 - using (Stream imageFileStream = File.OpenRead(filename)) - { - fileImage = FromStream(imageFileStream, Path.GetExtension(filename)); - } - - if (fileImage != null) - { - Log.InfoFormat("Information about file {0}: {1}x{2}-{3} Resolution {4}x{5}", filename, fileImage.Width, fileImage.Height, fileImage.PixelFormat, - fileImage.HorizontalResolution, fileImage.VerticalResolution); - } - - return fileImage; - } - - /// - /// Based on: https://www.codeproject.com/KB/cs/IconExtractor.aspx - /// And a hint from: https://www.codeproject.com/KB/cs/IconLib.aspx - /// - /// Stream with the icon information - /// Bitmap with the Vista Icon (256x256) - private static Bitmap ExtractVistaIcon(Stream iconStream) - { - const int sizeIconDir = 6; - const int sizeIconDirEntry = 16; - Bitmap bmpPngExtracted = null; - try - { - byte[] srcBuf = new byte[iconStream.Length]; - iconStream.Read(srcBuf, 0, (int) iconStream.Length); - int iCount = BitConverter.ToInt16(srcBuf, 4); - for (int iIndex = 0; iIndex < iCount; iIndex++) - { - int iWidth = srcBuf[sizeIconDir + sizeIconDirEntry * iIndex]; - int iHeight = srcBuf[sizeIconDir + sizeIconDirEntry * iIndex + 1]; - if (iWidth == 0 && iHeight == 0) - { - int iImageSize = BitConverter.ToInt32(srcBuf, sizeIconDir + sizeIconDirEntry * iIndex + 8); - int iImageOffset = BitConverter.ToInt32(srcBuf, sizeIconDir + sizeIconDirEntry * iIndex + 12); - using MemoryStream destStream = new MemoryStream(); - destStream.Write(srcBuf, iImageOffset, iImageSize); - destStream.Seek(0, SeekOrigin.Begin); - bmpPngExtracted = new Bitmap(destStream); // This is PNG! :) - break; - } - } - } - catch - { - return null; - } - - return bmpPngExtracted; - } - - /// - /// See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms648069%28v=vs.85%29.aspx - /// - /// The file (EXE or DLL) to get the icon from - /// Index of the icon - /// true if the large icon is wanted - /// Icon - public static Icon ExtractAssociatedIcon(string location, int index, bool takeLarge) - { - Shell32.ExtractIconEx(location, index, out var large, out var small, 1); - Icon returnIcon = null; - bool isLarge = false; - bool isSmall = false; - try - { - if (takeLarge && !IntPtr.Zero.Equals(large)) - { - returnIcon = Icon.FromHandle(large); - isLarge = true; - } - else if (!IntPtr.Zero.Equals(small)) - { - returnIcon = Icon.FromHandle(small); - isSmall = true; - } - else if (!IntPtr.Zero.Equals(large)) - { - returnIcon = Icon.FromHandle(large); - isLarge = true; - } - } - finally - { - if (isLarge && !IntPtr.Zero.Equals(small)) - { - User32.DestroyIcon(small); - } - - if (isSmall && !IntPtr.Zero.Equals(large)) - { - User32.DestroyIcon(large); - } - } - - return returnIcon; - } - /// /// Apply the effect to the bitmap /// @@ -1568,7 +1443,7 @@ namespace Greenshot.Base.Core nPercentW = nPercentH; if (canvasUseNewSize) { - destX = Math.Max(0, System.Convert.ToInt32((newWidth - sourceImage.Width * nPercentW) / 2)); + destX = Math.Max(0, Convert.ToInt32((newWidth - sourceImage.Width * nPercentW) / 2)); } } else if ((int) nPercentH == 1) @@ -1576,7 +1451,7 @@ namespace Greenshot.Base.Core nPercentH = nPercentW; if (canvasUseNewSize) { - destY = Math.Max(0, System.Convert.ToInt32((newHeight - sourceImage.Height * nPercentH) / 2)); + destY = Math.Max(0, Convert.ToInt32((newHeight - sourceImage.Height * nPercentH) / 2)); } } else if ((int) nPercentH != 0 && nPercentH < nPercentW) @@ -1584,7 +1459,7 @@ namespace Greenshot.Base.Core nPercentW = nPercentH; if (canvasUseNewSize) { - destX = Math.Max(0, System.Convert.ToInt32((newWidth - sourceImage.Width * nPercentW) / 2)); + destX = Math.Max(0, Convert.ToInt32((newWidth - sourceImage.Width * nPercentW) / 2)); } } else @@ -1592,7 +1467,7 @@ namespace Greenshot.Base.Core nPercentH = nPercentW; if (canvasUseNewSize) { - destY = Math.Max(0, System.Convert.ToInt32((newHeight - sourceImage.Height * nPercentH) / 2)); + destY = Math.Max(0, Convert.ToInt32((newHeight - sourceImage.Height * nPercentH) / 2)); } } } @@ -1631,102 +1506,7 @@ namespace Greenshot.Base.Core return newImage; } - - /// - /// Load a Greenshot surface from a stream - /// - /// Stream - /// - /// ISurface - public static ISurface LoadGreenshotSurface(Stream surfaceFileStream, ISurface returnSurface) - { - Image fileImage; - // Fixed problem that the bitmap stream is disposed... by Cloning the image - // This also ensures the bitmap is correctly created - - // We create a copy of the bitmap, so everything else can be disposed - surfaceFileStream.Position = 0; - using (Image tmpImage = Image.FromStream(surfaceFileStream, true, true)) - { - Log.DebugFormat("Loaded .greenshot file with Size {0}x{1} and PixelFormat {2}", tmpImage.Width, tmpImage.Height, tmpImage.PixelFormat); - fileImage = Clone(tmpImage); - } - - // Start at -14 read "GreenshotXX.YY" (XX=Major, YY=Minor) - const int markerSize = 14; - surfaceFileStream.Seek(-markerSize, SeekOrigin.End); - using (StreamReader streamReader = new StreamReader(surfaceFileStream)) - { - var greenshotMarker = streamReader.ReadToEnd(); - if (!greenshotMarker.StartsWith("Greenshot")) - { - throw new ArgumentException("Stream is not a Greenshot file!"); - } - - Log.InfoFormat("Greenshot file format: {0}", greenshotMarker); - 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); - returnSurface.LoadElementsFromStream(surfaceFileStream); - } - - if (fileImage != null) - { - returnSurface.Image = fileImage; - Log.InfoFormat("Information about .greenshot file: {0}x{1}-{2} Resolution {3}x{4}", fileImage.Width, fileImage.Height, fileImage.PixelFormat, - fileImage.HorizontalResolution, fileImage.VerticalResolution); - } - - return returnSurface; - } - - /// - /// Create an image from a stream, if an extension is supplied more formats are supported. - /// - /// Stream - /// - /// Image - public static Image FromStream(Stream stream, string extension = null) - { - if (stream == null) - { - return null; - } - - if (!string.IsNullOrEmpty(extension)) - { - extension = extension.Replace(".", string.Empty); - } - - var startingPosition = stream.Position; - - // Make sure we can try multiple times - if (!stream.CanSeek) - { - var memoryStream = new MemoryStream(); - stream.CopyTo(memoryStream); - stream = memoryStream; - // As we are if a different stream, which starts at 0, change the starting position - startingPosition = 0; - } - var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances(); - foreach (var fileFormatHandler in fileFormatHandlers - .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension)) - .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension))) - { - stream.Seek(startingPosition, SeekOrigin.Begin); - if (fileFormatHandler.TryLoadFromStream(stream, extension, out var bitmap)) - { - return bitmap; - } - } - - return null; - } - - + /// /// Rotate the image /// diff --git a/src/Greenshot.Base/Core/ImageOutput.cs b/src/Greenshot.Base/Core/ImageIO.cs similarity index 70% rename from src/Greenshot.Base/Core/ImageOutput.cs rename to src/Greenshot.Base/Core/ImageIO.cs index e722921f1..16f69c0fe 100644 --- a/src/Greenshot.Base/Core/ImageOutput.cs +++ b/src/Greenshot.Base/Core/ImageIO.cs @@ -24,6 +24,7 @@ using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; +using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; @@ -35,6 +36,7 @@ using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.IniFile; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Plugin; +using Greenshot.Base.UnmanagedHelpers; using log4net; namespace Greenshot.Base.Core @@ -42,9 +44,9 @@ namespace Greenshot.Base.Core /// /// Description of ImageOutput. /// - public static class ImageOutput + public static class ImageIO { - private static readonly ILog Log = LogManager.GetLogger(typeof(ImageOutput)); + private static readonly ILog Log = LogManager.GetLogger(typeof(ImageIO)); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection(); private static readonly int PROPERTY_TAG_SOFTWARE_USED = 0x0131; private static readonly Cache TmpFileCache = new Cache(10 * 60 * 60, RemoveExpiredTmpFile); @@ -280,7 +282,7 @@ namespace Greenshot.Base.Core // Fixed lock problem Bug #3431881 using (Stream surfaceFileStream = File.OpenRead(fullPath)) { - returnSurface = ImageHelper.LoadGreenshotSurface(surfaceFileStream, returnSurface); + returnSurface = LoadGreenshotSurface(surfaceFileStream, returnSurface); } if (returnSurface != null) @@ -522,5 +524,220 @@ namespace Greenshot.Base.Core File.Delete(path); } } + + /// + /// Load an image from file + /// + /// + /// + public static Image LoadImage(string filename) + { + if (string.IsNullOrEmpty(filename)) + { + return null; + } + + if (!File.Exists(filename)) + { + return null; + } + + Image fileImage; + Log.InfoFormat("Loading image from file {0}", filename); + // Fixed lock problem Bug #3431881 + using (Stream imageFileStream = File.OpenRead(filename)) + { + fileImage = FromStream(imageFileStream, Path.GetExtension(filename)); + } + + if (fileImage != null) + { + Log.InfoFormat("Information about file {0}: {1}x{2}-{3} Resolution {4}x{5}", filename, fileImage.Width, fileImage.Height, fileImage.PixelFormat, + fileImage.HorizontalResolution, fileImage.VerticalResolution); + } + + return fileImage; + } + + /// + /// Based on: https://www.codeproject.com/KB/cs/IconExtractor.aspx + /// And a hint from: https://www.codeproject.com/KB/cs/IconLib.aspx + /// + /// Stream with the icon information + /// Bitmap with the Vista Icon (256x256) + private static Bitmap ExtractVistaIcon(Stream iconStream) + { + const int sizeIconDir = 6; + const int sizeIconDirEntry = 16; + Bitmap bmpPngExtracted = null; + try + { + byte[] srcBuf = new byte[iconStream.Length]; + iconStream.Read(srcBuf, 0, (int)iconStream.Length); + int iCount = BitConverter.ToInt16(srcBuf, 4); + for (int iIndex = 0; iIndex < iCount; iIndex++) + { + int iWidth = srcBuf[sizeIconDir + sizeIconDirEntry * iIndex]; + int iHeight = srcBuf[sizeIconDir + sizeIconDirEntry * iIndex + 1]; + if (iWidth == 0 && iHeight == 0) + { + int iImageSize = BitConverter.ToInt32(srcBuf, sizeIconDir + sizeIconDirEntry * iIndex + 8); + int iImageOffset = BitConverter.ToInt32(srcBuf, sizeIconDir + sizeIconDirEntry * iIndex + 12); + using MemoryStream destStream = new MemoryStream(); + destStream.Write(srcBuf, iImageOffset, iImageSize); + destStream.Seek(0, SeekOrigin.Begin); + bmpPngExtracted = new Bitmap(destStream); // This is PNG! :) + break; + } + } + } + catch + { + return null; + } + + return bmpPngExtracted; + } + + /// + /// See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms648069%28v=vs.85%29.aspx + /// + /// The file (EXE or DLL) to get the icon from + /// Index of the icon + /// true if the large icon is wanted + /// Icon + public static Icon ExtractAssociatedIcon(string location, int index, bool takeLarge) + { + Shell32.ExtractIconEx(location, index, out var large, out var small, 1); + Icon returnIcon = null; + bool isLarge = false; + bool isSmall = false; + try + { + if (takeLarge && !IntPtr.Zero.Equals(large)) + { + returnIcon = Icon.FromHandle(large); + isLarge = true; + } + else if (!IntPtr.Zero.Equals(small)) + { + returnIcon = Icon.FromHandle(small); + isSmall = true; + } + else if (!IntPtr.Zero.Equals(large)) + { + returnIcon = Icon.FromHandle(large); + isLarge = true; + } + } + finally + { + if (isLarge && !IntPtr.Zero.Equals(small)) + { + User32.DestroyIcon(small); + } + + if (isSmall && !IntPtr.Zero.Equals(large)) + { + User32.DestroyIcon(large); + } + } + + return returnIcon; + } + + /// + /// Create an image from a stream, if an extension is supplied more formats are supported. + /// + /// Stream + /// + /// Image + public static Image FromStream(Stream stream, string extension = null) + { + if (stream == null) + { + return null; + } + + if (!string.IsNullOrEmpty(extension)) + { + extension = extension.Replace(".", string.Empty); + } + + var startingPosition = stream.Position; + + // Make sure we can try multiple times + if (!stream.CanSeek) + { + var memoryStream = new MemoryStream(); + stream.CopyTo(memoryStream); + stream = memoryStream; + // As we are if a different stream, which starts at 0, change the starting position + startingPosition = 0; + } + var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances(); + foreach (var fileFormatHandler in fileFormatHandlers + .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension)) + .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension))) + { + stream.Seek(startingPosition, SeekOrigin.Begin); + if (fileFormatHandler.TryLoadFromStream(stream, extension, out var bitmap)) + { + return bitmap; + } + } + + return null; + } + + /// + /// Load a Greenshot surface from a stream + /// + /// Stream + /// + /// ISurface + public static ISurface LoadGreenshotSurface(Stream surfaceFileStream, ISurface returnSurface) + { + Image fileImage; + // Fixed problem that the bitmap stream is disposed... by Cloning the image + // This also ensures the bitmap is correctly created + + // We create a copy of the bitmap, so everything else can be disposed + surfaceFileStream.Position = 0; + using (Image tmpImage = Image.FromStream(surfaceFileStream, true, true)) + { + Log.DebugFormat("Loaded .greenshot file with Size {0}x{1} and PixelFormat {2}", tmpImage.Width, tmpImage.Height, tmpImage.PixelFormat); + fileImage = ImageHelper.Clone(tmpImage); + } + + // Start at -14 read "GreenshotXX.YY" (XX=Major, YY=Minor) + const int markerSize = 14; + surfaceFileStream.Seek(-markerSize, SeekOrigin.End); + using (StreamReader streamReader = new StreamReader(surfaceFileStream)) + { + var greenshotMarker = streamReader.ReadToEnd(); + if (!greenshotMarker.StartsWith("Greenshot")) + { + throw new ArgumentException("Stream is not a Greenshot file!"); + } + + Log.InfoFormat("Greenshot file format: {0}", greenshotMarker); + 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); + returnSurface.LoadElementsFromStream(surfaceFileStream); + } + + if (fileImage != null) + { + returnSurface.Image = fileImage; + Log.InfoFormat("Information about .greenshot file: {0}x{1}-{2} Resolution {3}x{4}", fileImage.Width, fileImage.Height, fileImage.PixelFormat, + fileImage.HorizontalResolution, fileImage.VerticalResolution); + } + + return returnSurface; + } } } \ No newline at end of file diff --git a/src/Greenshot.Base/Core/NetworkHelper.cs b/src/Greenshot.Base/Core/NetworkHelper.cs index 15a964f5b..88cfff569 100644 --- a/src/Greenshot.Base/Core/NetworkHelper.cs +++ b/src/Greenshot.Base/Core/NetworkHelper.cs @@ -732,7 +732,7 @@ namespace Greenshot.Base.Core public string ToBase64String(Base64FormattingOptions formattingOptions) { using MemoryStream stream = new MemoryStream(); - ImageOutput.SaveToStream(_surface, stream, _outputSettings); + ImageIO.SaveToStream(_surface, stream, _outputSettings); return Convert.ToBase64String(stream.GetBuffer(), 0, (int) stream.Length, formattingOptions); } @@ -744,7 +744,7 @@ namespace Greenshot.Base.Core public byte[] ToByteArray() { using MemoryStream stream = new MemoryStream(); - ImageOutput.SaveToStream(_surface, stream, _outputSettings); + ImageIO.SaveToStream(_surface, stream, _outputSettings); return stream.ToArray(); } @@ -760,7 +760,7 @@ namespace Greenshot.Base.Core string header = $"--{boundary}\r\nContent-Disposition: form-data; name=\"{name}\"; filename=\"{Filename ?? name}\";\r\nContent-Type: {ContentType}\r\n\r\n"; formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header)); - ImageOutput.SaveToStream(_surface, formDataStream, _outputSettings); + ImageIO.SaveToStream(_surface, formDataStream, _outputSettings); } /// @@ -770,7 +770,7 @@ namespace Greenshot.Base.Core public void WriteToStream(Stream dataStream) { // Write the file data directly to the Stream, rather than serializing it to a string. - ImageOutput.SaveToStream(_surface, dataStream, _outputSettings); + ImageIO.SaveToStream(_surface, dataStream, _outputSettings); } /// diff --git a/src/Greenshot.Base/Core/PluginUtils.cs b/src/Greenshot.Base/Core/PluginUtils.cs index 3d3ec79f2..cb09cd8af 100644 --- a/src/Greenshot.Base/Core/PluginUtils.cs +++ b/src/Greenshot.Base/Core/PluginUtils.cs @@ -158,7 +158,7 @@ namespace Greenshot.Base.Core try { - using (Icon appIcon = ImageHelper.ExtractAssociatedIcon(path, index, CoreConfig.UseLargeIcons)) + using (Icon appIcon = ImageIO.ExtractAssociatedIcon(path, index, CoreConfig.UseLargeIcons)) { if (appIcon != null) { diff --git a/src/Greenshot.Editor/Drawing/ImageContainer.cs b/src/Greenshot.Editor/Drawing/ImageContainer.cs index 68b4cd797..5def5578b 100644 --- a/src/Greenshot.Editor/Drawing/ImageContainer.cs +++ b/src/Greenshot.Editor/Drawing/ImageContainer.cs @@ -41,7 +41,7 @@ namespace Greenshot.Editor.Drawing { private static readonly ILog Log = LogManager.GetLogger(typeof(ImageContainer)); - private Image image; + private Image _image; /// /// This is the shadow version of the bitmap, rendered once to save performance @@ -108,8 +108,8 @@ namespace Greenshot.Editor.Drawing } else { - Width = image.Width; - Height = image.Height; + Width = _image.Width; + Height = _image.Height; if (_shadowBitmap != null) { Left += _shadowOffset.X; @@ -125,13 +125,13 @@ namespace Greenshot.Editor.Drawing // Remove all current bitmaps DisposeImage(); DisposeShadow(); - image = ImageHelper.Clone(value); + _image = ImageHelper.Clone(value); bool shadow = GetFieldValueAsBool(FieldType.SHADOW); CheckShadow(shadow); if (!shadow) { - Width = image.Width; - Height = image.Height; + Width = _image.Width; + Height = _image.Height; } else { @@ -141,7 +141,7 @@ namespace Greenshot.Editor.Drawing Top -= _shadowOffset.Y; } } - get { return image; } + get { return _image; } } /// @@ -163,8 +163,8 @@ namespace Greenshot.Editor.Drawing private void DisposeImage() { - image?.Dispose(); - image = null; + _image?.Dispose(); + _image = null; } private void DisposeShadow() @@ -187,9 +187,9 @@ namespace Greenshot.Editor.Drawing Log.DebugFormat("Rotating element with {0} degrees.", rotateAngle); DisposeShadow(); using var tmpMatrix = new Matrix(); - using (image) + using (_image) { - image = ImageHelper.ApplyEffect(image, new RotateEffect(rotateAngle), tmpMatrix); + _image = ImageHelper.ApplyEffect(_image, new RotateEffect(rotateAngle), tmpMatrix); } } @@ -209,7 +209,8 @@ namespace Greenshot.Editor.Drawing // Always make sure ImageHelper.LoadBitmap results are disposed some time, // as we close the bitmap internally, we need to do it afterwards - using (var tmpImage = ImageHelper.LoadImage(filename)) + // TODO: Replace with some other code, like the file format handler, or move it completely outside of this class + using (var tmpImage = ImageIO.LoadImage(filename)) { Image = tmpImage; } @@ -229,7 +230,7 @@ namespace Greenshot.Editor.Drawing } using var matrix = new Matrix(); - _shadowBitmap = ImageHelper.ApplyEffect(image, new DropShadowEffect(), matrix); + _shadowBitmap = ImageHelper.ApplyEffect(_image, new DropShadowEffect(), matrix); } /// @@ -239,7 +240,7 @@ namespace Greenshot.Editor.Drawing /// public override void Draw(Graphics graphics, RenderMode rm) { - if (image == null) + if (_image == null) { return; } @@ -257,12 +258,12 @@ namespace Greenshot.Editor.Drawing } else { - graphics.DrawImage(image, Bounds); + graphics.DrawImage(_image, Bounds); } } public override bool HasDefaultSize => true; - public override Size DefaultSize => image?.Size ?? new Size(32, 32); + public override Size DefaultSize => _image?.Size ?? new Size(32, 32); } } \ No newline at end of file diff --git a/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs index 3a664051a..8d7ad7790 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs @@ -86,7 +86,8 @@ namespace Greenshot.Editor.FileFormatHandlers bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize); bitmapStream.Write(dibBuffer, 0, dibBuffer.Length); bitmapStream.Seek(0, SeekOrigin.Begin); - bitmap = ImageHelper.FromStream(bitmapStream) as Bitmap; + // TODO: Replace with a FileFormatHandler + bitmap = ImageIO.FromStream(bitmapStream) as Bitmap; return true; } Log.Info("Using special DIBV5 / Format17 format reader"); diff --git a/src/Greenshot.Plugin.Confluence/ConfluenceDestination.cs b/src/Greenshot.Plugin.Confluence/ConfluenceDestination.cs index ddcb66530..669087901 100644 --- a/src/Greenshot.Plugin.Confluence/ConfluenceDestination.cs +++ b/src/Greenshot.Plugin.Confluence/ConfluenceDestination.cs @@ -54,8 +54,8 @@ namespace Greenshot.Plugin.Confluence Uri confluenceIconUri = new Uri("/Greenshot.Plugin.Confluence;component/Images/Confluence.ico", UriKind.Relative); using (Stream iconStream = Application.GetResourceStream(confluenceIconUri)?.Stream) { - // TODO: Check what to do with the IImage - ConfluenceIcon = ImageHelper.FromStream(iconStream); + // TODO: Replace with FileFormatHandler + ConfluenceIcon = ImageIO.FromStream(iconStream); } IsInitialized = true; diff --git a/src/Greenshot.Plugin.ExternalCommand/ExternalCommandDestination.cs b/src/Greenshot.Plugin.ExternalCommand/ExternalCommandDestination.cs index 273535952..4083827e3 100644 --- a/src/Greenshot.Plugin.ExternalCommand/ExternalCommandDestination.cs +++ b/src/Greenshot.Plugin.ExternalCommand/ExternalCommandDestination.cs @@ -77,7 +77,7 @@ namespace Greenshot.Plugin.ExternalCommand } bool runInBackground = config.RunInbackground[_presetCommand]; - string fullPath = captureDetails.Filename ?? ImageOutput.SaveNamedTmpFile(surface, captureDetails, outputSettings); + string fullPath = captureDetails.Filename ?? ImageIO.SaveNamedTmpFile(surface, captureDetails, outputSettings); string output; string error; diff --git a/src/Greenshot.Plugin.Imgur/ImgurUtils.cs b/src/Greenshot.Plugin.Imgur/ImgurUtils.cs index a2156d6d0..02af34e56 100644 --- a/src/Greenshot.Plugin.Imgur/ImgurUtils.cs +++ b/src/Greenshot.Plugin.Imgur/ImgurUtils.cs @@ -179,7 +179,7 @@ namespace Greenshot.Plugin.Imgur { using (var requestStream = webRequest.GetRequestStream()) { - ImageOutput.SaveToStream(surfaceToUpload, requestStream, outputSettings); + ImageIO.SaveToStream(surfaceToUpload, requestStream, outputSettings); } using WebResponse response = webRequest.GetResponse(); @@ -265,7 +265,8 @@ namespace Greenshot.Plugin.Imgur Stream responseStream = response.GetResponseStream(); if (responseStream != null) { - imgurInfo.Image = ImageHelper.FromStream(responseStream); + // TODO: Replace with some other code, like the file format handler + imgurInfo.Image = ImageIO.FromStream(responseStream); } } diff --git a/src/Greenshot.Plugin.Office/Destinations/ExcelDestination.cs b/src/Greenshot.Plugin.Office/Destinations/ExcelDestination.cs index cf09272e2..fb1930c8c 100644 --- a/src/Greenshot.Plugin.Office/Destinations/ExcelDestination.cs +++ b/src/Greenshot.Plugin.Office/Destinations/ExcelDestination.cs @@ -89,7 +89,7 @@ namespace Greenshot.Plugin.Office.Destinations string imageFile = captureDetails.Filename; if (imageFile == null || surface.Modified || !Regex.IsMatch(imageFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$")) { - imageFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat()); + imageFile = ImageIO.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat()); createdFile = true; } @@ -107,7 +107,7 @@ namespace Greenshot.Plugin.Office.Destinations // Cleanup imageFile if we created it here, so less tmp-files are generated and left if (createdFile) { - ImageOutput.DeleteNamedTmpFile(imageFile); + ImageIO.DeleteNamedTmpFile(imageFile); } return exportInformation; diff --git a/src/Greenshot.Plugin.Office/Destinations/OutlookDestination.cs b/src/Greenshot.Plugin.Office/Destinations/OutlookDestination.cs index da694be62..6d93c4096 100644 --- a/src/Greenshot.Plugin.Office/Destinations/OutlookDestination.cs +++ b/src/Greenshot.Plugin.Office/Destinations/OutlookDestination.cs @@ -160,7 +160,7 @@ namespace Greenshot.Plugin.Office.Destinations string tmpFile = captureDetails.Filename; if (tmpFile == null || surface.Modified || !Regex.IsMatch(tmpFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$")) { - tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat()); + tmpFile = ImageIO.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat()); } else { diff --git a/src/Greenshot.Plugin.Office/Destinations/PowerpointDestination.cs b/src/Greenshot.Plugin.Office/Destinations/PowerpointDestination.cs index a151d3388..3b9ce4bc8 100644 --- a/src/Greenshot.Plugin.Office/Destinations/PowerpointDestination.cs +++ b/src/Greenshot.Plugin.Office/Destinations/PowerpointDestination.cs @@ -114,7 +114,7 @@ namespace Greenshot.Plugin.Office.Destinations Size imageSize = Size.Empty; if (tmpFile == null || surface.Modified || !Regex.IsMatch(tmpFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$")) { - tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat()); + tmpFile = ImageIO.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat()); imageSize = surface.Image.Size; } diff --git a/src/Greenshot.Plugin.Office/Destinations/WordDestination.cs b/src/Greenshot.Plugin.Office/Destinations/WordDestination.cs index fd91295be..99cf4693c 100644 --- a/src/Greenshot.Plugin.Office/Destinations/WordDestination.cs +++ b/src/Greenshot.Plugin.Office/Destinations/WordDestination.cs @@ -88,7 +88,7 @@ namespace Greenshot.Plugin.Office.Destinations string tmpFile = captureDetails.Filename; if (tmpFile == null || surface.Modified || !Regex.IsMatch(tmpFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$")) { - tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat()); + tmpFile = ImageIO.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat()); } if (_documentCaption != null) diff --git a/src/Greenshot.Plugin.Office/OfficeExport/OneNoteExporter.cs b/src/Greenshot.Plugin.Office/OfficeExport/OneNoteExporter.cs index 305888ee2..645623780 100644 --- a/src/Greenshot.Plugin.Office/OfficeExport/OneNoteExporter.cs +++ b/src/Greenshot.Plugin.Office/OfficeExport/OneNoteExporter.cs @@ -97,7 +97,7 @@ namespace Greenshot.Plugin.Office.OfficeExport using var pngStream = new MemoryStream(); var pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); - ImageOutput.SaveToStream(surfaceToUpload, pngStream, pngOutputSettings); + ImageIO.SaveToStream(surfaceToUpload, pngStream, pngOutputSettings); var base64String = Convert.ToBase64String(pngStream.GetBuffer()); var imageXmlStr = string.Format(XmlImageContent, base64String, surfaceToUpload.Image.Width, surfaceToUpload.Image.Height); var pageChangesXml = string.Format(XmlOutline, imageXmlStr, page.Id, OnenoteNamespace2010, page.Name); diff --git a/src/Greenshot.Plugin.Win10/Destinations/Win10ShareDestination.cs b/src/Greenshot.Plugin.Win10/Destinations/Win10ShareDestination.cs index 0f2557da2..0574a6d0c 100644 --- a/src/Greenshot.Plugin.Win10/Destinations/Win10ShareDestination.cs +++ b/src/Greenshot.Plugin.Win10/Destinations/Win10ShareDestination.cs @@ -151,7 +151,7 @@ namespace Greenshot.Plugin.Win10.Destinations outputSettings.PreventGreenshotFormat(); // Create capture for export - ImageOutput.SaveToStream(surface, imageStream, outputSettings); + ImageIO.SaveToStream(surface, imageStream, outputSettings); imageStream.Position = 0; Log.Debug("Created RandomAccessStreamReference for the image"); var imageRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(imageStream); @@ -161,7 +161,7 @@ namespace Greenshot.Plugin.Win10.Destinations using (var tmpImageForThumbnail = surface.GetImageForExport()) using (var thumbnail = ImageHelper.CreateThumbnail(tmpImageForThumbnail, 240, 160)) { - ImageOutput.SaveToStream(thumbnail, null, thumbnailStream, outputSettings); + ImageIO.SaveToStream(thumbnail, null, thumbnailStream, outputSettings); thumbnailStream.Position = 0; thumbnailRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(thumbnailStream); Log.Debug("Created RandomAccessStreamReference for the thumbnail"); @@ -172,7 +172,7 @@ namespace Greenshot.Plugin.Win10.Destinations using (var logo = GreenshotResources.GetGreenshotIcon().ToBitmap()) using (var logoThumbnail = ImageHelper.CreateThumbnail(logo, 30, 30)) { - ImageOutput.SaveToStream(logoThumbnail, null, logoStream, outputSettings); + ImageIO.SaveToStream(logoThumbnail, null, logoStream, outputSettings); logoStream.Position = 0; logoRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(logoStream); Log.Info("Created RandomAccessStreamReference for the logo"); diff --git a/src/Greenshot.Plugin.Win10/Win10OcrProvider.cs b/src/Greenshot.Plugin.Win10/Win10OcrProvider.cs index 77aa0d663..fdc0c07fa 100644 --- a/src/Greenshot.Plugin.Win10/Win10OcrProvider.cs +++ b/src/Greenshot.Plugin.Win10/Win10OcrProvider.cs @@ -97,7 +97,7 @@ namespace Greenshot.Plugin.Win10 IEffect effect = new ResizeCanvasEffect(addedWidth, addedWidth, addedHeight, addedHeight); outputSettings.Effects.Add(effect); } - ImageOutput.SaveToStream(surface, imageStream, outputSettings); + ImageIO.SaveToStream(surface, imageStream, outputSettings); imageStream.Position = 0; var randomAccessStream = imageStream.AsRandomAccessStream(); @@ -117,7 +117,7 @@ namespace Greenshot.Plugin.Win10 OcrInformation result; using (var imageStream = new MemoryStream()) { - ImageOutput.SaveToStream(image, null, imageStream, new SurfaceOutputSettings()); + ImageIO.SaveToStream(image, null, imageStream, new SurfaceOutputSettings()); imageStream.Position = 0; var randomAccessStream = imageStream.AsRandomAccessStream(); diff --git a/src/Greenshot/Destinations/FileDestination.cs b/src/Greenshot/Destinations/FileDestination.cs index 9389c3d26..64f8f21a9 100644 --- a/src/Greenshot/Destinations/FileDestination.cs +++ b/src/Greenshot/Destinations/FileDestination.cs @@ -68,7 +68,7 @@ namespace Greenshot.Destinations overwrite = true; Log.InfoFormat("Using previous filename"); fullPath = captureDetails.Filename; - outputSettings.Format = ImageOutput.FormatForFilename(fullPath); + outputSettings.Format = ImageIO.FormatForFilename(fullPath); } else { @@ -87,7 +87,7 @@ namespace Greenshot.Destinations // This is done for e.g. bugs #2974608, #2963943, #2816163, #2795317, #2789218, #3004642 try { - ImageOutput.Save(surface, fullPath, overwrite, outputSettings, CoreConfig.OutputFileCopyPathToClipboard); + ImageIO.Save(surface, fullPath, overwrite, outputSettings, CoreConfig.OutputFileCopyPathToClipboard); outputMade = true; } catch (ArgumentException ex1) @@ -95,7 +95,7 @@ namespace Greenshot.Destinations // Our generated filename exists, display 'save-as' Log.InfoFormat("Not overwriting: {0}", ex1.Message); // when we don't allow to overwrite present a new SaveWithDialog - fullPath = ImageOutput.SaveWithDialog(surface, captureDetails); + fullPath = ImageIO.SaveWithDialog(surface, captureDetails); outputMade = fullPath != null; } catch (Exception ex2) @@ -104,7 +104,7 @@ namespace Greenshot.Destinations // Show the problem MessageBox.Show(Language.GetString(LangKey.error_save), Language.GetString(LangKey.error)); // when save failed we present a SaveWithDialog - fullPath = ImageOutput.SaveWithDialog(surface, captureDetails); + fullPath = ImageIO.SaveWithDialog(surface, captureDetails); outputMade = fullPath != null; } diff --git a/src/Greenshot/Destinations/FileWithDialogDestination.cs b/src/Greenshot/Destinations/FileWithDialogDestination.cs index 3a8520fb0..72924689f 100644 --- a/src/Greenshot/Destinations/FileWithDialogDestination.cs +++ b/src/Greenshot/Destinations/FileWithDialogDestination.cs @@ -57,7 +57,7 @@ namespace Greenshot.Destinations { ExportInformation exportInformation = new ExportInformation(Designation, Description); // Bug #2918756 don't overwrite path if SaveWithDialog returns null! - var savedTo = ImageOutput.SaveWithDialog(surface, captureDetails); + var savedTo = ImageIO.SaveWithDialog(surface, captureDetails); if (savedTo != null) { exportInformation.ExportMade = true; diff --git a/src/Greenshot/Forms/MainForm.cs b/src/Greenshot/Forms/MainForm.cs index 64f2e521f..fc7fb046d 100644 --- a/src/Greenshot/Forms/MainForm.cs +++ b/src/Greenshot/Forms/MainForm.cs @@ -1911,7 +1911,7 @@ namespace Greenshot.Forms LOG.Error("Error closing application!", e); } - ImageOutput.RemoveTmpFiles(); + ImageIO.RemoveTmpFiles(); // Store any open configuration changes try diff --git a/src/Greenshot/Helpers/CaptureHelper.cs b/src/Greenshot/Helpers/CaptureHelper.cs index 5e031c6af..20496a839 100644 --- a/src/Greenshot/Helpers/CaptureHelper.cs +++ b/src/Greenshot/Helpers/CaptureHelper.cs @@ -431,12 +431,13 @@ namespace Greenshot.Helpers if (!string.IsNullOrEmpty(filename)) { + // TODO: Fix that the Greenshot format needs a separate code path try { if (filename.ToLower().EndsWith("." + OutputFormat.greenshot)) { ISurface surface = new Surface(); - surface = ImageOutput.LoadGreenshotSurface(filename, surface); + surface = ImageIO.LoadGreenshotSurface(filename, surface); surface.CaptureDetails = _capture.CaptureDetails; DestinationHelper.GetDestination(EditorDestination.DESIGNATION).ExportCapture(true, surface, _capture.CaptureDetails); break; @@ -448,9 +449,10 @@ namespace Greenshot.Helpers MessageBox.Show(Language.GetFormattedString(LangKey.error_openfile, filename)); } + // TODO: Remove Image loading for here try { - fileImage = ImageHelper.LoadImage(filename); + fileImage = ImageIO.LoadImage(filename); } catch (Exception e) { diff --git a/src/Greenshot/Helpers/MailHelper.cs b/src/Greenshot/Helpers/MailHelper.cs index f3975a205..39aa3c150 100644 --- a/src/Greenshot/Helpers/MailHelper.cs +++ b/src/Greenshot/Helpers/MailHelper.cs @@ -82,7 +82,7 @@ namespace Greenshot.Helpers /// ICaptureDetails public static void SendImage(ISurface surface, ICaptureDetails captureDetails) { - string tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings()); + string tmpFile = ImageIO.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings()); if (tmpFile == null) return; diff --git a/src/Greenshot/Helpers/PrintHelper.cs b/src/Greenshot/Helpers/PrintHelper.cs index 9e6a43a7f..36bf8257b 100644 --- a/src/Greenshot/Helpers/PrintHelper.cs +++ b/src/Greenshot/Helpers/PrintHelper.cs @@ -187,7 +187,7 @@ namespace Greenshot.Helpers ApplyEffects(printOutputSettings); - bool disposeImage = ImageOutput.CreateImageFromSurface(_surface, printOutputSettings, out var image); + bool disposeImage = ImageIO.CreateImageFromSurface(_surface, printOutputSettings, out var image); try { ContentAlignment alignment = CoreConfig.OutputPrintCenter ? ContentAlignment.MiddleCenter : ContentAlignment.TopLeft;