Moved the list of IFileFormatHandler to the SimpleServiceProvider

This commit is contained in:
Robin Krom 2022-02-11 22:17:31 +01:00
commit 6761190643
No known key found for this signature in database
GPG key ID: BCC01364F1371490
16 changed files with 233 additions and 99 deletions

View file

@ -301,8 +301,8 @@ EndSelection:<<<<<<<4
{ {
return true; return true;
} }
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList(); var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList();
foreach (var fileData in IterateClipboardContent(dataObject)) foreach (var fileData in IterateClipboardContent(dataObject))
{ {
try try
@ -520,7 +520,8 @@ EndSelection:<<<<<<<4
yield break; yield break;
} }
var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList(); var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList();
foreach (var fileData in IterateClipboardContent(dataObject)) foreach (var fileData in IterateClipboardContent(dataObject))
{ {
@ -534,7 +535,7 @@ EndSelection:<<<<<<<4
try try
{ {
if (!FileFormatHandlerRegistry.TryLoadFromStream(fileData.stream, extension, out bitmap)) if (!fileFormatHandlers.TryLoadFromStream(fileData.stream, extension, out bitmap))
{ {
continue; continue;
} }
@ -566,7 +567,7 @@ EndSelection:<<<<<<<4
using FileStream fileStream = new FileStream(imageFile, FileMode.Open, FileAccess.Read, FileShare.Read); using FileStream fileStream = new FileStream(imageFile, FileMode.Open, FileAccess.Read, FileShare.Read);
try try
{ {
if (!FileFormatHandlerRegistry.TryLoadFromStream(fileStream, extension, out bitmap)) if (!fileFormatHandlers.TryLoadFromStream(fileStream, extension, out bitmap))
{ {
continue; continue;
} }
@ -597,8 +598,8 @@ EndSelection:<<<<<<<4
yield return singleImage; yield return singleImage;
yield break; yield break;
} }
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList(); var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList();
foreach (var fileData in IterateClipboardContent(dataObject)) foreach (var fileData in IterateClipboardContent(dataObject))
{ {
@ -612,7 +613,7 @@ EndSelection:<<<<<<<4
try try
{ {
if (!FileFormatHandlerRegistry.TryLoadDrawableFromStream(fileData.stream, extension, out drawableContainer)) if (!fileFormatHandlers.TryLoadDrawableFromStream(fileData.stream, extension, out drawableContainer))
{ {
continue; continue;
} }
@ -644,7 +645,7 @@ EndSelection:<<<<<<<4
using FileStream fileStream = new FileStream(imageFile, FileMode.Open, FileAccess.Read, FileShare.Read); using FileStream fileStream = new FileStream(imageFile, FileMode.Open, FileAccess.Read, FileShare.Read);
try try
{ {
if (!FileFormatHandlerRegistry.TryLoadDrawableFromStream(fileStream, extension, out drawableContainer)) if (!fileFormatHandlers.TryLoadDrawableFromStream(fileStream, extension, out drawableContainer))
{ {
continue; continue;
} }
@ -812,9 +813,10 @@ EndSelection:<<<<<<<4
{ {
return clipboardObject as Bitmap; return clipboardObject as Bitmap;
} }
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
// From here, imageStream is a valid stream // From here, imageStream is a valid stream
if (!FileFormatHandlerRegistry.TryLoadFromStream(imageStream, format, out bitmap)) if (!fileFormatHandlers.TryLoadFromStream(imageStream, format, out bitmap))
{ {
return bitmap; return bitmap;
} }
@ -880,8 +882,9 @@ EndSelection:<<<<<<<4
} }
// From here, imageStream is a valid stream // From here, imageStream is a valid stream
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
if (!FileFormatHandlerRegistry.TryLoadDrawableFromStream(imageStream, format, out drawableContainer)) if (!fileFormatHandlers.TryLoadDrawableFromStream(imageStream, format, out drawableContainer))
{ {
return drawableContainer; return drawableContainer;
} }
@ -995,8 +998,9 @@ EndSelection:<<<<<<<4
{ {
// Create the stream for the clipboard // Create the stream for the clipboard
dibStream = new MemoryStream(); dibStream = new MemoryStream();
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
if (!FileFormatHandlerRegistry.TrySaveToStream((Bitmap)imageToSave, dibStream, DataFormats.Dib)) if (!fileFormatHandlers.TrySaveToStream((Bitmap)imageToSave, dibStream, DataFormats.Dib))
{ {
dibStream.Dispose(); dibStream.Dispose();
dibStream = null; dibStream = null;
@ -1261,8 +1265,9 @@ EndSelection:<<<<<<<4
{ {
string[] dropFileNames = (string[])dataObject.GetData(DataFormats.FileDrop); string[] dropFileNames = (string[])dataObject.GetData(DataFormats.FileDrop);
if (dropFileNames is not { Length: > 0 }) return Enumerable.Empty<string>(); if (dropFileNames is not { Length: > 0 }) return Enumerable.Empty<string>();
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).ToList(); var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).ToList();
return dropFileNames return dropFileNames
.Where(filename => !string.IsNullOrEmpty(filename)) .Where(filename => !string.IsNullOrEmpty(filename))
.Where(Path.HasExtension) .Where(Path.HasExtension)

View file

@ -31,10 +31,8 @@ namespace Greenshot.Base.Core.FileFormatHandlers
/// <summary> /// <summary>
/// This is the registry where all IFileFormatHandler are registered and can be used /// This is the registry where all IFileFormatHandler are registered and can be used
/// </summary> /// </summary>
public static class FileFormatHandlerRegistry public static class FileFormatHandlerExtensions
{ {
public static IList<IFileFormatHandler> FileFormatHandlers { get; } = new List<IFileFormatHandler>();
/// <summary> /// <summary>
/// Make sure we handle the input extension always the same, by "normalizing" it /// Make sure we handle the input extension always the same, by "normalizing" it
/// </summary> /// </summary>
@ -52,13 +50,14 @@ namespace Greenshot.Base.Core.FileFormatHandlers
} }
/// <summary> /// <summary>
/// /// Return the extensions that the provided IFileFormatHandlers can accept for the specified action
/// </summary> /// </summary>
/// <param name="fileFormatHandlers">IEnumerable{IFileFormatHandler}</param>
/// <param name="fileFormatHandlerAction"></param> /// <param name="fileFormatHandlerAction"></param>
/// <returns></returns> /// <returns></returns>
public static IEnumerable<string> ExtensionsFor(FileFormatHandlerActions fileFormatHandlerAction) public static IEnumerable<string> ExtensionsFor(this IEnumerable<IFileFormatHandler> fileFormatHandlers, FileFormatHandlerActions fileFormatHandlerAction)
{ {
return FileFormatHandlers.Where(ffh => ffh.SupportedExtensions.ContainsKey(fileFormatHandlerAction)).SelectMany(ffh => ffh.SupportedExtensions[fileFormatHandlerAction]).Distinct(); return fileFormatHandlers.Where(ffh => ffh.SupportedExtensions.ContainsKey(fileFormatHandlerAction)).SelectMany(ffh => ffh.SupportedExtensions[fileFormatHandlerAction]).Distinct();
} }
/// <summary> /// <summary>
@ -79,76 +78,87 @@ namespace Greenshot.Base.Core.FileFormatHandlers
/// Find all the IFileFormatHandler which support the action for the supplied extension. /// Find all the IFileFormatHandler which support the action for the supplied extension.
/// Take the first, to call the TrySaveToStream on. /// Take the first, to call the TrySaveToStream on.
/// </summary> /// </summary>
/// <param name="fileFormatHandlers">IEnumerable{IFileFormatHandler}</param>
/// <param name="bitmap">Bitmap</param> /// <param name="bitmap">Bitmap</param>
/// <param name="destination">Stream</param> /// <param name="destination">Stream</param>
/// <param name="extension">string</param> /// <param name="extension">string</param>
/// <param name="surface">ISurface</param>
/// <returns>bool</returns> /// <returns>bool</returns>
public static bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null) public static bool TrySaveToStream(this IEnumerable<IFileFormatHandler> fileFormatHandlers, Bitmap bitmap, Stream destination, string extension, ISurface surface = null)
{ {
extension = NormalizeExtension(extension); extension = NormalizeExtension(extension);
var fileFormatHandler = FileFormatHandlers var saveFileFormatHandlers = fileFormatHandlers
.Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension)) .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension))
.OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension)) .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension)).ToList();
.FirstOrDefault();
if (fileFormatHandler == null) if (!saveFileFormatHandlers.Any())
{ {
return false; return false;
} }
return fileFormatHandler.TrySaveToStream(bitmap, destination, extension, surface); foreach (var fileFormatHandler in saveFileFormatHandlers)
{
if (fileFormatHandler.TrySaveToStream(bitmap, destination, extension, surface))
{
return true;
}
}
return false;
} }
/// <summary> /// <summary>
/// Try to load a drawable container from the stream /// Try to load a drawable container from the stream
/// </summary> /// </summary>
/// <param name="fileFormatHandlers">IEnumerable{IFileFormatHandler}</param>
/// <param name="stream">Stream</param> /// <param name="stream">Stream</param>
/// <param name="extension">string</param> /// <param name="extension">string</param>
/// <param name="drawableContainer">IDrawableContainer out</param> /// <param name="drawableContainer">IDrawableContainer out</param>
/// <param name="parentSurface">ISurface</param> /// <param name="parentSurface">ISurface</param>
/// <returns>bool true if it was successful</returns> /// <returns>bool true if it was successful</returns>
public static bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parentSurface = null) public static bool TryLoadDrawableFromStream(this IEnumerable<IFileFormatHandler> fileFormatHandlers, Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parentSurface = null)
{ {
extension = NormalizeExtension(extension); extension = NormalizeExtension(extension);
var fileFormatHandler = FileFormatHandlers var loadfileFormatHandler = fileFormatHandlers
.Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadDrawableFromStream, extension)) .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadDrawableFromStream, extension))
.OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadDrawableFromStream, extension)) .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadDrawableFromStream, extension))
.FirstOrDefault(); .FirstOrDefault();
if (fileFormatHandler == null) if (loadfileFormatHandler == null)
{ {
drawableContainer = null; drawableContainer = null;
return false; return false;
} }
return fileFormatHandler.TryLoadDrawableFromStream(stream, extension, out drawableContainer, parentSurface); return loadfileFormatHandler.TryLoadDrawableFromStream(stream, extension, out drawableContainer, parentSurface);
} }
/// <summary> /// <summary>
/// Try to load a Bitmap from the stream /// Try to load a Bitmap from the stream
/// </summary> /// </summary>
/// <param name="fileFormatHandlers">IEnumerable{IFileFormatHandler}</param>
/// <param name="stream">Stream</param> /// <param name="stream">Stream</param>
/// <param name="extension">string</param> /// <param name="extension">string</param>
/// <param name="bitmap">Bitmap out</param> /// <param name="bitmap">Bitmap out</param>
/// <returns>bool true if it was successful</returns> /// <returns>bool true if it was successful</returns>
public static bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) public static bool TryLoadFromStream(this IEnumerable<IFileFormatHandler> fileFormatHandlers, Stream stream, string extension, out Bitmap bitmap)
{ {
extension = NormalizeExtension(extension); extension = NormalizeExtension(extension);
var fileFormatHandler = FileFormatHandlers var loadFileFormatHandler = fileFormatHandlers
.Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension)) .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension))
.OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension)) .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension))
.FirstOrDefault(); .FirstOrDefault();
if (fileFormatHandler == null) if (loadFileFormatHandler == null)
{ {
bitmap = null; bitmap = null;
return false; return false;
} }
return fileFormatHandler.TryLoadFromStream(stream, extension, out bitmap); return loadFileFormatHandler.TryLoadFromStream(stream, extension, out bitmap);
} }
} }
} }

View file

@ -1711,8 +1711,8 @@ namespace Greenshot.Base.Core
// As we are if a different stream, which starts at 0, change the starting position // As we are if a different stream, which starts at 0, change the starting position
startingPosition = 0; startingPosition = 0;
} }
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
foreach (var fileFormatHandler in FileFormatHandlerRegistry.FileFormatHandlers foreach (var fileFormatHandler in fileFormatHandlers
.Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension)) .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension))
.OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension))) .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension)))
{ {

View file

@ -135,8 +135,8 @@ namespace Greenshot.Base.Core
targetStream = memoryStream; targetStream = memoryStream;
} }
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
if (!FileFormatHandlerRegistry.TrySaveToStream(imageToSave as Bitmap, targetStream, outputSettings.Format.ToString(), surface)) if (!fileFormatHandlers.TrySaveToStream(imageToSave as Bitmap, targetStream, outputSettings.Format.ToString(), surface))
{ {
return; return;
} }

View file

@ -24,6 +24,7 @@ using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq;
using System.Net; using System.Net;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -95,7 +96,8 @@ namespace Greenshot.Base.Core
/// <returns>IDrawableContainer</returns> /// <returns>IDrawableContainer</returns>
public static IDrawableContainer DownloadImageAsDrawableContainer(string url) public static IDrawableContainer DownloadImageAsDrawableContainer(string url)
{ {
var extensions = string.Join("|", FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream)); var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
var extensions = string.Join("|", fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadFromStream));
var imageUrlRegex = new Regex($@"(http|https)://.*(?<extension>{extensions})"); var imageUrlRegex = new Regex($@"(http|https)://.*(?<extension>{extensions})");
var match = imageUrlRegex.Match(url); var match = imageUrlRegex.Match(url);
@ -104,7 +106,7 @@ namespace Greenshot.Base.Core
using var memoryStream = GetAsMemoryStream(url); using var memoryStream = GetAsMemoryStream(url);
try try
{ {
if (FileFormatHandlerRegistry.TryLoadDrawableFromStream(memoryStream, match.Success ? match.Groups["extension"]?.Value : null, out var drawableContainer)) if (fileFormatHandlers.TryLoadDrawableFromStream(memoryStream, match.Success ? match.Groups["extension"]?.Value : null, out var drawableContainer))
{ {
return drawableContainer; return drawableContainer;
} }
@ -130,7 +132,7 @@ namespace Greenshot.Base.Core
} }
using var memoryStream2 = GetAsMemoryStream(match.Value); using var memoryStream2 = GetAsMemoryStream(match.Value);
if (FileFormatHandlerRegistry.TryLoadDrawableFromStream(memoryStream2, match.Success ? match.Groups["extension"]?.Value : null, out var drawableContainer)) if (fileFormatHandlers.TryLoadDrawableFromStream(memoryStream2, match.Success ? match.Groups["extension"]?.Value : null, out var drawableContainer))
{ {
return drawableContainer; return drawableContainer;
} }
@ -151,7 +153,9 @@ namespace Greenshot.Base.Core
/// <returns>Bitmap</returns> /// <returns>Bitmap</returns>
public static Bitmap DownloadImage(string url) public static Bitmap DownloadImage(string url)
{ {
var extensions = string.Join("|", FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream)); var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
var extensions = string.Join("|", fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadFromStream));
var imageUrlRegex = new Regex($@"(http|https)://.*(?<extension>{extensions})"); var imageUrlRegex = new Regex($@"(http|https)://.*(?<extension>{extensions})");
var match = imageUrlRegex.Match(url); var match = imageUrlRegex.Match(url);
@ -160,7 +164,7 @@ namespace Greenshot.Base.Core
using var memoryStream = GetAsMemoryStream(url); using var memoryStream = GetAsMemoryStream(url);
try try
{ {
if (FileFormatHandlerRegistry.TryLoadFromStream(memoryStream, match.Success ? match.Groups["extension"]?.Value : null, out var bitmap)) if (fileFormatHandlers.TryLoadFromStream(memoryStream, match.Success ? match.Groups["extension"]?.Value : null, out var bitmap))
{ {
return bitmap; return bitmap;
} }
@ -186,7 +190,7 @@ namespace Greenshot.Base.Core
} }
using var memoryStream2 = GetAsMemoryStream(match.Value); using var memoryStream2 = GetAsMemoryStream(match.Value);
if (FileFormatHandlerRegistry.TryLoadFromStream(memoryStream2, match.Success ? match.Groups["extension"]?.Value : null, out var bitmap)) if (fileFormatHandlers.TryLoadFromStream(memoryStream2, match.Success ? match.Groups["extension"]?.Value : null, out var bitmap))
{ {
return bitmap; return bitmap;
} }

View file

@ -10,22 +10,19 @@ namespace Greenshot.Base.Core
/// </summary> /// </summary>
public class SimpleServiceProvider : IServiceLocator public class SimpleServiceProvider : IServiceLocator
{ {
private readonly Dictionary<Type, List<object>> _services = new Dictionary<Type, List<object>>(); private readonly Dictionary<Type, IList<object>> _services = new();
public static IServiceLocator Current { get; } = new SimpleServiceProvider(); public static IServiceLocator Current { get; } = new SimpleServiceProvider();
public IEnumerable<TService> GetAllInstances<TService>() public IReadOnlyList<TService> GetAllInstances<TService>()
{ {
var typeOfService = typeof(TService); var typeOfService = typeof(TService);
if (!_services.TryGetValue(typeOfService, out var results)) if (!_services.TryGetValue(typeOfService, out var results))
{ {
yield break; return Array.Empty<TService>();
} }
foreach (TService result in results) return results.Cast<TService>().ToArray();
{
yield return result;
}
} }
public TService GetInstance<TService>() public TService GetInstance<TService>()

View file

@ -61,9 +61,9 @@ namespace Greenshot.Base.Interfaces
/// <param name="bitmap">Bitmap</param> /// <param name="bitmap">Bitmap</param>
/// <param name="destination">Stream</param> /// <param name="destination">Stream</param>
/// <param name="extension">extension</param> /// <param name="extension">extension</param>
/// <param name="surface">ISurface</param> /// <param name="surface">ISurface with the elements for those file types which can store a surface (.greenshot)</param>
/// <returns>bool true if it was successful</returns> /// <returns>bool true if it was successful</returns>
public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface); public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null);
/// <summary> /// <summary>
/// ///

View file

@ -32,7 +32,7 @@ namespace Greenshot.Base.Interfaces
/// </summary> /// </summary>
/// <typeparam name="TService">Service to find</typeparam> /// <typeparam name="TService">Service to find</typeparam>
/// <returns>IEnumerable{TService}</returns> /// <returns>IEnumerable{TService}</returns>
IEnumerable<TService> GetAllInstances<TService>(); IReadOnlyList<TService> GetAllInstances<TService>();
/// <summary> /// <summary>
/// Get the only instance of the specified service /// Get the only instance of the specified service

View file

@ -19,7 +19,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.Core;
using Greenshot.Base.Interfaces;
using Greenshot.Editor.FileFormatHandlers; using Greenshot.Editor.FileFormatHandlers;
namespace Greenshot.Editor namespace Greenshot.Editor
@ -28,19 +29,22 @@ namespace Greenshot.Editor
{ {
public static void Initialize() public static void Initialize()
{ {
// All generic things, like gif, png, jpg etc. SimpleServiceProvider.Current.AddService<IFileFormatHandler>(
FileFormatHandlerRegistry.FileFormatHandlers.Add(new DefaultFileFormatHandler()); // All generic things, like gif, png, jpg etc.
FileFormatHandlerRegistry.FileFormatHandlers.Add(new GreenshotFileFormatHandler()); new DefaultFileFormatHandler(),
// For .svg support // Greenshot format
FileFormatHandlerRegistry.FileFormatHandlers.Add(new SvgFileFormatHandler()); new GreenshotFileFormatHandler(),
// For clipboard support // For .svg support
FileFormatHandlerRegistry.FileFormatHandlers.Add(new DibFileFormatHandler()); new SvgFileFormatHandler(),
// .ico // For clipboard support
FileFormatHandlerRegistry.FileFormatHandlers.Add(new IconFileFormatHandler()); new DibFileFormatHandler(),
// EMF & WMF // .ico
FileFormatHandlerRegistry.FileFormatHandlers.Add(new MetaFileFormatHandler()); new IconFileFormatHandler(),
// JPG XR // EMF & WMF
FileFormatHandlerRegistry.FileFormatHandlers.Add(new WmpFileFormatHandler()); new MetaFileFormatHandler(),
// JPG XR
new WpfFileFormatHandler()
);
} }
} }
} }

View file

@ -19,15 +19,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Core.FileFormatHandlers;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using log4net;
namespace Greenshot.Editor.FileFormatHandlers namespace Greenshot.Editor.FileFormatHandlers
{ {
@ -36,6 +37,7 @@ namespace Greenshot.Editor.FileFormatHandlers
/// </summary> /// </summary>
public class DefaultFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler public class DefaultFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{ {
private static readonly ILog Log = LogManager.GetLogger(typeof(DefaultFileFormatHandler));
private readonly List<string> _ourExtensions = new() { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff", ".tif" }; private readonly List<string> _ourExtensions = new() { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff", ".tif" };
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
public DefaultFileFormatHandler() public DefaultFileFormatHandler()
@ -85,8 +87,20 @@ namespace Greenshot.Editor.FileFormatHandlers
{ {
// Set that this file was written by Greenshot // Set that this file was written by Greenshot
nonAlphaImage.AddTag(); nonAlphaImage.AddTag();
}
catch (Exception ex)
{
Log.Warn("Couldn't set 'software used' tag on image.", ex);
}
try
{
nonAlphaImage.Save(destination, imageEncoder, parameters); nonAlphaImage.Save(destination, imageEncoder, parameters);
} }
catch (Exception ex)
{
Log.Error("Couldn't save image: ", ex);
}
finally finally
{ {
nonAlphaImage.Dispose(); nonAlphaImage.Dispose();
@ -105,9 +119,20 @@ namespace Greenshot.Editor.FileFormatHandlers
/// <inheritdoc /> /// <inheritdoc />
public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
{ {
using var tmpImage = Image.FromStream(stream, true, true); try
bitmap = ImageHelper.Clone(tmpImage, PixelFormat.Format32bppArgb); {
return true; using var tmpImage = Image.FromStream(stream, true, true);
bitmap = ImageHelper.Clone(tmpImage, PixelFormat.DontCare);
return true;
}
catch (Exception ex)
{
Log.Error("Couldn't load image: ", ex);
}
bitmap = null;
return false;
} }
} }
} }

View file

@ -28,11 +28,13 @@ using System.Reflection;
using System.Text; using System.Text;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using log4net;
namespace Greenshot.Editor.FileFormatHandlers namespace Greenshot.Editor.FileFormatHandlers
{ {
public class GreenshotFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler public class GreenshotFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{ {
private static readonly ILog Log = LogManager.GetLogger(typeof(GreenshotFileFormatHandler));
private readonly List<string> _ourExtensions = new() { ".greenshot" }; private readonly List<string> _ourExtensions = new() { ".greenshot" };
public GreenshotFileFormatHandler() public GreenshotFileFormatHandler()
{ {
@ -43,23 +45,88 @@ namespace Greenshot.Editor.FileFormatHandlers
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)
{ {
bitmap.Save(stream, ImageFormat.Png); if (surface == null)
using MemoryStream tmpStream = new MemoryStream(); {
long bytesWritten = surface.SaveElementsToStream(tmpStream); return false;
using BinaryWriter writer = new BinaryWriter(tmpStream); }
writer.Write(bytesWritten);
Version v = Assembly.GetExecutingAssembly().GetName().Version; try
byte[] marker = Encoding.ASCII.GetBytes($"Greenshot{v.Major:00}.{v.Minor:00}"); {
writer.Write(marker); bitmap.Save(stream, ImageFormat.Png);
tmpStream.WriteTo(stream); using MemoryStream tmpStream = new MemoryStream();
return true; long bytesWritten = surface.SaveElementsToStream(tmpStream);
using BinaryWriter writer = new BinaryWriter(tmpStream);
writer.Write(bytesWritten);
Version v = Assembly.GetExecutingAssembly().GetName().Version;
byte[] marker = Encoding.ASCII.GetBytes($"Greenshot{v.Major:00}.{v.Minor:00}");
writer.Write(marker);
tmpStream.WriteTo(stream);
return true;
}
catch (Exception ex)
{
Log.Error("Couldn't save surface as .greenshot: ", ex);
}
return false;
} }
public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
{ {
var surface = SimpleServiceProvider.Current.GetInstance<Func<ISurface>>().Invoke(); try
bitmap = (Bitmap)surface.GetImageForExport(); {
return true; var surface = LoadSurface(stream);
bitmap = (Bitmap)surface.GetImageForExport();
return true;
}
catch (Exception ex)
{
Log.Error("Couldn't load .greenshot: ", ex);
}
bitmap = null;
return false;
}
private ISurface LoadSurface(Stream surfaceFileStream)
{
var returnSurface = SimpleServiceProvider.Current.GetInstance<Func<ISurface>>().Invoke();
Bitmap captureBitmap;
// Fixed problem that the bitmap stream is disposed... by Cloning the image
// This also ensures the bitmap is correctly created
using (Image tmpImage = Image.FromStream(surfaceFileStream, true, true))
{
Log.DebugFormat("Loaded capture from .greenshot file with Size {0}x{1} and PixelFormat {2}", tmpImage.Width, tmpImage.Height, tmpImage.PixelFormat);
captureBitmap = ImageHelper.Clone(tmpImage) as Bitmap;
}
// Start at -14 read "GreenshotXX.YY" (XX=Major, YY=Minor)
const int markerSize = 14;
surfaceFileStream.Seek(-markerSize, SeekOrigin.End);
using (var 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 (captureBitmap != null)
{
returnSurface.Image = captureBitmap;
Log.InfoFormat("Information about .greenshot file: {0}x{1}-{2} Resolution {3}x{4}", captureBitmap.Width, captureBitmap.Height, captureBitmap.PixelFormat, captureBitmap.HorizontalResolution, captureBitmap.VerticalResolution);
}
return returnSurface;
} }
} }
} }

View file

@ -23,7 +23,6 @@ using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Linq;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;

View file

@ -70,13 +70,20 @@ namespace Greenshot.Editor.FileFormatHandlers
public override bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent = null) public override bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent = null)
{ {
var svgDocument = SvgDocument.Open<SvgDocument>(stream); try
if (svgDocument == null)
{ {
drawableContainer = null; var svgDocument = SvgDocument.Open<SvgDocument>(stream);
return false; if (svgDocument != null)
{
drawableContainer = new SvgContainer(svgDocument, parent);
return true;
}
} }
drawableContainer = new SvgContainer(svgDocument, parent); catch (Exception ex)
{
Log.Error("Can't load SVG", ex);
}
drawableContainer = null;
return true; return true;
} }
} }

View file

@ -19,24 +19,27 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using log4net;
namespace Greenshot.Editor.FileFormatHandlers namespace Greenshot.Editor.FileFormatHandlers
{ {
/// <summary> /// <summary>
/// This is the System.Windows.Media.Imaging (WPF) file format handler /// This is the System.Windows.Media.Imaging (WPF) file format handler, which uses WIC
/// </summary> /// </summary>
public class WmpFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler public class WpfFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{ {
private static readonly ILog Log = LogManager.GetLogger(typeof(WpfFileFormatHandler));
private List<string> LoadFromStreamExtensions { get; } = new() { ".jxr", ".wdp", ".wmp", ".heic", ".heif" }; private List<string> LoadFromStreamExtensions { get; } = new() { ".jxr", ".wdp", ".wmp", ".heic", ".heif" };
private List<string> SaveToStreamExtensions { get; } = new() { ".jxr" }; private List<string> SaveToStreamExtensions { get; } = new() { ".jxr" };
public WmpFileFormatHandler() public WpfFileFormatHandler()
{ {
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = LoadFromStreamExtensions; SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = LoadFromStreamExtensions;
SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = LoadFromStreamExtensions; SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = LoadFromStreamExtensions;
@ -57,8 +60,9 @@ namespace Greenshot.Editor.FileFormatHandlers
jpegXrEncoder.Save(destination); jpegXrEncoder.Save(destination);
return true; return true;
} }
catch catch (Exception ex)
{ {
Log.Error("Couldn't save image as JPEG XR: ", ex);
return false; return false;
} }
} }
@ -66,10 +70,20 @@ namespace Greenshot.Editor.FileFormatHandlers
/// <inheritdoc /> /// <inheritdoc />
public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
{ {
var bitmapDecoder = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None); try
var bitmapSource = bitmapDecoder.Frames[0]; {
bitmap = bitmapSource.ToBitmap(); var bitmapDecoder = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);
return true; var bitmapSource = bitmapDecoder.Frames[0];
bitmap = bitmapSource.ToBitmap();
return true;
}
catch (Exception ex)
{
Log.Error("Couldn't load image: ", ex);
}
bitmap = null;
return false;
} }
} }
} }

View file

@ -937,7 +937,8 @@ namespace Greenshot.Forms
private void CaptureFile(IDestination destination = null) private void CaptureFile(IDestination destination = null)
{ {
var extensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).Select(e => $"*{e}").ToList(); var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
var extensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).Select(e => $"*{e}").ToList();
var openFileDialog = new OpenFileDialog var openFileDialog = new OpenFileDialog
{ {

View file

@ -20,6 +20,7 @@
*/ */
using System; using System;
using System.Drawing.Imaging;
using System.Globalization; using System.Globalization;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;