Added a routine to get the WIC supported extensions automatically.

This commit is contained in:
Robin Krom 2022-02-19 00:37:36 +01:00
commit baad75aacc
No known key found for this signature in database
GPG key ID: BCC01364F1371490
7 changed files with 70 additions and 17 deletions

View file

@ -523,9 +523,9 @@ EndSelection:<<<<<<<4
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList();
foreach (var fileData in IterateClipboardContent(dataObject))
foreach (var (stream, filename) in IterateClipboardContent(dataObject))
{
var extension = Path.GetExtension(fileData.filename)?.ToLowerInvariant();
var extension = Path.GetExtension(filename)?.ToLowerInvariant();
if (!supportedExtensions.Contains(extension))
{
continue;
@ -535,7 +535,7 @@ EndSelection:<<<<<<<4
try
{
if (!fileFormatHandlers.TryLoadFromStream(fileData.stream, extension, out bitmap))
if (!fileFormatHandlers.TryLoadFromStream(stream, extension, out bitmap))
{
continue;
}
@ -548,7 +548,7 @@ EndSelection:<<<<<<<4
}
finally
{
fileData.stream?.Dispose();
stream?.Dispose();
}
// If we get here, there is an image
yield return bitmap;
@ -601,9 +601,9 @@ EndSelection:<<<<<<<4
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList();
foreach (var fileData in IterateClipboardContent(dataObject))
foreach (var (stream, filename) in IterateClipboardContent(dataObject))
{
var extension = Path.GetExtension(fileData.filename)?.ToLowerInvariant();
var extension = Path.GetExtension(filename)?.ToLowerInvariant();
if (!supportedExtensions.Contains(extension))
{
continue;
@ -612,7 +612,7 @@ EndSelection:<<<<<<<4
IEnumerable<IDrawableContainer> drawableContainers;
try
{
drawableContainers = fileFormatHandlers.LoadDrawablesFromStream(fileData.stream, extension);
drawableContainers = fileFormatHandlers.LoadDrawablesFromStream(stream, extension);
}
catch (Exception ex)
{
@ -621,7 +621,7 @@ EndSelection:<<<<<<<4
}
finally
{
fileData.stream?.Dispose();
stream?.Dispose();
}
// If we get here, there is an image
foreach (var container in drawableContainers)

View file

@ -58,7 +58,7 @@ namespace Greenshot.Base.Core.FileFormatHandlers
/// <returns></returns>
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().OrderBy(e => e);
}
/// <summary>

View file

@ -26,7 +26,6 @@ using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using Greenshot.Base.Core;
using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Plugin;
using log4net;
@ -40,7 +39,6 @@ namespace Greenshot.Editor.FileFormatHandlers
{
private static readonly ILog Log = LogManager.GetLogger(typeof(DefaultFileFormatHandler));
private readonly IReadOnlyCollection<string> _ourExtensions = new[] { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff", ".tif" };
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
public DefaultFileFormatHandler()
{
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;

View file

@ -21,14 +21,15 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Media.Imaging;
using Greenshot.Base.Interfaces;
using Greenshot.Base.Core;
using Greenshot.Base.Interfaces.Plugin;
using log4net;
using Microsoft.Win32;
namespace Greenshot.Editor.FileFormatHandlers
{
@ -38,16 +39,67 @@ namespace Greenshot.Editor.FileFormatHandlers
public class WpfFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{
private static readonly ILog Log = LogManager.GetLogger(typeof(WpfFileFormatHandler));
private IReadOnlyCollection<string> LoadFromStreamExtensions { get; } = new []{ ".jxr", ".wdp", ".wmp", ".heic", ".heif" };
private const string HeifDecoder = "{E9A4A80A-44FE-4DE4-8971-7150B10A5199}";
private const string WicDecoderCategory = "{7ED96837-96F0-4812-B211-F13C24117ED3}";
private IReadOnlyCollection<string> LoadFromStreamExtensions { get; } = new []{ ".jxr", ".dds", ".hdp", ".wdp", ".wmp"};
private IReadOnlyCollection<string> SaveToStreamExtensions { get; } = new[] { ".jxr" };
public WpfFileFormatHandler()
{
LoadFromStreamExtensions = LoadFromStreamExtensions.ToList().Concat(RetrieveSupportedExtensions()).OrderBy(e => e).Distinct().ToArray();
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = LoadFromStreamExtensions;
SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = LoadFromStreamExtensions;
SupportedExtensions[FileFormatHandlerActions.SaveToStream] = SaveToStreamExtensions;
}
/// <summary>
/// Detect all the formats WIC supports
/// </summary>
/// <returns>IEnumerable{string}</returns>
private IEnumerable<string> RetrieveSupportedExtensions()
{
string baseKeyPath;
if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
{
baseKeyPath = "Wow6432Node\\CLSID";
}
else
{
baseKeyPath = "CLSID";
}
using RegistryKey baseKey = Registry.ClassesRoot.OpenSubKey(baseKeyPath, false);
if (baseKey == null) yield break;
var wicDecoderCategoryPath = Path.Combine(baseKeyPath, WicDecoderCategory, "instance");
using RegistryKey categoryKey = Registry.ClassesRoot.OpenSubKey(wicDecoderCategoryPath, false);
if (categoryKey == null)
{
yield break;
}
foreach (var codecGuid in categoryKey.GetSubKeyNames())
{
// Read the properties of the single registered decoder
using var codecKey = baseKey.OpenSubKey(codecGuid);
if (codecKey == null) continue;
var fileExtensions = Convert.ToString(codecKey.GetValue("FileExtensions", "")).ToLowerInvariant();
foreach (var fileExtension in fileExtensions.Split(','))
{
yield return fileExtension;
}
}
var heifDecoderPath = Path.Combine(baseKeyPath, HeifDecoder);
using RegistryKey heifKey = Registry.ClassesRoot.OpenSubKey(heifDecoderPath, false);
if (heifKey == null) yield break;
yield return ".heic";
yield return ".heif";
}
/// <inheritdoc />
public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null)
{

View file

@ -181,6 +181,9 @@ namespace Greenshot.Editor.Forms
UpdateUi();
// Use best fit
ZoomBestFitMenuItemClick(this, EventArgs.Empty);
// Workaround: As the cursor is (mostly) selected on the surface a funny artifact is visible, this fixes it.
HideToolstripItems();
}

View file

@ -44,6 +44,7 @@ using Greenshot.Base.Interfaces.Plugin;
using Greenshot.Base.UnmanagedHelpers;
using Greenshot.Configuration;
using Greenshot.Destinations;
using Greenshot.Editor;
using Greenshot.Editor.Destinations;
using Greenshot.Editor.Drawing;
using Greenshot.Editor.Forms;
@ -163,7 +164,7 @@ namespace Greenshot.Forms
if (argument.ToLower().Equals("/exit"))
{
// unregister application on uninstall (allow uninstall)
// un-register application on uninstall (allow uninstall)
try
{
LOG.Info("Sending all instances the exit command.");
@ -388,6 +389,8 @@ namespace Greenshot.Forms
_instance = this;
EditorInitialize.Initialize();
// Factory for surface objects
ISurface SurfaceFactory() => new Surface();

View file

@ -20,11 +20,9 @@
*/
using System;
using System.Drawing.Imaging;
using System.Globalization;
using System.Net;
using System.Reflection;
using Greenshot.Editor;
using Greenshot.Forms;
namespace Greenshot
@ -67,7 +65,6 @@ namespace Greenshot
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;
EditorInitialize.Initialize();
MainForm.Start(args);
}
}