diff --git a/src/Greenshot.Base/Core/ClipboardHelper.cs b/src/Greenshot.Base/Core/ClipboardHelper.cs
index d37e4634f..0ab70e5b2 100644
--- a/src/Greenshot.Base/Core/ClipboardHelper.cs
+++ b/src/Greenshot.Base/Core/ClipboardHelper.cs
@@ -34,6 +34,7 @@ using Greenshot.Base.Core.Enums;
using Greenshot.Base.Core.FileFormatHandlers;
using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces;
+using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.Interfaces.Plugin;
using Greenshot.Base.UnmanagedHelpers;
using log4net;
@@ -300,13 +301,14 @@ EndSelection:<<<<<<<4
return true;
}
+ var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList();
foreach (var fileData in IterateClipboardContent(dataObject))
{
try
{
- using (ImageHelper.FromStream(fileData))
+ var extension = Path.GetExtension(fileData.filename)?.ToLowerInvariant();
+ if (supportedExtensions.Contains(extension))
{
- // If we get here, there is an image
return true;
}
}
@@ -316,7 +318,7 @@ EndSelection:<<<<<<<4
}
finally
{
- fileData?.Dispose();
+ fileData.stream?.Dispose();
}
}
@@ -328,6 +330,7 @@ EndSelection:<<<<<<<4
var imageStream = clipboardContent as MemoryStream;
if (IsValidStream(imageStream))
{
+ // TODO: How to check if we support "just a stream"?
using (ImageHelper.FromStream(imageStream))
{
// If we get here, there is an image
@@ -374,8 +377,8 @@ EndSelection:<<<<<<<4
/// Iterate the clipboard content
///
/// IDataObject
- /// IEnumerable{MemoryStream}
- private static IEnumerable IterateClipboardContent(IDataObject dataObject)
+ /// IEnumerable{(MemoryStream,string)}
+ private static IEnumerable<(MemoryStream stream,string filename)> IterateClipboardContent(IDataObject dataObject)
{
var fileDescriptors = AvailableFileDescriptors(dataObject);
if (fileDescriptors == null) yield break;
@@ -414,8 +417,8 @@ EndSelection:<<<<<<<4
///
/// IEnumerable{FileDescriptor}
/// IDataObject
- /// IEnumerable{MemoryStream}
- private static IEnumerable IterateFileDescriptors(IEnumerable fileDescriptors, IDataObject dataObject)
+ /// IEnumerable{(MemoryStream stream, string filename)}
+ private static IEnumerable<(MemoryStream stream, string filename)> IterateFileDescriptors(IEnumerable fileDescriptors, IDataObject dataObject)
{
if (fileDescriptors == null)
{
@@ -446,7 +449,7 @@ EndSelection:<<<<<<<4
if (fileData?.Length > 0)
{
fileData.Position = 0;
- yield return fileData;
+ yield return (fileData, fileDescriptor.FileName);
}
fileIndex++;
@@ -505,56 +508,75 @@ EndSelection:<<<<<<<4
///
///
/// IEnumerable of Image
- public static IEnumerable GetImages(IDataObject dataObject)
+ public static IEnumerable GetImages(IDataObject dataObject)
{
// Get single image, this takes the "best" match
- Image singleImage = GetImage(dataObject);
+ IDrawableContainer singleImage = GetImage(dataObject);
if (singleImage != null)
{
- Log.InfoFormat("Got image from clipboard with size {0} and format {1}", singleImage.Size, singleImage.PixelFormat);
+ Log.InfoFormat($"Got {singleImage.GetType()} from clipboard with size {singleImage.Size}");
yield return singleImage;
+ yield break;
}
- else
+
+ var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList();
+
+ foreach (var fileData in IterateClipboardContent(dataObject))
{
- foreach (var fileData in IterateClipboardContent(dataObject))
+ var extension = Path.GetExtension(fileData.filename)?.ToLowerInvariant();
+ if (!supportedExtensions.Contains(extension))
{
- Image image;
- try
+ continue;
+ }
+
+ IDrawableContainer drawableContainer = null;
+
+ try
+ {
+ if (!FileFormatHandlerRegistry.TryLoadDrawableFromStream(fileData.stream, extension, out drawableContainer))
{
- image = ImageHelper.FromStream(fileData);
- }
- catch (Exception ex)
- {
- Log.Error("Couldn't read file contents", ex);
continue;
}
- finally
- {
- fileData?.Dispose();
- }
- // If we get here, there is an image
- yield return image;
- }
- // check if files are supplied
- foreach (string imageFile in GetImageFilenames(dataObject))
+ }
+ catch (Exception ex)
{
- Image returnImage = null;
- try
- {
- returnImage = ImageHelper.LoadImage(imageFile);
- }
- catch (Exception streamImageEx)
- {
- Log.Error("Problem retrieving Image from clipboard.", streamImageEx);
- }
+ Log.Error("Couldn't read file contents", ex);
+ continue;
+ }
+ finally
+ {
+ fileData.stream?.Dispose();
+ }
+ // If we get here, there is an image
+ yield return drawableContainer;
+ }
- if (returnImage != null)
+ // check if files are supplied
+ foreach (string imageFile in GetImageFilenames(dataObject))
+ {
+ var extension = Path.GetExtension(imageFile)?.ToLowerInvariant();
+ if (!supportedExtensions.Contains(extension))
+ {
+ continue;
+ }
+
+ IDrawableContainer drawableContainer = null;
+ using FileStream fileStream = new FileStream(imageFile, FileMode.Open, FileAccess.Read, FileShare.Read);
+ try
+ {
+ if (!FileFormatHandlerRegistry.TryLoadDrawableFromStream(fileStream, extension, out drawableContainer))
{
- Log.InfoFormat("Got image from clipboard with size {0} and format {1}", returnImage.Size, returnImage.PixelFormat);
- yield return returnImage;
+ continue;
}
}
+ catch (Exception ex)
+ {
+ Log.Error("Couldn't read file contents", ex);
+ continue;
+ }
+ // If we get here, there is an image
+ yield return drawableContainer;
}
}
@@ -563,51 +585,50 @@ EndSelection:<<<<<<<4
///
///
/// Image or null
- private static Image GetImage(IDataObject dataObject)
+ private static IDrawableContainer GetImage(IDataObject dataObject)
{
- Image returnImage = null;
- if (dataObject != null)
- {
- IList formats = GetFormats(dataObject);
- string[] retrieveFormats;
+ if (dataObject == null) return null;
- // Found a weird bug, where PNG's from Outlook 2010 are clipped
- // So I build some special logic to get the best format:
- if (formats != null && formats.Contains(FORMAT_PNG_OFFICEART) && formats.Contains(DataFormats.Dib))
+ IDrawableContainer returnImage = null;
+ IList formats = GetFormats(dataObject);
+ string[] retrieveFormats;
+
+ // Found a weird bug, where PNG's from Outlook 2010 are clipped
+ // So I build some special logic to get the best format:
+ if (formats != null && formats.Contains(FORMAT_PNG_OFFICEART) && formats.Contains(DataFormats.Dib))
+ {
+ // Outlook ??
+ Log.Info("Most likely the current clipboard contents come from Outlook, as this has a problem with PNG and others we place the DIB format to the front...");
+ retrieveFormats = new[]
{
- // Outlook ??
- Log.Info("Most likely the current clipboard contents come from Outlook, as this has a problem with PNG and others we place the DIB format to the front...");
- retrieveFormats = new[]
- {
- DataFormats.Dib, FORMAT_BITMAP, FORMAT_FILECONTENTS, FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JPEG, FORMAT_JFIF,
- DataFormats.Tiff, FORMAT_GIF, FORMAT_HTML
- };
+ DataFormats.Dib, FORMAT_BITMAP, FORMAT_FILECONTENTS, FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JPEG, FORMAT_JFIF,
+ DataFormats.Tiff, FORMAT_GIF, FORMAT_HTML
+ };
+ }
+ else
+ {
+ retrieveFormats = new[]
+ {
+ FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_17, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JPEG, FORMAT_JFIF, DataFormats.Tiff, DataFormats.Dib, FORMAT_BITMAP,
+ FORMAT_FILECONTENTS, FORMAT_GIF, FORMAT_HTML
+ };
+ }
+
+ foreach (string currentFormat in retrieveFormats)
+ {
+ if (formats != null && formats.Contains(currentFormat))
+ {
+ Log.InfoFormat("Found {0}, trying to retrieve.", currentFormat);
+ returnImage = GetImageForFormat(currentFormat, dataObject);
}
else
{
- retrieveFormats = new[]
- {
- FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_17, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JPEG, FORMAT_JFIF, DataFormats.Tiff, DataFormats.Dib, FORMAT_BITMAP,
- FORMAT_FILECONTENTS, FORMAT_GIF, FORMAT_HTML
- };
+ Log.DebugFormat("Couldn't find format {0}.", currentFormat);
}
- foreach (string currentFormat in retrieveFormats)
+ if (returnImage != null)
{
- if (formats != null && formats.Contains(currentFormat))
- {
- Log.InfoFormat("Found {0}, trying to retrieve.", currentFormat);
- returnImage = GetImageForFormat(currentFormat, dataObject);
- }
- else
- {
- Log.DebugFormat("Couldn't find format {0}.", currentFormat);
- }
-
- if (returnImage != null)
- {
- return returnImage;
- }
+ return returnImage;
}
}
@@ -615,15 +636,17 @@ EndSelection:<<<<<<<4
}
///
- /// Helper method to try to get an image in the specified format from the dataObject
+ /// Helper method to try to get an IDrawableContainer in the specified format from the dataObject
/// the DIB reader should solve some issues
/// It also supports Format17/DibV5, by using the following information: https://stackoverflow.com/a/14335591
///
/// string with the format
/// IDataObject
- /// Image or null
- private static Image GetImageForFormat(string format, IDataObject dataObject)
+ /// IDrawableContainer or null
+ private static IDrawableContainer GetImageForFormat(string format, IDataObject dataObject)
{
+ IDrawableContainer drawableContainer = null;
+
if (format == FORMAT_HTML)
{
var textObject = ContentAsString(dataObject, FORMAT_HTML, Encoding.UTF8);
@@ -639,10 +662,10 @@ EndSelection:<<<<<<<4
var srcAttribute = imgNode.Attributes["src"];
var imageUrl = srcAttribute.Value;
Log.Debug(imageUrl);
- var image = NetworkHelper.DownloadImage(imageUrl);
- if (image != null)
+ drawableContainer = NetworkHelper.DownloadImageAsDrawableContainer(imageUrl);
+ if (drawableContainer != null)
{
- return image;
+ return drawableContainer;
}
}
}
@@ -653,110 +676,29 @@ EndSelection:<<<<<<<4
var imageStream = clipboardObject as MemoryStream;
if (!IsValidStream(imageStream))
{
- // TODO: add "HTML Format" support here...
+ // TODO: add text based, like "HTML Format" support here...
+ // TODO: solve the issue that we do not have a factory for the ImageContainer
+ /*var image = clipboardObject as Image;
+ if (image != null)
+ {
+ return new ImageContainer(this)
+ {
+ Image = image,
+ Left = x,
+ Top = y
+ };
+ }
return clipboardObject as Image;
+*/
+ return null;
}
- if (CoreConfig.EnableSpecialDIBClipboardReader)
+ // From here, imageStream is a valid stream
+
+ if (!FileFormatHandlerRegistry.TryLoadDrawableFromStream(imageStream, format, out drawableContainer))
{
- if (format == FORMAT_17 || format == DataFormats.Dib)
- {
- Log.Info("Found DIB stream, trying to process it.");
- try
- {
- if (imageStream != null)
- {
- byte[] dibBuffer = new byte[imageStream.Length];
- _ = imageStream.Read(dibBuffer, 0, dibBuffer.Length);
- var infoHeader = BinaryStructHelper.FromByteArray(dibBuffer);
- if (!infoHeader.IsDibV5)
- {
- Log.InfoFormat("Using special DIB GetImageFilenames(IDataObject dataObject)
{
string[] dropFileNames = (string[])dataObject.GetData(DataFormats.FileDrop);
- if (dropFileNames != null && dropFileNames.Length > 0)
- {
- var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).ToList();
- return dropFileNames
- .Where(filename => !string.IsNullOrEmpty(filename))
- .Where(Path.HasExtension)
- .Where(filename => supportedExtensions.Contains(Path.GetExtension(filename).ToLowerInvariant().Substring(1)));
- }
+ if (dropFileNames is not { Length: > 0 }) return Enumerable.Empty();
+
+ var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).ToList();
+ return dropFileNames
+ .Where(filename => !string.IsNullOrEmpty(filename))
+ .Where(Path.HasExtension)
+ .Where(filename => supportedExtensions.Contains(Path.GetExtension(filename)));
- return Enumerable.Empty();
}
///
diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/AbstractFileFormatHandler.cs b/src/Greenshot.Base/Core/FileFormatHandlers/AbstractFileFormatHandler.cs
new file mode 100644
index 000000000..c8d842b45
--- /dev/null
+++ b/src/Greenshot.Base/Core/FileFormatHandlers/AbstractFileFormatHandler.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using Greenshot.Base.Interfaces;
+using Greenshot.Base.Interfaces.Drawing;
+
+namespace Greenshot.Base.Core.FileFormatHandlers
+{
+ public abstract class AbstractFileFormatHandler
+ {
+ ///
+ /// Make sure we handle the input extension always the same, by "normalizing" it
+ ///
+ /// string
+ /// string
+ protected string NormalizeExtension(string extension)
+ {
+ if (string.IsNullOrEmpty(extension))
+ {
+ return null;
+ }
+
+ extension = extension.ToLowerInvariant();
+ return !extension.StartsWith(".") ? $".{extension}" : extension;
+ }
+ }
+}
diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs b/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs
index 93db7f5d2..0dded0b55 100644
--- a/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs
+++ b/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs
@@ -24,6 +24,7 @@ using System.Drawing;
using System.IO;
using System.Linq;
using Greenshot.Base.Interfaces;
+using Greenshot.Base.Interfaces.Drawing;
namespace Greenshot.Base.Core.FileFormatHandlers
{
@@ -31,13 +32,6 @@ namespace Greenshot.Base.Core.FileFormatHandlers
{
public static IList FileFormatHandlers { get; } = new List();
- static FileFormatHandlerRegistry()
- {
- FileFormatHandlers.Add(new IconFileFormatHandler());
- FileFormatHandlers.Add(new GreenshotFileFormatHandler());
- FileFormatHandlers.Add(new DefaultFileFormatHandler());
- }
-
public static IEnumerable ExtensionsFor(FileFormatHandlerActions fileFormatHandlerAction)
{
return FileFormatHandlers.SelectMany(ffh => ffh.SupportedExtensions(fileFormatHandlerAction)).Distinct();
@@ -66,5 +60,29 @@ namespace Greenshot.Base.Core.FileFormatHandlers
return fileFormatHandler.TrySaveToStream(bitmap, destination, extension);
}
+
+ ///
+ /// Try to load a drawable container from the stream
+ ///
+ /// Stream
+ /// string
+ /// IDrawableContainer out
+ /// ISurface
+ /// bool true if it was successful
+ public static bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parentSurface = null)
+ {
+ var fileFormatHandler = FileFormatHandlers
+ .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadDrawableFromStream, extension))
+ .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadDrawableFromStream, extension))
+ .FirstOrDefault();
+
+ if (fileFormatHandler == null)
+ {
+ drawableContainer = null;
+ return false;
+ }
+
+ return fileFormatHandler.TryLoadDrawableFromStream(stream, extension, out drawableContainer, parentSurface);
+ }
}
}
diff --git a/src/Greenshot.Base/Core/ImageHelper.cs b/src/Greenshot.Base/Core/ImageHelper.cs
index c74e9f80c..e9745dd9b 100644
--- a/src/Greenshot.Base/Core/ImageHelper.cs
+++ b/src/Greenshot.Base/Core/ImageHelper.cs
@@ -1320,7 +1320,7 @@ namespace Greenshot.Base.Core
}
// If no pixelformat is supplied
- if (PixelFormat.DontCare == targetFormat || PixelFormat.Undefined == targetFormat)
+ if (targetFormat is PixelFormat.DontCare or PixelFormat.Undefined)
{
if (SupportsPixelFormat(sourceImage.PixelFormat))
{
diff --git a/src/Greenshot.Base/Core/NetworkHelper.cs b/src/Greenshot.Base/Core/NetworkHelper.cs
index e9671db38..23427ce0d 100644
--- a/src/Greenshot.Base/Core/NetworkHelper.cs
+++ b/src/Greenshot.Base/Core/NetworkHelper.cs
@@ -31,6 +31,7 @@ using System.Text.RegularExpressions;
using Greenshot.Base.Core.FileFormatHandlers;
using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces;
+using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.Interfaces.Plugin;
using log4net;
@@ -89,25 +90,13 @@ namespace Greenshot.Base.Core
}
///
- /// Download the uri to Bitmap
+ /// Download the uri to build an IDrawableContainer
///
/// Of an image
- /// Bitmap
- public static Image DownloadImage(string url)
+ /// IDrawableContainer
+ public static IDrawableContainer DownloadImageAsDrawableContainer(string url)
{
- var extensions = new StringBuilder();
- var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).ToList();
- foreach (var extension in supportedExtensions)
- {
- if (string.IsNullOrEmpty(extension))
- {
- continue;
- }
-
- extensions.AppendFormat(@"\.{0}|", extension);
- }
-
- extensions.Length--;
+ var extensions = string.Join("|", FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream));
var imageUrlRegex = new Regex($@"(http|https)://.*(?{extensions})");
var match = imageUrlRegex.Match(url);
@@ -116,7 +105,10 @@ namespace Greenshot.Base.Core
using var memoryStream = GetAsMemoryStream(url);
try
{
- return ImageHelper.FromStream(memoryStream, match.Success ? match.Groups["extension"]?.Value : null);
+ if (FileFormatHandlerRegistry.TryLoadDrawableFromStream(memoryStream, match.Success ? match.Groups["extension"]?.Value : null, out var drawableContainer))
+ {
+ return drawableContainer;
+ }
}
catch (Exception)
{
@@ -139,7 +131,10 @@ namespace Greenshot.Base.Core
}
using var memoryStream2 = GetAsMemoryStream(match.Value);
- return ImageHelper.FromStream(memoryStream2, match.Groups["extension"]?.Value);
+ if (FileFormatHandlerRegistry.TryLoadDrawableFromStream(memoryStream2, match.Success ? match.Groups["extension"]?.Value : null, out var drawableContainer))
+ {
+ return drawableContainer;
+ }
}
}
catch (Exception e)
diff --git a/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs b/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs
index 1742b8054..24abc2d25 100644
--- a/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs
+++ b/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs
@@ -30,7 +30,14 @@ namespace Greenshot.Base.Interfaces.Drawing
{
public interface IDrawableContainer : INotifyPropertyChanged, IDisposable
{
+ ///
+ /// The parent surface where this IDrawableContainer is on
+ ///
ISurface Parent { get; set; }
+
+ ///
+ /// Is this IDrawableContainer selected on the surface
+ ///
bool Selected { get; set; }
int Left { get; set; }
@@ -54,15 +61,25 @@ namespace Greenshot.Base.Interfaces.Drawing
bool HasFilters { get; }
EditStatus Status { get; set; }
+
void Invalidate();
+
bool ClickableAt(int x, int y);
+
void MoveBy(int x, int y);
+
void Transform(Matrix matrix);
+
bool HandleMouseDown(int x, int y);
+
void HandleMouseUp(int x, int y);
+
bool HandleMouseMove(int x, int y);
+
bool InitContent();
+
void MakeBoundsChangeUndoable(bool allowMerge);
+
EditStatus DefaultEditMode { get; }
///
diff --git a/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs b/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs
index 04442d71b..7281f0228 100644
--- a/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs
+++ b/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs
@@ -89,8 +89,8 @@ namespace Greenshot.Base.Interfaces
/// Stream
/// string
/// IDrawableContainer out
- /// ISurface
+ /// ISurface
/// bool true if it was successful
- public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent);
+ public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parentSurface = null);
}
}
diff --git a/src/Greenshot.Editor/Drawing/IconContainer.cs b/src/Greenshot.Editor/Drawing/IconContainer.cs
index adda1cc23..dd6668ce9 100644
--- a/src/Greenshot.Editor/Drawing/IconContainer.cs
+++ b/src/Greenshot.Editor/Drawing/IconContainer.cs
@@ -61,6 +61,11 @@ namespace Greenshot.Editor.Drawing
Load(filename);
}
+ public IconContainer(ISurface parent, Stream stream) : base(parent)
+ {
+ Load(stream);
+ }
+
public Icon Icon
{
set
@@ -100,6 +105,18 @@ namespace Greenshot.Editor.Drawing
Log.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
}
+ public void Load(Stream iconStream)
+ {
+ if (iconStream == null)
+ {
+ return;
+ }
+
+ using Icon fileIcon = new Icon(iconStream);
+ Icon = fileIcon;
+ Log.Debug("Loaded stream: with resolution: " + Height + "," + Width);
+ }
+
public override void Draw(Graphics graphics, RenderMode rm)
{
if (icon == null)
diff --git a/src/Greenshot.Editor/Drawing/MetafileContainer.cs b/src/Greenshot.Editor/Drawing/MetafileContainer.cs
new file mode 100644
index 000000000..79159b262
--- /dev/null
+++ b/src/Greenshot.Editor/Drawing/MetafileContainer.cs
@@ -0,0 +1,71 @@
+/*
+ * 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.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
+using Greenshot.Base.Core;
+using Greenshot.Base.Interfaces;
+using Svg;
+
+namespace Greenshot.Editor.Drawing
+{
+ ///
+ /// This provides a resizable SVG container, redrawing the SVG in the size the container takes.
+ ///
+ [Serializable]
+ public class MetafileContainer : VectorGraphicsContainer
+ {
+ private readonly Metafile _metafile;
+
+ public MetafileContainer(Metafile metafile, ISurface parent) : base(parent)
+ {
+ _metafile = metafile;
+ Size = new Size(metafile.Width/4, metafile.Height/4);
+ }
+
+ protected override Image ComputeBitmap()
+ {
+ var image = ImageHelper.CreateEmpty(Width, Height, PixelFormat.Format32bppArgb, Color.Transparent);
+
+ var dstRect = new Rectangle(0, 0, Width, Height);
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ graphics.SmoothingMode = SmoothingMode.HighQuality;
+ graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
+ graphics.CompositingQuality = CompositingQuality.HighQuality;
+ graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
+ graphics.DrawImage(_metafile, dstRect);
+ }
+
+ if (RotationAngle == 0) return image;
+
+ var newImage = image.Rotate(RotationAngle);
+ image.Dispose();
+ return newImage;
+ }
+
+ public override bool HasDefaultSize => true;
+
+ public override Size DefaultSize => new Size(_metafile.Width, _metafile.Height);
+ }
+}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Drawing/Surface.cs b/src/Greenshot.Editor/Drawing/Surface.cs
index 2445cb486..d39276992 100644
--- a/src/Greenshot.Editor/Drawing/Surface.cs
+++ b/src/Greenshot.Editor/Drawing/Surface.cs
@@ -49,7 +49,6 @@ namespace Greenshot.Editor.Drawing
public sealed class Surface : Control, ISurface, INotifyPropertyChanged
{
private static readonly ILog LOG = LogManager.GetLogger(typeof(Surface));
- public static int Count;
private static readonly CoreConfiguration conf = IniConfig.GetIniSection();
// Property to identify the Surface ID
@@ -207,7 +206,7 @@ namespace Greenshot.Editor.Drawing
[NonSerialized] private IDrawableContainer _undrawnElement;
///
- /// the cropcontainer, when cropping this is set, do not serialize
+ /// the crop container, when cropping this is set, do not serialize
///
[NonSerialized] private IDrawableContainer _cropContainer;
@@ -467,7 +466,6 @@ namespace Greenshot.Editor.Drawing
public Surface()
{
_fieldAggregator = new FieldAggregator(this);
- Count++;
_elements = new DrawableContainerList(_uniqueId);
selectedElements = new DrawableContainerList(_uniqueId);
LOG.Debug("Creating surface!");
@@ -550,7 +548,6 @@ namespace Greenshot.Editor.Drawing
{
if (disposing)
{
- Count--;
LOG.Debug("Disposing surface!");
if (_buffer != null)
{
@@ -927,20 +924,23 @@ namespace Greenshot.Editor.Drawing
// Test if it's an url and try to download the image so we have it in the original form
if (possibleUrl != null && possibleUrl.StartsWith("http"))
{
- using Image image = NetworkHelper.DownloadImage(possibleUrl);
- if (image != null)
+ var drawableContainer = NetworkHelper.DownloadImageAsDrawableContainer(possibleUrl);
+ if (drawableContainer != null)
{
- AddImageContainer(image, mouse.X, mouse.Y);
+ drawableContainer.Left = Location.X;
+ drawableContainer.Top = Location.Y;
+ AddElement(drawableContainer);
return;
}
}
}
- foreach (Image image in ClipboardHelper.GetImages(e.Data))
+ foreach (var drawableContainer in ClipboardHelper.GetImages(e.Data))
{
- AddImageContainer(image, mouse.X, mouse.Y);
+ drawableContainer.Left = mouse.X;
+ drawableContainer.Top = mouse.Y;
+ AddElement(drawableContainer);
mouse.Offset(10, 10);
- image.Dispose();
}
}
@@ -2057,17 +2057,15 @@ namespace Greenshot.Editor.Drawing
{
Point pasteLocation = GetPasteLocation(0.1f, 0.1f);
- foreach (Image clipboardImage in ClipboardHelper.GetImages(clipboard))
+ foreach (var drawableContainer in ClipboardHelper.GetImages(clipboard))
{
- if (clipboardImage != null)
- {
- DeselectAllElements();
- IImageContainer container = AddImageContainer(clipboardImage as Bitmap, pasteLocation.X, pasteLocation.Y);
- SelectElement(container);
- clipboardImage.Dispose();
- pasteLocation.X += 10;
- pasteLocation.Y += 10;
- }
+ if (drawableContainer == null) continue;
+ DeselectAllElements();
+ drawableContainer.Left = pasteLocation.X;
+ drawableContainer.Top = pasteLocation.Y;
+ SelectElement(drawableContainer);
+ pasteLocation.X += 10;
+ pasteLocation.Y += 10;
}
}
else if (ClipboardHelper.ContainsText(clipboard))
diff --git a/src/Greenshot.Editor/Drawing/SvgContainer.cs b/src/Greenshot.Editor/Drawing/SvgContainer.cs
index d1a3d1e20..f98f03a32 100644
--- a/src/Greenshot.Editor/Drawing/SvgContainer.cs
+++ b/src/Greenshot.Editor/Drawing/SvgContainer.cs
@@ -21,7 +21,6 @@
using System;
using System.Drawing;
-using System.Drawing.Imaging;
using Greenshot.Base.Core;
using Greenshot.Base.Interfaces;
using Svg;
@@ -44,14 +43,19 @@ namespace Greenshot.Editor.Drawing
protected override Image ComputeBitmap()
{
- var image = ImageHelper.CreateEmpty(Width, Height, PixelFormat.Format32bppRgb, Color.Transparent);
+ //var image = ImageHelper.CreateEmpty(Width, Height, PixelFormat.Format32bppArgb, Color.Transparent);
- _svgDocument.Draw(image);
+ var image = _svgDocument.Draw(Width, Height);
+
if (RotationAngle == 0) return image;
var newImage = image.Rotate(RotationAngle);
image.Dispose();
return newImage;
}
+
+ public override bool HasDefaultSize => true;
+
+ public override Size DefaultSize => new Size((int)_svgDocument.Width, (int)_svgDocument.Height);
}
}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs b/src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs
index 2ad97e093..0c467c0b8 100644
--- a/src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs
+++ b/src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs
@@ -22,9 +22,7 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
-using System.Drawing.Imaging;
using System.Runtime.Serialization;
-using Greenshot.Base.Core;
using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
@@ -78,6 +76,7 @@ namespace Greenshot.Editor.Drawing
base.Dispose(disposing);
}
+ ///
public override void Transform(Matrix matrix)
{
RotationAngle += CalculateAngle(matrix);
@@ -88,34 +87,26 @@ namespace Greenshot.Editor.Drawing
base.Transform(matrix);
}
+ ///
public override void Draw(Graphics graphics, RenderMode rm)
{
- graphics.SmoothingMode = SmoothingMode.HighQuality;
- graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
- graphics.CompositingQuality = CompositingQuality.HighQuality;
- graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
-
if (_cachedImage != null && _cachedImage.Size != Bounds.Size)
{
ResetCachedBitmap();
}
- _cachedImage ??= ComputeBitmap();
+ _cachedImage ??= ComputeBitmap();
+
+ graphics.SmoothingMode = SmoothingMode.HighQuality;
+ graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
+ graphics.CompositingQuality = CompositingQuality.HighQuality;
+ graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
+
graphics.DrawImage(_cachedImage, Bounds);
}
- protected virtual Image ComputeBitmap()
- {
- var image = ImageHelper.CreateEmpty(Width, Height, PixelFormat.Format32bppRgb, Color.Transparent);
-
- if (RotationAngle == 0) return image;
-
- var newImage = image.Rotate(RotationAngle);
- image.Dispose();
- return newImage;
-
- }
+ protected abstract Image ComputeBitmap();
private void ResetCachedBitmap()
{
diff --git a/src/Greenshot.Editor/EditorInitialize.cs b/src/Greenshot.Editor/EditorInitialize.cs
index e3b2667fd..47a50e7ac 100644
--- a/src/Greenshot.Editor/EditorInitialize.cs
+++ b/src/Greenshot.Editor/EditorInitialize.cs
@@ -29,6 +29,11 @@ namespace Greenshot.Editor
public static void Initialize()
{
FileFormatHandlerRegistry.FileFormatHandlers.Add(new SvgFileFormatHandler());
+ FileFormatHandlerRegistry.FileFormatHandlers.Add(new DefaultFileFormatHandler());
+ FileFormatHandlerRegistry.FileFormatHandlers.Add(new DibFileFormatHandler());
+ FileFormatHandlerRegistry.FileFormatHandlers.Add(new GreenshotFileFormatHandler());
+ FileFormatHandlerRegistry.FileFormatHandlers.Add(new IconFileFormatHandler());
+ FileFormatHandlerRegistry.FileFormatHandlers.Add(new MetaFileFormatHandler());
}
}
}
diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/DefaultFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs
similarity index 68%
rename from src/Greenshot.Base/Core/FileFormatHandlers/DefaultFileFormatHandler.cs
rename to src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs
index 74d2e3573..419e1898e 100644
--- a/src/Greenshot.Base/Core/FileFormatHandlers/DefaultFileFormatHandler.cs
+++ b/src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs
@@ -19,44 +19,36 @@
* 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 Greenshot.Base.Core;
+using Greenshot.Base.Core.FileFormatHandlers;
using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
+using Greenshot.Editor.Drawing;
-namespace Greenshot.Base.Core.FileFormatHandlers
+namespace Greenshot.Editor.FileFormatHandlers
{
///
/// This is the default .NET bitmap file format handler
///
- public class DefaultFileFormatHandler : IFileFormatHandler
+ public class DefaultFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{
- private static readonly string [] OurExtensions = { "png", "bmp", "gif", "jpg", "jpeg", "tiff", "tif" };
+ private static readonly string [] OurExtensions = { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff", ".tif" };
///
public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction)
{
- if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
- {
- return Enumerable.Empty();
- }
-
return OurExtensions;
}
///
public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension)
{
- if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
- {
- return false;
- }
-
- return OurExtensions.Contains(extension?.ToLowerInvariant());
+ return OurExtensions.Contains(NormalizeExtension(extension));
}
///
@@ -68,15 +60,15 @@ namespace Greenshot.Base.Core.FileFormatHandlers
///
public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension)
{
- ImageFormat imageFormat = extension?.ToLowerInvariant() switch
+ ImageFormat imageFormat = NormalizeExtension(extension) switch
{
- "png" => ImageFormat.Png,
- "bmp" => ImageFormat.Bmp,
- "gif" => ImageFormat.Gif,
- "jpg" => ImageFormat.Jpeg,
- "jpeg" => ImageFormat.Jpeg,
- "tiff" => ImageFormat.Tiff,
- "tif" => ImageFormat.Tiff,
+ ".png" => ImageFormat.Png,
+ ".bmp" => ImageFormat.Bmp,
+ ".gif" => ImageFormat.Gif,
+ ".jpg" => ImageFormat.Jpeg,
+ ".jpeg" => ImageFormat.Jpeg,
+ ".tiff" => ImageFormat.Tiff,
+ ".tif" => ImageFormat.Tiff,
_ => null
};
@@ -97,9 +89,20 @@ namespace Greenshot.Base.Core.FileFormatHandlers
}
///
- public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface)
+ public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface = null)
{
- throw new NotImplementedException();
+ if (TryLoadFromStream(stream, extension, out var bitmap))
+ {
+ var imageContainer = new ImageContainer(surface)
+ {
+ Image = bitmap
+ };
+ drawableContainer = imageContainer;
+ return true;
+ }
+
+ drawableContainer = null;
+ return true;
}
}
}
diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/DibFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs
similarity index 68%
rename from src/Greenshot.Base/Core/FileFormatHandlers/DibFileFormatHandler.cs
rename to src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs
index 79c78ef27..495f669b9 100644
--- a/src/Greenshot.Base/Core/FileFormatHandlers/DibFileFormatHandler.cs
+++ b/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs
@@ -26,40 +26,36 @@ using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
+using Greenshot.Base.Core;
+using Greenshot.Base.Core.FileFormatHandlers;
using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Base.UnmanagedHelpers;
+using Greenshot.Editor.Drawing;
+using log4net;
-namespace Greenshot.Base.Core.FileFormatHandlers
+namespace Greenshot.Editor.FileFormatHandlers
{
///
/// This handles creating a DIB (Device Independent Bitmap) on the clipboard
///
- public class DibFileFormatHandler : IFileFormatHandler
+ public class DibFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{
private const double DpiToPelsPerMeter = 39.3701;
- private static readonly string [] OurExtensions = { "dib" };
+ private static readonly ILog Log = LogManager.GetLogger(typeof(DibFileFormatHandler));
+ private static readonly string [] OurExtensions = { ".dib", ".format17" };
///
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());
+ extension = NormalizeExtension(extension);
+ return OurExtensions.Contains(extension);
}
///
@@ -79,13 +75,79 @@ namespace Greenshot.Base.Core.FileFormatHandlers
///
public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
{
- throw new NotImplementedException();
+ byte[] dibBuffer = new byte[stream.Length];
+ _ = stream.Read(dibBuffer, 0, dibBuffer.Length);
+ var infoHeader = BinaryStructHelper.FromByteArray(dibBuffer);
+ if (!infoHeader.IsDibV5)
+ {
+ Log.InfoFormat("Using special DIB
- public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface)
+ public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface = null)
{
- throw new NotImplementedException();
+ if (TryLoadFromStream(stream, extension, out var bitmap))
+ {
+ var imageContainer = new ImageContainer(surface)
+ {
+ Image = bitmap
+ };
+ drawableContainer = imageContainer;
+ return true;
+ }
+
+ drawableContainer = null;
+ return true;
}
diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs
similarity index 83%
rename from src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs
rename to src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs
index 5370f8934..0a4483884 100644
--- a/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs
+++ b/src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs
@@ -24,14 +24,16 @@ using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
+using Greenshot.Base.Core;
+using Greenshot.Base.Core.FileFormatHandlers;
using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
-namespace Greenshot.Base.Core.FileFormatHandlers
+namespace Greenshot.Editor.FileFormatHandlers
{
- public class GreenshotFileFormatHandler : IFileFormatHandler
+ public class GreenshotFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{
- private static readonly string[] OurExtensions = { "greenshot" };
+ private static readonly string[] OurExtensions = { ".greenshot" };
///
public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction)
@@ -51,8 +53,12 @@ namespace Greenshot.Base.Core.FileFormatHandlers
{
return false;
}
+ if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream)
+ {
+ return false;
+ }
- return OurExtensions.Contains(extension?.ToLowerInvariant());
+ return OurExtensions.Contains(NormalizeExtension(extension));
}
@@ -75,7 +81,7 @@ namespace Greenshot.Base.Core.FileFormatHandlers
return true;
}
- public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent)
+ public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent = null)
{
throw new NotImplementedException();
}
diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/IconFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs
similarity index 86%
rename from src/Greenshot.Base/Core/FileFormatHandlers/IconFileFormatHandler.cs
rename to src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs
index ab92f814e..aa254e760 100644
--- a/src/Greenshot.Base/Core/FileFormatHandlers/IconFileFormatHandler.cs
+++ b/src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs
@@ -25,25 +25,28 @@ using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
+using Greenshot.Base.Core;
+using Greenshot.Base.Core.FileFormatHandlers;
using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
+using Greenshot.Editor.Drawing;
using log4net;
-namespace Greenshot.Base.Core.FileFormatHandlers
+namespace Greenshot.Editor.FileFormatHandlers
{
///
/// THis is the default .NET bitmap file format handler
///
- public class IconFileFormatHandler : IFileFormatHandler
+ public class IconFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{
private static readonly ILog Log = LogManager.GetLogger(typeof(ImageHelper));
- private static readonly string[] OurExtensions = { "ico" };
+ private static readonly string[] OurExtensions = { ".ico" };
///
public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction)
{
- if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
+ if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream)
{
return Enumerable.Empty();
}
@@ -54,12 +57,12 @@ namespace Greenshot.Base.Core.FileFormatHandlers
///
public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension)
{
- if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
+ if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream)
{
return false;
}
- return OurExtensions.Contains(extension?.ToLowerInvariant());
+ return OurExtensions.Contains(NormalizeExtension(extension));
}
///
@@ -76,7 +79,7 @@ namespace Greenshot.Base.Core.FileFormatHandlers
public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
{
- var startingPosition = stream.Seek(0, SeekOrigin.Current);
+ _ = stream.Seek(0, SeekOrigin.Current);
// Icon logic, try to get the Vista icon, else the biggest possible
try
@@ -113,10 +116,20 @@ namespace Greenshot.Base.Core.FileFormatHandlers
}
- public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent)
+ public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface = null)
{
- // TODO: Implement this
- throw new NotImplementedException();
+ if (TryLoadFromStream(stream, extension, out var bitmap))
+ {
+ var imageContainer = new ImageContainer(surface)
+ {
+ Image = bitmap
+ };
+ drawableContainer = imageContainer;
+ return true;
+ }
+
+ drawableContainer = null;
+ return true;
}
///
diff --git a/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs
new file mode 100644
index 000000000..42280c0c2
--- /dev/null
+++ b/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs
@@ -0,0 +1,108 @@
+/*
+ * 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 System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+using Greenshot.Base.Core;
+using Greenshot.Base.Core.FileFormatHandlers;
+using Greenshot.Base.Interfaces;
+using Greenshot.Base.Interfaces.Drawing;
+using Greenshot.Editor.Drawing;
+
+namespace Greenshot.Editor.FileFormatHandlers
+{
+ ///
+ /// This handles the Windows metafile files
+ ///
+ public class MetaFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
+ {
+ private static readonly string [] OurExtensions = { ".wmf", ".emf" };
+
+ ///
+ public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction)
+ {
+ if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream)
+ {
+ return Enumerable.Empty();
+ }
+
+ return OurExtensions;
+ }
+
+ ///
+ public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension)
+ {
+ if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream)
+ {
+ return false;
+ }
+
+ return OurExtensions.Contains(NormalizeExtension(extension));
+ }
+
+ ///
+ public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension)
+ {
+ return int.MaxValue;
+ }
+
+ ///
+ public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension)
+ {
+ return false;
+ }
+
+ ///
+ public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
+ {
+ try
+ {
+ if (Image.FromStream(stream, true, true) is Metafile metaFile)
+ {
+ bitmap = ImageHelper.Clone(metaFile, PixelFormat.Format32bppArgb);
+ return true;
+ }
+ }
+ catch
+ {
+ // Ignore
+ }
+ bitmap = null;
+ return false;
+ }
+
+ ///
+ public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface = null)
+ {
+ if (Image.FromStream(stream, true, true) is Metafile metaFile)
+ {
+ drawableContainer = new MetafileContainer(metaFile, surface);
+ return true;
+ }
+
+ drawableContainer = null;
+ return false;
+ }
+ }
+}
diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/PngFileFormatHandler.cs
similarity index 98%
rename from src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs
rename to src/Greenshot.Editor/FileFormatHandlers/PngFileFormatHandler.cs
index 84ed74c17..a7a2820d5 100644
--- a/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs
+++ b/src/Greenshot.Editor/FileFormatHandlers/PngFileFormatHandler.cs
@@ -27,7 +27,7 @@ using System.Linq;
using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
-namespace Greenshot.Base.Core.FileFormatHandlers
+namespace Greenshot.Editor.FileFormatHandlers
{
///
/// This can be an ImageSharp implementation
diff --git a/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs
index aa0a512de..17c3eb542 100644
--- a/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs
+++ b/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs
@@ -26,6 +26,7 @@ using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using Greenshot.Base.Core;
+using Greenshot.Base.Core.FileFormatHandlers;
using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing;
@@ -37,15 +38,15 @@ namespace Greenshot.Editor.FileFormatHandlers
///
/// This handled the loading of SVG images to the editor
///
- public class SvgFileFormatHandler : IFileFormatHandler
+ public class SvgFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{
- private static readonly ILog Log = LogManager.GetLogger(typeof(ImageHelper));
- private static readonly string[] OurExtensions = { "svg" };
+ private static readonly ILog Log = LogManager.GetLogger(typeof(SvgFileFormatHandler));
+ private static readonly string[] OurExtensions = { ".svg" };
///
public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction)
{
- if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
+ if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream)
{
return Enumerable.Empty();
}
@@ -56,12 +57,12 @@ namespace Greenshot.Editor.FileFormatHandlers
///
public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension)
{
- if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
+ if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream)
{
return false;
}
- return OurExtensions.Contains(extension);
+ return OurExtensions.Contains(NormalizeExtension(extension));
}
///
public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension)
@@ -96,9 +97,14 @@ namespace Greenshot.Editor.FileFormatHandlers
return false;
}
- public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent)
+ public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent = null)
{
var svgDocument = SvgDocument.Open(stream);
+ if (svgDocument == null)
+ {
+ drawableContainer = null;
+ return false;
+ }
drawableContainer = new SvgContainer(svgDocument, parent);
return true;
}
diff --git a/src/Greenshot.Editor/Greenshot.Editor.csproj b/src/Greenshot.Editor/Greenshot.Editor.csproj
index 768bdb99d..7da9d555d 100644
--- a/src/Greenshot.Editor/Greenshot.Editor.csproj
+++ b/src/Greenshot.Editor/Greenshot.Editor.csproj
@@ -1,4 +1,7 @@
+
+ True
+
PreserveNewest
diff --git a/src/Greenshot/Helpers/CaptureHelper.cs b/src/Greenshot/Helpers/CaptureHelper.cs
index 3d0d3385d..5e031c6af 100644
--- a/src/Greenshot/Helpers/CaptureHelper.cs
+++ b/src/Greenshot/Helpers/CaptureHelper.cs
@@ -389,6 +389,7 @@ namespace Greenshot.Helpers
HandleCapture();
break;
case CaptureMode.Clipboard:
+ // TODO: Fix getting image vs. drawablecontainer
Image clipboardImage = ClipboardHelper.GetImage();
if (clipboardImage != null)
{