mirror of
https://github.com/greenshot/greenshot
synced 2025-08-20 21:43:24 -07:00
Merge branch 'release/1.3' into fix/379-preferences-window
# Conflicts: # src/Greenshot/Forms/SettingsForm.Designer.cs
This commit is contained in:
commit
1585d1c2ea
90 changed files with 2795 additions and 1340 deletions
|
@ -120,6 +120,7 @@ namespace Greenshot.Base.Controls
|
||||||
|
|
||||||
private void PrepareFilterOptions()
|
private void PrepareFilterOptions()
|
||||||
{
|
{
|
||||||
|
// TODO: Change to the FileFormatHandlerRegistry to look for all the supported extensions
|
||||||
OutputFormat[] supportedImageFormats = (OutputFormat[]) Enum.GetValues(typeof(OutputFormat));
|
OutputFormat[] supportedImageFormats = (OutputFormat[]) Enum.GetValues(typeof(OutputFormat));
|
||||||
_filterOptions = new FilterOption[supportedImageFormats.Length];
|
_filterOptions = new FilterOption[supportedImageFormats.Length];
|
||||||
for (int i = 0; i < _filterOptions.Length; i++)
|
for (int i = 0; i < _filterOptions.Length; i++)
|
||||||
|
@ -166,7 +167,7 @@ namespace Greenshot.Base.Controls
|
||||||
// if the filename contains a valid extension, which is the same like the selected filter item's extension, the filename is okay
|
// if the filename contains a valid extension, which is the same like the selected filter item's extension, the filename is okay
|
||||||
if (fn.EndsWith(Extension, StringComparison.CurrentCultureIgnoreCase)) return fn;
|
if (fn.EndsWith(Extension, StringComparison.CurrentCultureIgnoreCase)) return fn;
|
||||||
// otherwise we just add the selected filter item's extension
|
// otherwise we just add the selected filter item's extension
|
||||||
else return fn + "." + Extension;
|
return fn + "." + Extension;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,8 +31,10 @@ using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Greenshot.Base.Core.Enums;
|
using Greenshot.Base.Core.Enums;
|
||||||
|
using Greenshot.Base.Core.FileFormatHandlers;
|
||||||
using Greenshot.Base.IniFile;
|
using Greenshot.Base.IniFile;
|
||||||
using Greenshot.Base.Interfaces;
|
using Greenshot.Base.Interfaces;
|
||||||
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Base.Interfaces.Plugin;
|
using Greenshot.Base.Interfaces.Plugin;
|
||||||
using Greenshot.Base.UnmanagedHelpers;
|
using Greenshot.Base.UnmanagedHelpers;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
@ -63,7 +65,8 @@ namespace Greenshot.Base.Core
|
||||||
//private static readonly string FORMAT_HTML = "HTML Format";
|
//private static readonly string FORMAT_HTML = "HTML Format";
|
||||||
|
|
||||||
// Template for the HTML Text on the clipboard
|
// Template for the HTML Text on the clipboard
|
||||||
// see: https://msdn.microsoft.com/en-us/library/ms649015%28v=vs.85%29.aspx
|
// see: https://msdn.microsoft.com/en-us/library/ms649015%28v=v
|
||||||
|
// s.85%29.aspx
|
||||||
// or: https://msdn.microsoft.com/en-us/library/Aa767917.aspx
|
// or: https://msdn.microsoft.com/en-us/library/Aa767917.aspx
|
||||||
private const string HtmlClipboardString = @"Version:0.9
|
private const string HtmlClipboardString = @"Version:0.9
|
||||||
StartHTML:<<<<<<<1
|
StartHTML:<<<<<<<1
|
||||||
|
@ -298,14 +301,15 @@ EndSelection:<<<<<<<4
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
|
||||||
foreach (var fileData in IterateClipboardContent(dataObject))
|
var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList();
|
||||||
|
foreach (var (stream, filename) in IterateClipboardContent(dataObject))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (ImageHelper.FromStream(fileData))
|
var extension = Path.GetExtension(filename)?.ToLowerInvariant();
|
||||||
|
if (supportedExtensions.Contains(extension))
|
||||||
{
|
{
|
||||||
// If we get here, there is an image
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,7 +319,7 @@ EndSelection:<<<<<<<4
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
fileData?.Dispose();
|
stream?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +331,8 @@ EndSelection:<<<<<<<4
|
||||||
var imageStream = clipboardContent as MemoryStream;
|
var imageStream = clipboardContent as MemoryStream;
|
||||||
if (IsValidStream(imageStream))
|
if (IsValidStream(imageStream))
|
||||||
{
|
{
|
||||||
using (ImageHelper.FromStream(imageStream))
|
// TODO: How to check if we support "just a stream"?
|
||||||
|
using (ImageIO.FromStream(imageStream))
|
||||||
{
|
{
|
||||||
// If we get here, there is an image
|
// If we get here, there is an image
|
||||||
return true;
|
return true;
|
||||||
|
@ -373,8 +378,8 @@ EndSelection:<<<<<<<4
|
||||||
/// Iterate the clipboard content
|
/// Iterate the clipboard content
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dataObject">IDataObject</param>
|
/// <param name="dataObject">IDataObject</param>
|
||||||
/// <returns>IEnumerable{MemoryStream}</returns>
|
/// <returns>IEnumerable{(MemoryStream,string)}</returns>
|
||||||
private static IEnumerable<MemoryStream> IterateClipboardContent(IDataObject dataObject)
|
private static IEnumerable<(MemoryStream stream,string filename)> IterateClipboardContent(IDataObject dataObject)
|
||||||
{
|
{
|
||||||
var fileDescriptors = AvailableFileDescriptors(dataObject);
|
var fileDescriptors = AvailableFileDescriptors(dataObject);
|
||||||
if (fileDescriptors == null) yield break;
|
if (fileDescriptors == null) yield break;
|
||||||
|
@ -413,8 +418,8 @@ EndSelection:<<<<<<<4
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileDescriptors">IEnumerable{FileDescriptor}</param>
|
/// <param name="fileDescriptors">IEnumerable{FileDescriptor}</param>
|
||||||
/// <param name="dataObject">IDataObject</param>
|
/// <param name="dataObject">IDataObject</param>
|
||||||
/// <returns>IEnumerable{MemoryStream}</returns>
|
/// <returns>IEnumerable{(MemoryStream stream, string filename)}</returns>
|
||||||
private static IEnumerable<MemoryStream> IterateFileDescriptors(IEnumerable<FileDescriptor> fileDescriptors, IDataObject dataObject)
|
private static IEnumerable<(MemoryStream stream, string filename)> IterateFileDescriptors(IEnumerable<FileDescriptor> fileDescriptors, IDataObject dataObject)
|
||||||
{
|
{
|
||||||
if (fileDescriptors == null)
|
if (fileDescriptors == null)
|
||||||
{
|
{
|
||||||
|
@ -445,7 +450,7 @@ EndSelection:<<<<<<<4
|
||||||
if (fileData?.Length > 0)
|
if (fileData?.Length > 0)
|
||||||
{
|
{
|
||||||
fileData.Position = 0;
|
fileData.Position = 0;
|
||||||
yield return fileData;
|
yield return (fileData, fileDescriptor.FileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
fileIndex++;
|
fileIndex++;
|
||||||
|
@ -490,7 +495,7 @@ EndSelection:<<<<<<<4
|
||||||
{
|
{
|
||||||
IDataObject clipboardData = GetDataObject();
|
IDataObject clipboardData = GetDataObject();
|
||||||
// Return the first image
|
// Return the first image
|
||||||
foreach (Image clipboardImage in GetImages(clipboardData))
|
foreach (var clipboardImage in GetImages(clipboardData))
|
||||||
{
|
{
|
||||||
return clipboardImage;
|
return clipboardImage;
|
||||||
}
|
}
|
||||||
|
@ -503,24 +508,38 @@ EndSelection:<<<<<<<4
|
||||||
/// Returned images must be disposed by the calling code!
|
/// Returned images must be disposed by the calling code!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dataObject"></param>
|
/// <param name="dataObject"></param>
|
||||||
/// <returns>IEnumerable of Image</returns>
|
/// <returns>IEnumerable of Bitmap</returns>
|
||||||
public static IEnumerable<Image> GetImages(IDataObject dataObject)
|
public static IEnumerable<Bitmap> GetImages(IDataObject dataObject)
|
||||||
{
|
{
|
||||||
// Get single image, this takes the "best" match
|
// Get single image, this takes the "best" match
|
||||||
Image singleImage = GetImage(dataObject);
|
Bitmap singleImage = GetImage(dataObject);
|
||||||
if (singleImage != null)
|
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 return singleImage;
|
||||||
|
yield break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
|
||||||
|
var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList();
|
||||||
|
|
||||||
|
foreach (var (stream, filename) in IterateClipboardContent(dataObject))
|
||||||
{
|
{
|
||||||
foreach (var fileData in IterateClipboardContent(dataObject))
|
var extension = Path.GetExtension(filename)?.ToLowerInvariant();
|
||||||
|
if (!supportedExtensions.Contains(extension))
|
||||||
{
|
{
|
||||||
Image image;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap bitmap = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
image = ImageHelper.FromStream(fileData);
|
if (!fileFormatHandlers.TryLoadFromStream(stream, extension, out bitmap))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -529,31 +548,114 @@ EndSelection:<<<<<<<4
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
fileData?.Dispose();
|
stream?.Dispose();
|
||||||
}
|
}
|
||||||
// If we get here, there is an image
|
// If we get here, there is an image
|
||||||
yield return image;
|
yield return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if files are supplied
|
// check if files are supplied
|
||||||
foreach (string imageFile in GetImageFilenames(dataObject))
|
foreach (string imageFile in GetImageFilenames(dataObject))
|
||||||
{
|
{
|
||||||
Image returnImage = null;
|
var extension = Path.GetExtension(imageFile)?.ToLowerInvariant();
|
||||||
try
|
if (!supportedExtensions.Contains(extension))
|
||||||
{
|
{
|
||||||
returnImage = ImageHelper.LoadImage(imageFile);
|
continue;
|
||||||
}
|
|
||||||
catch (Exception streamImageEx)
|
|
||||||
{
|
|
||||||
Log.Error("Problem retrieving Image from clipboard.", streamImageEx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnImage != null)
|
Bitmap bitmap = null;
|
||||||
|
using FileStream fileStream = new FileStream(imageFile, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||||
|
try
|
||||||
{
|
{
|
||||||
Log.InfoFormat("Got image from clipboard with size {0} and format {1}", returnImage.Size, returnImage.PixelFormat);
|
if (!fileFormatHandlers.TryLoadFromStream(fileStream, extension, out bitmap))
|
||||||
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 bitmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get all images (multiple if file names are available) from the dataObject
|
||||||
|
/// Returned images must be disposed by the calling code!
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dataObject"></param>
|
||||||
|
/// <returns>IEnumerable of IDrawableContainer</returns>
|
||||||
|
public static IEnumerable<IDrawableContainer> GetDrawables(IDataObject dataObject)
|
||||||
|
{
|
||||||
|
// Get single image, this takes the "best" match
|
||||||
|
IDrawableContainer singleImage = GetDrawable(dataObject);
|
||||||
|
if (singleImage != null)
|
||||||
|
{
|
||||||
|
Log.InfoFormat($"Got {singleImage.GetType()} from clipboard with size {singleImage.Size}");
|
||||||
|
yield return singleImage;
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
|
||||||
|
var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList();
|
||||||
|
|
||||||
|
foreach (var (stream, filename) in IterateClipboardContent(dataObject))
|
||||||
|
{
|
||||||
|
var extension = Path.GetExtension(filename)?.ToLowerInvariant();
|
||||||
|
if (!supportedExtensions.Contains(extension))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<IDrawableContainer> drawableContainers;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
drawableContainers = fileFormatHandlers.LoadDrawablesFromStream(stream, extension);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error("Couldn't read file contents", ex);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
stream?.Dispose();
|
||||||
|
}
|
||||||
|
// If we get here, there is an image
|
||||||
|
foreach (var container in drawableContainers)
|
||||||
|
{
|
||||||
|
yield return container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
IEnumerable<IDrawableContainer> drawableContainers;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
drawableContainers = fileFormatHandlers.LoadDrawablesFromStream(fileStream, extension);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error("Couldn't read file contents", ex);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// If we get here, there is an image
|
||||||
|
foreach (var container in drawableContainers)
|
||||||
|
{
|
||||||
|
yield return container;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,11 +664,11 @@ EndSelection:<<<<<<<4
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dataObject"></param>
|
/// <param name="dataObject"></param>
|
||||||
/// <returns>Image or null</returns>
|
/// <returns>Image or null</returns>
|
||||||
private static Image GetImage(IDataObject dataObject)
|
private static Bitmap GetImage(IDataObject dataObject)
|
||||||
{
|
|
||||||
Image returnImage = null;
|
|
||||||
if (dataObject != null)
|
|
||||||
{
|
{
|
||||||
|
if (dataObject == null) return null;
|
||||||
|
|
||||||
|
Bitmap returnImage = null;
|
||||||
IList<string> formats = GetFormats(dataObject);
|
IList<string> formats = GetFormats(dataObject);
|
||||||
string[] retrieveFormats;
|
string[] retrieveFormats;
|
||||||
|
|
||||||
|
@ -608,21 +710,77 @@ EndSelection:<<<<<<<4
|
||||||
return returnImage;
|
return returnImage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get an IDrawableContainer from the IDataObject, don't check for FileDrop
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dataObject"></param>
|
||||||
|
/// <returns>Image or null</returns>
|
||||||
|
private static IDrawableContainer GetDrawable(IDataObject dataObject)
|
||||||
|
{
|
||||||
|
if (dataObject == null) return null;
|
||||||
|
|
||||||
|
IDrawableContainer returnImage = null;
|
||||||
|
IList<string> 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[]
|
||||||
|
{
|
||||||
|
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 = GetDrawableForFormat(currentFormat, dataObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.DebugFormat("Couldn't find format {0}.", currentFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnImage != null)
|
||||||
|
{
|
||||||
|
return returnImage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper method to try to get an image in the specified format from the dataObject
|
/// Helper method to try to get an Bitmap in the specified format from the dataObject
|
||||||
/// the DIB reader should solve some issues
|
/// the DIB reader should solve some issues
|
||||||
/// It also supports Format17/DibV5, by using the following information: https://stackoverflow.com/a/14335591
|
/// It also supports Format17/DibV5, by using the following information: https://stackoverflow.com/a/14335591
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="format">string with the format</param>
|
/// <param name="format">string with the format</param>
|
||||||
/// <param name="dataObject">IDataObject</param>
|
/// <param name="dataObject">IDataObject</param>
|
||||||
/// <returns>Image or null</returns>
|
/// <returns>Bitmap or null</returns>
|
||||||
private static Image GetImageForFormat(string format, IDataObject dataObject)
|
private static Bitmap GetImageForFormat(string format, IDataObject dataObject)
|
||||||
{
|
{
|
||||||
|
Bitmap bitmap = null;
|
||||||
|
|
||||||
if (format == FORMAT_HTML)
|
if (format == FORMAT_HTML)
|
||||||
{
|
{
|
||||||
var textObject = ContentAsString(dataObject, FORMAT_HTML, Encoding.UTF8);
|
var textObject = ContentAsString(dataObject, FORMAT_HTML, Encoding.UTF8);
|
||||||
|
@ -638,10 +796,10 @@ EndSelection:<<<<<<<4
|
||||||
var srcAttribute = imgNode.Attributes["src"];
|
var srcAttribute = imgNode.Attributes["src"];
|
||||||
var imageUrl = srcAttribute.Value;
|
var imageUrl = srcAttribute.Value;
|
||||||
Log.Debug(imageUrl);
|
Log.Debug(imageUrl);
|
||||||
var image = NetworkHelper.DownloadImage(imageUrl);
|
bitmap = NetworkHelper.DownloadImage(imageUrl);
|
||||||
if (image != null)
|
if (bitmap != null)
|
||||||
{
|
{
|
||||||
return image;
|
return bitmap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -652,113 +810,82 @@ EndSelection:<<<<<<<4
|
||||||
var imageStream = clipboardObject as MemoryStream;
|
var imageStream = clipboardObject as MemoryStream;
|
||||||
if (!IsValidStream(imageStream))
|
if (!IsValidStream(imageStream))
|
||||||
{
|
{
|
||||||
// TODO: add "HTML Format" support here...
|
return clipboardObject as Bitmap;
|
||||||
return clipboardObject as Image;
|
}
|
||||||
|
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
|
||||||
|
|
||||||
|
// From here, imageStream is a valid stream
|
||||||
|
if (!fileFormatHandlers.TryLoadFromStream(imageStream, format, out bitmap))
|
||||||
|
{
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CoreConfig.EnableSpecialDIBClipboardReader)
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">string with the format</param>
|
||||||
|
/// <param name="dataObject">IDataObject</param>
|
||||||
|
/// <returns>IDrawableContainer or null</returns>
|
||||||
|
private static IDrawableContainer GetDrawableForFormat(string format, IDataObject dataObject)
|
||||||
{
|
{
|
||||||
if (format == FORMAT_17 || format == DataFormats.Dib)
|
IDrawableContainer drawableContainer = null;
|
||||||
{
|
|
||||||
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<BITMAPINFOHEADERV5>(dibBuffer);
|
|
||||||
if (!infoHeader.IsDibV5)
|
|
||||||
{
|
|
||||||
Log.InfoFormat("Using special DIB <v5 format reader with biCompression {0}", infoHeader.biCompression);
|
|
||||||
int fileHeaderSize = Marshal.SizeOf(typeof(BITMAPFILEHEADER));
|
|
||||||
uint infoHeaderSize = infoHeader.biSize;
|
|
||||||
int fileSize = (int) (fileHeaderSize + infoHeader.biSize + infoHeader.biSizeImage);
|
|
||||||
|
|
||||||
var fileHeader = new BITMAPFILEHEADER
|
if (format == FORMAT_HTML)
|
||||||
{
|
{
|
||||||
bfType = BITMAPFILEHEADER.BM,
|
var textObject = ContentAsString(dataObject, FORMAT_HTML, Encoding.UTF8);
|
||||||
bfSize = fileSize,
|
if (textObject != null)
|
||||||
bfReserved1 = 0,
|
{
|
||||||
bfReserved2 = 0,
|
var doc = new HtmlDocument();
|
||||||
bfOffBits = (int) (fileHeaderSize + infoHeaderSize + infoHeader.biClrUsed * 4)
|
doc.LoadHtml(textObject);
|
||||||
};
|
var imgNodes = doc.DocumentNode.SelectNodes("//img");
|
||||||
|
if (imgNodes != null)
|
||||||
|
{
|
||||||
|
foreach (var imgNode in imgNodes)
|
||||||
|
{
|
||||||
|
var srcAttribute = imgNode.Attributes["src"];
|
||||||
|
var imageUrl = srcAttribute.Value;
|
||||||
|
Log.Debug(imageUrl);
|
||||||
|
drawableContainer = NetworkHelper.DownloadImageAsDrawableContainer(imageUrl);
|
||||||
|
if (drawableContainer != null)
|
||||||
|
{
|
||||||
|
return drawableContainer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
byte[] fileHeaderBytes = BinaryStructHelper.ToByteArray(fileHeader);
|
object clipboardObject = GetFromDataObject(dataObject, format);
|
||||||
|
var imageStream = clipboardObject as MemoryStream;
|
||||||
using var bitmapStream = new MemoryStream();
|
if (!IsValidStream(imageStream))
|
||||||
bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize);
|
{
|
||||||
bitmapStream.Write(dibBuffer, 0, dibBuffer.Length);
|
// TODO: add text based, like "HTML Format" support here...
|
||||||
bitmapStream.Seek(0, SeekOrigin.Begin);
|
// TODO: solve the issue that we do not have a factory for the ImageContainer
|
||||||
var image = ImageHelper.FromStream(bitmapStream);
|
/*var image = clipboardObject as Image;
|
||||||
if (image != null)
|
if (image != null)
|
||||||
{
|
{
|
||||||
return image;
|
return new ImageContainer(this)
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
Log.Info("Using special DIBV5 / Format17 format reader");
|
Image = image,
|
||||||
// CF_DIBV5
|
Left = x,
|
||||||
IntPtr gcHandle = IntPtr.Zero;
|
Top = y
|
||||||
try
|
};
|
||||||
{
|
|
||||||
GCHandle handle = GCHandle.Alloc(dibBuffer, GCHandleType.Pinned);
|
|
||||||
gcHandle = GCHandle.ToIntPtr(handle);
|
|
||||||
return
|
|
||||||
new Bitmap(infoHeader.biWidth, infoHeader.biHeight,
|
|
||||||
-(int) (infoHeader.biSizeImage / infoHeader.biHeight),
|
|
||||||
infoHeader.biBitCount == 32 ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb,
|
|
||||||
new IntPtr(handle.AddrOfPinnedObject().ToInt32() + infoHeader.OffsetToPixels +
|
|
||||||
(infoHeader.biHeight - 1) * (int) (infoHeader.biSizeImage / infoHeader.biHeight))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
return clipboardObject as Image;
|
||||||
{
|
*/
|
||||||
Log.Error("Problem retrieving Format17 from clipboard.", ex);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (gcHandle == IntPtr.Zero)
|
|
||||||
{
|
|
||||||
GCHandle.FromIntPtr(gcHandle).Free();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception dibEx)
|
|
||||||
{
|
|
||||||
Log.Error("Problem retrieving DIB from clipboard.", dibEx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log.Info("Skipping special DIB format reader as it's disabled in the configuration.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (imageStream != null)
|
|
||||||
{
|
|
||||||
imageStream.Seek(0, SeekOrigin.Begin);
|
|
||||||
var tmpImage = ImageHelper.FromStream(imageStream);
|
|
||||||
if (tmpImage != null)
|
|
||||||
{
|
|
||||||
Log.InfoFormat("Got image with clipboard format {0} from the clipboard.", format);
|
|
||||||
return tmpImage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception streamImageEx)
|
|
||||||
{
|
|
||||||
Log.Error($"Problem retrieving {format} from clipboard.", streamImageEx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From here, imageStream is a valid stream
|
||||||
|
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
|
||||||
|
|
||||||
|
return fileFormatHandlers.LoadDrawablesFromStream(imageStream, format).FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get Text from the DataObject
|
/// Get Text from the DataObject
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -840,7 +967,7 @@ EndSelection:<<<<<<<4
|
||||||
{
|
{
|
||||||
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false);
|
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
|
// 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
|
try
|
||||||
{
|
{
|
||||||
// Create PNG stream
|
// Create PNG stream
|
||||||
|
@ -849,7 +976,7 @@ EndSelection:<<<<<<<4
|
||||||
pngStream = new MemoryStream();
|
pngStream = new MemoryStream();
|
||||||
// PNG works for e.g. Powerpoint
|
// PNG works for e.g. Powerpoint
|
||||||
SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false);
|
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);
|
pngStream.Seek(0, SeekOrigin.Begin);
|
||||||
// Set the PNG stream
|
// Set the PNG stream
|
||||||
dataObject.SetData(FORMAT_PNG, false, pngStream);
|
dataObject.SetData(FORMAT_PNG, false, pngStream);
|
||||||
|
@ -866,13 +993,20 @@ EndSelection:<<<<<<<4
|
||||||
{
|
{
|
||||||
// Create the stream for the clipboard
|
// Create the stream for the clipboard
|
||||||
dibStream = new MemoryStream();
|
dibStream = new MemoryStream();
|
||||||
var dibBytes = ((Bitmap)imageToSave).ConvertToDib();
|
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
|
||||||
dibStream.Write(dibBytes,0, dibBytes.Length);
|
|
||||||
|
|
||||||
|
if (!fileFormatHandlers.TrySaveToStream((Bitmap)imageToSave, dibStream, DataFormats.Dib))
|
||||||
|
{
|
||||||
|
dibStream.Dispose();
|
||||||
|
dibStream = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Set the DIB to the clipboard DataObject
|
// Set the DIB to the clipboard DataObject
|
||||||
dataObject.SetData(DataFormats.Dib, false, dibStream);
|
dataObject.SetData(DataFormats.Dib, false, dibStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception dibEx)
|
catch (Exception dibEx)
|
||||||
{
|
{
|
||||||
Log.Error("Error creating DIB for the Clipboard.", dibEx);
|
Log.Error("Error creating DIB for the Clipboard.", dibEx);
|
||||||
|
@ -924,7 +1058,7 @@ EndSelection:<<<<<<<4
|
||||||
// Set the HTML
|
// Set the HTML
|
||||||
if (CoreConfig.ClipboardFormats.Contains(ClipboardFormat.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);
|
string html = GetHtmlString(surface, tmpFile);
|
||||||
dataObject.SetText(html, TextDataFormat.Html);
|
dataObject.SetText(html, TextDataFormat.Html);
|
||||||
}
|
}
|
||||||
|
@ -942,11 +1076,11 @@ EndSelection:<<<<<<<4
|
||||||
// Check if we can use the previously used image
|
// Check if we can use the previously used image
|
||||||
if (imageToSave.PixelFormat != PixelFormat.Format8bppIndexed)
|
if (imageToSave.PixelFormat != PixelFormat.Format8bppIndexed)
|
||||||
{
|
{
|
||||||
ImageOutput.SaveToStream(imageToSave, surface, tmpPngStream, pngOutputSettings);
|
ImageIO.SaveToStream(imageToSave, surface, tmpPngStream, pngOutputSettings);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ImageOutput.SaveToStream(surface, tmpPngStream, pngOutputSettings);
|
ImageIO.SaveToStream(surface, tmpPngStream, pngOutputSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
html = GetHtmlDataUrlString(surface, tmpPngStream);
|
html = GetHtmlDataUrlString(surface, tmpPngStream);
|
||||||
|
@ -1125,15 +1259,15 @@ EndSelection:<<<<<<<4
|
||||||
public static IEnumerable<string> GetImageFilenames(IDataObject dataObject)
|
public static IEnumerable<string> GetImageFilenames(IDataObject dataObject)
|
||||||
{
|
{
|
||||||
string[] dropFileNames = (string[])dataObject.GetData(DataFormats.FileDrop);
|
string[] dropFileNames = (string[])dataObject.GetData(DataFormats.FileDrop);
|
||||||
if (dropFileNames != null && dropFileNames.Length > 0)
|
if (dropFileNames is not { Length: > 0 }) return Enumerable.Empty<string>();
|
||||||
{
|
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
|
||||||
|
|
||||||
|
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)
|
||||||
.Where(filename => ImageHelper.StreamConverters.Keys.Contains(Path.GetExtension(filename).ToLowerInvariant().Substring(1)));
|
.Where(filename => supportedExtensions.Contains(Path.GetExtension(filename)));
|
||||||
}
|
|
||||||
|
|
||||||
return Enumerable.Empty<string>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
36
src/Greenshot.Base/Core/Enums/ExifOrientations.cs
Normal file
36
src/Greenshot.Base/Core/Enums/ExifOrientations.cs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Greenshot.Base.Core.Enums
|
||||||
|
{
|
||||||
|
internal enum ExifOrientations : byte
|
||||||
|
{
|
||||||
|
Unknown = 0,
|
||||||
|
TopLeft = 1,
|
||||||
|
TopRight = 2,
|
||||||
|
BottomRight = 3,
|
||||||
|
BottomLeft = 4,
|
||||||
|
LeftTop = 5,
|
||||||
|
RightTop = 6,
|
||||||
|
RightBottom = 7,
|
||||||
|
LeftBottom = 8,
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,7 @@ namespace Greenshot.Base.Core.Enums
|
||||||
jpg,
|
jpg,
|
||||||
png,
|
png,
|
||||||
tiff,
|
tiff,
|
||||||
|
jxr,
|
||||||
greenshot,
|
greenshot,
|
||||||
ico
|
ico
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
|
using Greenshot.Base.Interfaces.Plugin;
|
||||||
|
|
||||||
|
namespace Greenshot.Base.Core.FileFormatHandlers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This is the registry where all IFileFormatHandler are registered and can be used
|
||||||
|
/// </summary>
|
||||||
|
public static class FileFormatHandlerExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Make sure we handle the input extension always the same, by "normalizing" it
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="extension">string</param>
|
||||||
|
/// <returns>string</returns>
|
||||||
|
public static string NormalizeExtension(string extension)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(extension))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
extension = extension.ToLowerInvariant();
|
||||||
|
return !extension.StartsWith(".") ? $".{extension}" : extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the extensions that the provided IFileFormatHandlers can accept for the specified action
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileFormatHandlers">IEnumerable{IFileFormatHandler}</param>
|
||||||
|
/// <param name="fileFormatHandlerAction"></param>
|
||||||
|
/// <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().OrderBy(e => e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extension method to check if a certain IFileFormatHandler supports a certain action with a specific extension
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileFormatHandler">IFileFormatHandler</param>
|
||||||
|
/// <param name="fileFormatHandlerAction">FileFormatHandlerActions</param>
|
||||||
|
/// <param name="extension">string</param>
|
||||||
|
/// <returns>bool</returns>
|
||||||
|
public static bool Supports(this IFileFormatHandler fileFormatHandler, FileFormatHandlerActions fileFormatHandlerAction, string extension)
|
||||||
|
{
|
||||||
|
extension = NormalizeExtension(extension);
|
||||||
|
return fileFormatHandler.SupportedExtensions.ContainsKey(fileFormatHandlerAction) && fileFormatHandler.SupportedExtensions[fileFormatHandlerAction].Contains(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This wrapper method for TrySaveToStream will do:
|
||||||
|
/// Find all the IFileFormatHandler which support the action for the supplied extension.
|
||||||
|
/// Take the first, to call the TrySaveToStream on.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileFormatHandlers">IEnumerable{IFileFormatHandler}</param>
|
||||||
|
/// <param name="bitmap">Bitmap</param>
|
||||||
|
/// <param name="destination">Stream</param>
|
||||||
|
/// <param name="extension">string</param>
|
||||||
|
/// <param name="surface">ISurface</param>
|
||||||
|
/// <returns>bool</returns>
|
||||||
|
public static bool TrySaveToStream(this IEnumerable<IFileFormatHandler> fileFormatHandlers, Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null)
|
||||||
|
{
|
||||||
|
extension = NormalizeExtension(extension);
|
||||||
|
|
||||||
|
var saveFileFormatHandlers = fileFormatHandlers
|
||||||
|
.Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension))
|
||||||
|
.OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension)).ToList();
|
||||||
|
|
||||||
|
if (!saveFileFormatHandlers.Any())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var fileFormatHandler in saveFileFormatHandlers)
|
||||||
|
{
|
||||||
|
if (fileFormatHandler.TrySaveToStream(bitmap, destination, extension, surface))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to load a drawable container from the stream
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileFormatHandlers">IEnumerable{IFileFormatHandler}</param>
|
||||||
|
/// <param name="stream">Stream</param>
|
||||||
|
/// <param name="extension">string</param>
|
||||||
|
/// <param name="parentSurface">ISurface</param>
|
||||||
|
/// <returns>IEnumerable{IDrawableContainer}</returns>
|
||||||
|
public static IEnumerable<IDrawableContainer> LoadDrawablesFromStream(this IEnumerable<IFileFormatHandler> fileFormatHandlers, Stream stream, string extension, ISurface parentSurface = null)
|
||||||
|
{
|
||||||
|
extension = NormalizeExtension(extension);
|
||||||
|
|
||||||
|
var loadfileFormatHandler = fileFormatHandlers
|
||||||
|
.Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadDrawableFromStream, extension))
|
||||||
|
.OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadDrawableFromStream, extension))
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (loadfileFormatHandler != null)
|
||||||
|
{
|
||||||
|
return loadfileFormatHandler.LoadDrawablesFromStream(stream, extension, parentSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Enumerable.Empty<IDrawableContainer>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to load a Bitmap from the stream
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileFormatHandlers">IEnumerable{IFileFormatHandler}</param>
|
||||||
|
/// <param name="stream">Stream</param>
|
||||||
|
/// <param name="extension">string</param>
|
||||||
|
/// <param name="bitmap">Bitmap out</param>
|
||||||
|
/// <returns>bool true if it was successful</returns>
|
||||||
|
public static bool TryLoadFromStream(this IEnumerable<IFileFormatHandler> fileFormatHandlers, Stream stream, string extension, out Bitmap bitmap)
|
||||||
|
{
|
||||||
|
extension = NormalizeExtension(extension);
|
||||||
|
|
||||||
|
var loadFileFormatHandler = fileFormatHandlers
|
||||||
|
.Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension))
|
||||||
|
.OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension))
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (loadFileFormatHandler == null)
|
||||||
|
{
|
||||||
|
bitmap = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadFileFormatHandler.TryLoadFromStream(stream, extension, out bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,7 +61,7 @@ namespace Greenshot.Base.Core
|
||||||
float HorizontalResolution { get; }
|
float HorizontalResolution { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unterlying image, or an on demand rendered version with different attributes as the original
|
/// Underlying image, or an on demand rendered version with different attributes as the original
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Image Image { get; }
|
Image Image { get; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,28 +24,24 @@ using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.Windows;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using Greenshot.Base.Core.Enums;
|
||||||
using Greenshot.Base.Effects;
|
using Greenshot.Base.Effects;
|
||||||
using Greenshot.Base.IniFile;
|
using Greenshot.Base.IniFile;
|
||||||
using Greenshot.Base.Interfaces;
|
|
||||||
using Greenshot.Base.UnmanagedHelpers;
|
using Greenshot.Base.UnmanagedHelpers;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
using Brush = System.Drawing.Brush;
|
||||||
|
using Color = System.Drawing.Color;
|
||||||
|
using Matrix = System.Drawing.Drawing2D.Matrix;
|
||||||
|
using Pen = System.Drawing.Pen;
|
||||||
|
using PixelFormat = System.Drawing.Imaging.PixelFormat;
|
||||||
|
using Point = System.Drawing.Point;
|
||||||
|
using Size = System.Drawing.Size;
|
||||||
|
|
||||||
namespace Greenshot.Base.Core
|
namespace Greenshot.Base.Core
|
||||||
{
|
{
|
||||||
internal enum ExifOrientations : byte
|
|
||||||
{
|
|
||||||
Unknown = 0,
|
|
||||||
TopLeft = 1,
|
|
||||||
TopRight = 2,
|
|
||||||
BottomRight = 3,
|
|
||||||
BottomLeft = 4,
|
|
||||||
LeftTop = 5,
|
|
||||||
RightTop = 6,
|
|
||||||
RightBottom = 7,
|
|
||||||
LeftBottom = 8,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of ImageHelper.
|
/// Description of ImageHelper.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -55,83 +51,6 @@ namespace Greenshot.Base.Core
|
||||||
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
|
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
|
||||||
private const int ExifOrientationId = 0x0112;
|
private const int ExifOrientationId = 0x0112;
|
||||||
|
|
||||||
static ImageHelper()
|
|
||||||
{
|
|
||||||
StreamConverters["greenshot"] = (stream, s) =>
|
|
||||||
{
|
|
||||||
var surface = SimpleServiceProvider.Current.GetInstance<Func<ISurface>>().Invoke();
|
|
||||||
return surface.GetImageForExport();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add a SVG converter
|
|
||||||
StreamConverters["svg"] = (stream, s) =>
|
|
||||||
{
|
|
||||||
stream.Position = 0;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return SvgImage.FromStream(stream).Image;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error("Can't load SVG", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
static Image DefaultConverter(Stream stream, string s)
|
|
||||||
{
|
|
||||||
stream.Position = 0;
|
|
||||||
using var tmpImage = Image.FromStream(stream, true, true);
|
|
||||||
Log.DebugFormat("Loaded bitmap with Size {0}x{1} and PixelFormat {2}", tmpImage.Width, tmpImage.Height, tmpImage.PixelFormat);
|
|
||||||
return Clone(tmpImage, PixelFormat.Format32bppArgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback
|
|
||||||
StreamConverters[string.Empty] = DefaultConverter;
|
|
||||||
StreamConverters["gif"] = DefaultConverter;
|
|
||||||
StreamConverters["bmp"] = DefaultConverter;
|
|
||||||
StreamConverters["jpg"] = DefaultConverter;
|
|
||||||
StreamConverters["jpeg"] = DefaultConverter;
|
|
||||||
StreamConverters["png"] = DefaultConverter;
|
|
||||||
StreamConverters["wmf"] = DefaultConverter;
|
|
||||||
|
|
||||||
StreamConverters["ico"] = (stream, extension) =>
|
|
||||||
{
|
|
||||||
// Icon logic, try to get the Vista icon, else the biggest possible
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using Image tmpImage = ExtractVistaIcon(stream);
|
|
||||||
if (tmpImage != null)
|
|
||||||
{
|
|
||||||
return Clone(tmpImage, PixelFormat.Format32bppArgb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception vistaIconException)
|
|
||||||
{
|
|
||||||
Log.Warn("Can't read icon", vistaIconException);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// No vista icon, try normal icon
|
|
||||||
stream.Position = 0;
|
|
||||||
// We create a copy of the bitmap, so everything else can be disposed
|
|
||||||
using Icon tmpIcon = new Icon(stream, new Size(1024, 1024));
|
|
||||||
using Image tmpImage = tmpIcon.ToBitmap();
|
|
||||||
return Clone(tmpImage, PixelFormat.Format32bppArgb);
|
|
||||||
}
|
|
||||||
catch (Exception iconException)
|
|
||||||
{
|
|
||||||
Log.Warn("Can't read icon", iconException);
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.Position = 0;
|
|
||||||
return DefaultConverter(stream, extension);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IDictionary<string, Func<Stream, string, Image>> StreamConverters { get; } = new Dictionary<string, Func<Stream, string, Image>>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Make sure the image is orientated correctly
|
/// Make sure the image is orientated correctly
|
||||||
|
@ -371,127 +290,6 @@ namespace Greenshot.Base.Core
|
||||||
return cropRectangle;
|
return cropRectangle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Load an image from file
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="filename"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Based on: https://www.codeproject.com/KB/cs/IconExtractor.aspx
|
|
||||||
/// And a hint from: https://www.codeproject.com/KB/cs/IconLib.aspx
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="iconStream">Stream with the icon information</param>
|
|
||||||
/// <returns>Bitmap with the Vista Icon (256x256)</returns>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms648069%28v=vs.85%29.aspx
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="location">The file (EXE or DLL) to get the icon from</param>
|
|
||||||
/// <param name="index">Index of the icon</param>
|
|
||||||
/// <param name="takeLarge">true if the large icon is wanted</param>
|
|
||||||
/// <returns>Icon</returns>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Apply the effect to the bitmap
|
/// Apply the effect to the bitmap
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -563,8 +361,7 @@ namespace Greenshot.Base.Core
|
||||||
/// <returns>Changed bitmap</returns>
|
/// <returns>Changed bitmap</returns>
|
||||||
public static Image CreateTornEdge(Image sourceImage, int toothHeight, int horizontalToothRange, int verticalToothRange, bool[] edges)
|
public static Image CreateTornEdge(Image sourceImage, int toothHeight, int horizontalToothRange, int verticalToothRange, bool[] edges)
|
||||||
{
|
{
|
||||||
Image returnImage = CreateEmpty(sourceImage.Width, sourceImage.Height, PixelFormat.Format32bppArgb, Color.Empty, sourceImage.HorizontalResolution,
|
Image returnImage = CreateEmpty(sourceImage.Width, sourceImage.Height, PixelFormat.Format32bppArgb, Color.Empty, sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
|
||||||
sourceImage.VerticalResolution);
|
|
||||||
using (var path = new GraphicsPath())
|
using (var path = new GraphicsPath())
|
||||||
{
|
{
|
||||||
Random random = new Random();
|
Random random = new Random();
|
||||||
|
@ -1396,7 +1193,7 @@ namespace Greenshot.Base.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no pixelformat is supplied
|
// If no pixelformat is supplied
|
||||||
if (PixelFormat.DontCare == targetFormat || PixelFormat.Undefined == targetFormat)
|
if (targetFormat is PixelFormat.DontCare or PixelFormat.Undefined)
|
||||||
{
|
{
|
||||||
if (SupportsPixelFormat(sourceImage.PixelFormat))
|
if (SupportsPixelFormat(sourceImage.PixelFormat))
|
||||||
{
|
{
|
||||||
|
@ -1517,10 +1314,10 @@ namespace Greenshot.Base.Core
|
||||||
/// <param name="height"></param>
|
/// <param name="height"></param>
|
||||||
/// <param name="format"></param>
|
/// <param name="format"></param>
|
||||||
/// <param name="backgroundColor">The color to fill with, or Color.Empty to take the default depending on the pixel format</param>
|
/// <param name="backgroundColor">The color to fill with, or Color.Empty to take the default depending on the pixel format</param>
|
||||||
/// <param name="horizontalResolution"></param>
|
/// <param name="horizontalResolution">float</param>
|
||||||
/// <param name="verticalResolution"></param>
|
/// <param name="verticalResolution">float</param>
|
||||||
/// <returns>Bitmap</returns>
|
/// <returns>Bitmap</returns>
|
||||||
public static Bitmap CreateEmpty(int width, int height, PixelFormat format, Color backgroundColor, float horizontalResolution, float verticalResolution)
|
public static Bitmap CreateEmpty(int width, int height, PixelFormat format, Color backgroundColor, float horizontalResolution = 96f, float verticalResolution = 96f)
|
||||||
{
|
{
|
||||||
// Create a new "clean" image
|
// Create a new "clean" image
|
||||||
Bitmap newImage = new Bitmap(width, height, format);
|
Bitmap newImage = new Bitmap(width, height, format);
|
||||||
|
@ -1711,98 +1508,106 @@ namespace Greenshot.Base.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load a Greenshot surface from a stream
|
/// Rotate the image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="surfaceFileStream">Stream</param>
|
/// <param name="image">Input image</param>
|
||||||
/// <param name="returnSurface"></param>
|
/// <param name="rotationAngle">Angle in degrees</param>
|
||||||
/// <returns>ISurface</returns>
|
/// <returns>Rotated image</returns>
|
||||||
public static ISurface LoadGreenshotSurface(Stream surfaceFileStream, ISurface returnSurface)
|
public static Image Rotate(this Image image, float rotationAngle)
|
||||||
{
|
{
|
||||||
Image fileImage;
|
var bitmap = CreateEmptyLike(image, Color.Transparent);
|
||||||
// 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
|
using var graphics = Graphics.FromImage(bitmap);
|
||||||
surfaceFileStream.Position = 0;
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
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)
|
graphics.TranslateTransform((float)bitmap.Width / 2, (float)bitmap.Height / 2);
|
||||||
const int markerSize = 14;
|
graphics.RotateTransform(rotationAngle);
|
||||||
surfaceFileStream.Seek(-markerSize, SeekOrigin.End);
|
graphics.TranslateTransform(-(float)bitmap.Width / 2, -(float)bitmap.Height / 2);
|
||||||
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);
|
graphics.DrawImage(image, new Point(0, 0));
|
||||||
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)
|
return bitmap;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create an image from a stream, if an extension is supplied more formats are supported.
|
/// Map a System.Drawing.Imaging.PixelFormat to a System.Windows.Media.PixelFormat
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">Stream</param>
|
/// <param name="pixelFormat">System.Drawing.Imaging.PixelFormat</param>
|
||||||
/// <param name="extension"></param>
|
/// <returns>System.Windows.Media.PixelFormat</returns>
|
||||||
/// <returns>Image</returns>
|
/// <exception cref="NotSupportedException"></exception>
|
||||||
public static Image FromStream(Stream stream, string extension = null)
|
public static System.Windows.Media.PixelFormat Map(this PixelFormat pixelFormat) =>
|
||||||
|
pixelFormat switch
|
||||||
{
|
{
|
||||||
if (stream == null)
|
PixelFormat.Format32bppArgb => PixelFormats.Bgra32,
|
||||||
|
PixelFormat.Format24bppRgb => PixelFormats.Bgr24,
|
||||||
|
PixelFormat.Format32bppRgb => PixelFormats.Bgr32,
|
||||||
|
_ => throw new NotSupportedException($"Can't map {pixelFormat}.")
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Map a System.Windows.Media.PixelFormat to a System.Drawing.Imaging.PixelFormat
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pixelFormat">System.Windows.Media.PixelFormat</param>
|
||||||
|
/// <returns>System.Drawing.Imaging.PixelFormat</returns>
|
||||||
|
/// <exception cref="NotSupportedException"></exception>
|
||||||
|
public static PixelFormat Map(this System.Windows.Media.PixelFormat pixelFormat)
|
||||||
{
|
{
|
||||||
return null;
|
if (pixelFormat == PixelFormats.Bgra32)
|
||||||
|
{
|
||||||
|
return PixelFormat.Format32bppArgb;
|
||||||
|
}
|
||||||
|
if (pixelFormat == PixelFormats.Bgr24)
|
||||||
|
{
|
||||||
|
return PixelFormat.Format24bppRgb;
|
||||||
|
}
|
||||||
|
if (pixelFormat == PixelFormats.Bgr32)
|
||||||
|
{
|
||||||
|
return PixelFormat.Format32bppRgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(extension))
|
throw new NotSupportedException($"Can't map {pixelFormat}.");
|
||||||
{
|
|
||||||
extension = extension.Replace(".", string.Empty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we can try multiple times
|
/// <summary>
|
||||||
if (!stream.CanSeek)
|
/// Convert a Bitmap to a BitmapSource
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bitmap">Bitmap</param>
|
||||||
|
/// <returns>BitmapSource</returns>
|
||||||
|
public static BitmapSource ToBitmapSource(this Bitmap bitmap)
|
||||||
{
|
{
|
||||||
var memoryStream = new MemoryStream();
|
var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
||||||
stream.CopyTo(memoryStream);
|
|
||||||
stream = memoryStream;
|
BitmapSource bitmapSource;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bitmapSource = BitmapSource.Create(
|
||||||
|
bitmapData.Width, bitmapData.Height,
|
||||||
|
bitmap.HorizontalResolution, bitmap.VerticalResolution,
|
||||||
|
bitmap.PixelFormat.Map(), null,
|
||||||
|
bitmapData.Scan0, bitmapData.Stride * bitmapData.Height, bitmapData.Stride);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
bitmap.UnlockBits(bitmapData);
|
||||||
}
|
}
|
||||||
|
|
||||||
Image returnImage = null;
|
return bitmapSource;
|
||||||
if (StreamConverters.TryGetValue(extension ?? string.Empty, out var converter))
|
|
||||||
{
|
|
||||||
returnImage = converter(stream, extension);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback
|
/// <summary>
|
||||||
if (returnImage == null)
|
/// Convert a BitmapSource to a Bitmap
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bitmapSource">BitmapSource</param>
|
||||||
|
/// <returns>Bitmap</returns>
|
||||||
|
public static Bitmap ToBitmap(this BitmapSource bitmapSource)
|
||||||
{
|
{
|
||||||
// We create a copy of the bitmap, so everything else can be disposed
|
var pixelFormat = bitmapSource.Format.Map();
|
||||||
stream.Position = 0;
|
|
||||||
using var tmpImage = Image.FromStream(stream, true, true);
|
|
||||||
Log.DebugFormat("Loaded bitmap with Size {0}x{1} and PixelFormat {2}", tmpImage.Width, tmpImage.Height, tmpImage.PixelFormat);
|
|
||||||
returnImage = Clone(tmpImage, PixelFormat.Format32bppArgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnImage;
|
Bitmap bitmap = new Bitmap(bitmapSource.PixelWidth, bitmapSource.PixelHeight, pixelFormat);
|
||||||
|
BitmapData data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), ImageLockMode.WriteOnly, pixelFormat);
|
||||||
|
bitmapSource.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
|
||||||
|
bitmap.UnlockBits(data);
|
||||||
|
return bitmap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,12 +20,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -33,20 +32,21 @@ using System.Text.RegularExpressions;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Greenshot.Base.Controls;
|
using Greenshot.Base.Controls;
|
||||||
using Greenshot.Base.Core.Enums;
|
using Greenshot.Base.Core.Enums;
|
||||||
|
using Greenshot.Base.Core.FileFormatHandlers;
|
||||||
using Greenshot.Base.IniFile;
|
using Greenshot.Base.IniFile;
|
||||||
using Greenshot.Base.Interfaces;
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Plugin;
|
using Greenshot.Base.Interfaces.Plugin;
|
||||||
|
using Greenshot.Base.UnmanagedHelpers;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Encoder = System.Drawing.Imaging.Encoder;
|
|
||||||
|
|
||||||
namespace Greenshot.Base.Core
|
namespace Greenshot.Base.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of ImageOutput.
|
/// Description of ImageOutput.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
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<CoreConfiguration>();
|
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
|
||||||
private static readonly int PROPERTY_TAG_SOFTWARE_USED = 0x0131;
|
private static readonly int PROPERTY_TAG_SOFTWARE_USED = 0x0131;
|
||||||
private static readonly Cache<string, string> TmpFileCache = new Cache<string, string>(10 * 60 * 60, RemoveExpiredTmpFile);
|
private static readonly Cache<string, string> TmpFileCache = new Cache<string, string>(10 * 60 * 60, RemoveExpiredTmpFile);
|
||||||
|
@ -54,7 +54,7 @@ namespace Greenshot.Base.Core
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a PropertyItem (Metadata) to store with the image.
|
/// Creates a PropertyItem (Metadata) to store with the image.
|
||||||
/// For the possible ID's see: https://msdn.microsoft.com/de-de/library/system.drawing.imaging.propertyitem.id(v=vs.80).aspx
|
/// For the possible ID's see: https://msdn.microsoft.com/de-de/library/system.drawing.imaging.propertyitem.id(v=vs.80).aspx
|
||||||
/// This code uses Reflection to create a PropertyItem, although it's not adviced it's not as stupid as having a image in the project so we can read a PropertyItem from that!
|
/// This code uses Reflection to create a PropertyItem, although it's not advised it's not as stupid as having a image in the project so we can read a PropertyItem from that!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">ID</param>
|
/// <param name="id">ID</param>
|
||||||
/// <param name="text">Text</param>
|
/// <param name="text">Text</param>
|
||||||
|
@ -124,102 +124,21 @@ namespace Greenshot.Base.Core
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var imageFormat = outputSettings.Format switch
|
// Check if we want to use a memory stream, to prevent issues with non seekable streams
|
||||||
{
|
|
||||||
OutputFormat.bmp => ImageFormat.Bmp,
|
|
||||||
OutputFormat.gif => ImageFormat.Gif,
|
|
||||||
OutputFormat.jpg => ImageFormat.Jpeg,
|
|
||||||
OutputFormat.tiff => ImageFormat.Tiff,
|
|
||||||
OutputFormat.ico => ImageFormat.Icon,
|
|
||||||
_ => ImageFormat.Png
|
|
||||||
};
|
|
||||||
Log.DebugFormat("Saving image to stream with Format {0} and PixelFormat {1}", imageFormat, imageToSave.PixelFormat);
|
|
||||||
|
|
||||||
// Check if we want to use a memory stream, to prevent issues with non seakable streams
|
|
||||||
// The save is made to the targetStream, this is directed to either the MemoryStream or the original
|
// The save is made to the targetStream, this is directed to either the MemoryStream or the original
|
||||||
Stream targetStream = stream;
|
Stream targetStream = stream;
|
||||||
if (!stream.CanSeek)
|
if (!stream.CanSeek)
|
||||||
{
|
{
|
||||||
useMemoryStream = true;
|
useMemoryStream = true;
|
||||||
Log.Warn("Using memorystream prevent an issue with saving to a non seekable stream.");
|
Log.Warn("Using a memory stream prevent an issue with saving to a non seekable stream.");
|
||||||
memoryStream = new MemoryStream();
|
memoryStream = new MemoryStream();
|
||||||
targetStream = memoryStream;
|
targetStream = memoryStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Equals(imageFormat, ImageFormat.Jpeg))
|
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
|
||||||
|
if (!fileFormatHandlers.TrySaveToStream(imageToSave as Bitmap, targetStream, outputSettings.Format.ToString(), surface, outputSettings))
|
||||||
{
|
{
|
||||||
bool foundEncoder = false;
|
return;
|
||||||
foreach (ImageCodecInfo imageCodec in ImageCodecInfo.GetImageEncoders())
|
|
||||||
{
|
|
||||||
if (imageCodec.FormatID == imageFormat.Guid)
|
|
||||||
{
|
|
||||||
EncoderParameters parameters = new EncoderParameters(1)
|
|
||||||
{
|
|
||||||
Param =
|
|
||||||
{
|
|
||||||
[0] = new EncoderParameter(Encoder.Quality, outputSettings.JPGQuality)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Removing transparency if it's not supported in the output
|
|
||||||
if (Image.IsAlphaPixelFormat(imageToSave.PixelFormat))
|
|
||||||
{
|
|
||||||
Image nonAlphaImage = ImageHelper.Clone(imageToSave, PixelFormat.Format24bppRgb);
|
|
||||||
AddTag(nonAlphaImage);
|
|
||||||
nonAlphaImage.Save(targetStream, imageCodec, parameters);
|
|
||||||
nonAlphaImage.Dispose();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddTag(imageToSave);
|
|
||||||
imageToSave.Save(targetStream, imageCodec, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
foundEncoder = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!foundEncoder)
|
|
||||||
{
|
|
||||||
throw new ApplicationException("No JPG encoder found, this should not happen.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Equals(imageFormat, ImageFormat.Icon))
|
|
||||||
{
|
|
||||||
// FEATURE-916: Added Icon support
|
|
||||||
IList<Image> images = new List<Image>
|
|
||||||
{
|
|
||||||
imageToSave
|
|
||||||
};
|
|
||||||
WriteIcon(stream, images);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool needsDispose = false;
|
|
||||||
// Removing transparency if it's not supported in the output
|
|
||||||
if (!Equals(imageFormat, ImageFormat.Png) && Image.IsAlphaPixelFormat(imageToSave.PixelFormat))
|
|
||||||
{
|
|
||||||
imageToSave = ImageHelper.Clone(imageToSave, PixelFormat.Format24bppRgb);
|
|
||||||
needsDispose = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddTag(imageToSave);
|
|
||||||
// Added for OptiPNG
|
|
||||||
bool processed = false;
|
|
||||||
if (Equals(imageFormat, ImageFormat.Png) && !string.IsNullOrEmpty(CoreConfig.OptimizePNGCommand))
|
|
||||||
{
|
|
||||||
processed = ProcessPngImageExternally(imageToSave, targetStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!processed)
|
|
||||||
{
|
|
||||||
imageToSave.Save(targetStream, imageFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needsDispose)
|
|
||||||
{
|
|
||||||
imageToSave.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we used a memory stream, we need to stream the memory stream to the original stream.
|
// If we used a memory stream, we need to stream the memory stream to the original stream.
|
||||||
|
@ -227,21 +146,6 @@ namespace Greenshot.Base.Core
|
||||||
{
|
{
|
||||||
memoryStream.WriteTo(stream);
|
memoryStream.WriteTo(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output the surface elements, size and marker to the stream
|
|
||||||
if (outputSettings.Format != OutputFormat.greenshot)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
using MemoryStream tmpStream = new MemoryStream();
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -249,89 +153,6 @@ namespace Greenshot.Base.Core
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Write the passed Image to a tmp-file and call an external process, than read the file back and write it to the targetStream
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="imageToProcess">Image to pass to the external process</param>
|
|
||||||
/// <param name="targetStream">stream to write the processed image to</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private static bool ProcessPngImageExternally(Image imageToProcess, Stream targetStream)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(CoreConfig.OptimizePNGCommand))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!File.Exists(CoreConfig.OptimizePNGCommand))
|
|
||||||
{
|
|
||||||
Log.WarnFormat("Can't find 'OptimizePNGCommand' {0}", CoreConfig.OptimizePNGCommand);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string tmpFileName = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + ".png");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (FileStream tmpStream = File.Create(tmpFileName))
|
|
||||||
{
|
|
||||||
Log.DebugFormat("Writing png to tmp file: {0}", tmpFileName);
|
|
||||||
imageToProcess.Save(tmpStream, ImageFormat.Png);
|
|
||||||
if (Log.IsDebugEnabled)
|
|
||||||
{
|
|
||||||
Log.DebugFormat("File size before processing {0}", new FileInfo(tmpFileName).Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Log.IsDebugEnabled)
|
|
||||||
{
|
|
||||||
Log.DebugFormat("Starting : {0}", CoreConfig.OptimizePNGCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessStartInfo processStartInfo = new ProcessStartInfo(CoreConfig.OptimizePNGCommand)
|
|
||||||
{
|
|
||||||
Arguments = string.Format(CoreConfig.OptimizePNGCommandArguments, tmpFileName),
|
|
||||||
CreateNoWindow = true,
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
RedirectStandardError = true,
|
|
||||||
UseShellExecute = false
|
|
||||||
};
|
|
||||||
using Process process = Process.Start(processStartInfo);
|
|
||||||
if (process != null)
|
|
||||||
{
|
|
||||||
process.WaitForExit();
|
|
||||||
if (process.ExitCode == 0)
|
|
||||||
{
|
|
||||||
if (Log.IsDebugEnabled)
|
|
||||||
{
|
|
||||||
Log.DebugFormat("File size after processing {0}", new FileInfo(tmpFileName).Length);
|
|
||||||
Log.DebugFormat("Reading back tmp file: {0}", tmpFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] processedImage = File.ReadAllBytes(tmpFileName);
|
|
||||||
targetStream.Write(processedImage, 0, processedImage.Length);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.ErrorFormat("Error while processing PNG image: {0}", process.ExitCode);
|
|
||||||
Log.ErrorFormat("Output: {0}", process.StandardOutput.ReadToEnd());
|
|
||||||
Log.ErrorFormat("Error: {0}", process.StandardError.ReadToEnd());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.Error("Error while processing PNG image: ", e);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (File.Exists(tmpFileName))
|
|
||||||
{
|
|
||||||
Log.DebugFormat("Cleaning up tmp file: {0}", tmpFileName);
|
|
||||||
File.Delete(tmpFileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create an image from a surface with the settings from the output settings applied
|
/// Create an image from a surface with the settings from the output settings applied
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -429,12 +250,11 @@ namespace Greenshot.Base.Core
|
||||||
/// Add the greenshot property!
|
/// Add the greenshot property!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="imageToSave"></param>
|
/// <param name="imageToSave"></param>
|
||||||
private static void AddTag(Image imageToSave)
|
public static void AddTag(this Image imageToSave)
|
||||||
{
|
{
|
||||||
// Create meta-data
|
// Create meta-data
|
||||||
PropertyItem softwareUsedPropertyItem = CreatePropertyItem(PROPERTY_TAG_SOFTWARE_USED, "Greenshot");
|
PropertyItem softwareUsedPropertyItem = CreatePropertyItem(PROPERTY_TAG_SOFTWARE_USED, "Greenshot");
|
||||||
if (softwareUsedPropertyItem != null)
|
if (softwareUsedPropertyItem == null) return;
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
imageToSave.SetPropertyItem(softwareUsedPropertyItem);
|
imageToSave.SetPropertyItem(softwareUsedPropertyItem);
|
||||||
|
@ -444,7 +264,6 @@ namespace Greenshot.Base.Core
|
||||||
Log.WarnFormat("Couldn't set property {0}", softwareUsedPropertyItem.Id);
|
Log.WarnFormat("Couldn't set property {0}", softwareUsedPropertyItem.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load a Greenshot surface
|
/// Load a Greenshot surface
|
||||||
|
@ -463,7 +282,7 @@ namespace Greenshot.Base.Core
|
||||||
// Fixed lock problem Bug #3431881
|
// Fixed lock problem Bug #3431881
|
||||||
using (Stream surfaceFileStream = File.OpenRead(fullPath))
|
using (Stream surfaceFileStream = File.OpenRead(fullPath))
|
||||||
{
|
{
|
||||||
returnSurface = ImageHelper.LoadGreenshotSurface(surfaceFileStream, returnSurface);
|
returnSurface = LoadGreenshotSurface(surfaceFileStream, returnSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnSurface != null)
|
if (returnSurface != null)
|
||||||
|
@ -547,8 +366,7 @@ namespace Greenshot.Base.Core
|
||||||
using (SaveImageFileDialog saveImageFileDialog = new SaveImageFileDialog(captureDetails))
|
using (SaveImageFileDialog saveImageFileDialog = new SaveImageFileDialog(captureDetails))
|
||||||
{
|
{
|
||||||
DialogResult dialogResult = saveImageFileDialog.ShowDialog();
|
DialogResult dialogResult = saveImageFileDialog.ShowDialog();
|
||||||
if (dialogResult.Equals(DialogResult.OK))
|
if (!dialogResult.Equals(DialogResult.OK)) return returnValue;
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string fileNameWithExtension = saveImageFileDialog.FileNameWithExtension;
|
string fileNameWithExtension = saveImageFileDialog.FileNameWithExtension;
|
||||||
|
@ -569,7 +387,6 @@ namespace Greenshot.Base.Core
|
||||||
MessageBox.Show(Language.GetFormattedString("error_nowriteaccess", saveImageFileDialog.FileName).Replace(@"\\", @"\"), Language.GetString("error"));
|
MessageBox.Show(Language.GetFormattedString("error_nowriteaccess", saveImageFileDialog.FileName).Replace(@"\\", @"\"), Language.GetString("error"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
@ -709,91 +526,218 @@ namespace Greenshot.Base.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Write the images to the stream as icon
|
/// Load an image from file
|
||||||
/// Every image is resized to 256x256 (but the content maintains the aspect ratio)
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">Stream to write to</param>
|
/// <param name="filename"></param>
|
||||||
/// <param name="images">List of images</param>
|
/// <returns></returns>
|
||||||
public static void WriteIcon(Stream stream, IList<Image> images)
|
public static Image LoadImage(string filename)
|
||||||
{
|
{
|
||||||
var binaryWriter = new BinaryWriter(stream);
|
if (string.IsNullOrEmpty(filename))
|
||||||
//
|
{
|
||||||
// ICONDIR structure
|
return null;
|
||||||
//
|
}
|
||||||
binaryWriter.Write((short) 0); // reserved
|
|
||||||
binaryWriter.Write((short) 1); // image type (icon)
|
|
||||||
binaryWriter.Write((short) images.Count); // number of images
|
|
||||||
|
|
||||||
IList<Size> imageSizes = new List<Size>();
|
if (!File.Exists(filename))
|
||||||
IList<MemoryStream> encodedImages = new List<MemoryStream>();
|
|
||||||
foreach (var image in images)
|
|
||||||
{
|
{
|
||||||
// Pick the best fit
|
return null;
|
||||||
var sizes = new[]
|
}
|
||||||
|
|
||||||
|
Image fileImage;
|
||||||
|
Log.InfoFormat("Loading image from file {0}", filename);
|
||||||
|
// Fixed lock problem Bug #3431881
|
||||||
|
using (Stream imageFileStream = File.OpenRead(filename))
|
||||||
{
|
{
|
||||||
16, 32, 48
|
fileImage = FromStream(imageFileStream, Path.GetExtension(filename));
|
||||||
};
|
}
|
||||||
int size = 256;
|
|
||||||
foreach (var possibleSize in sizes)
|
if (fileImage != null)
|
||||||
{
|
{
|
||||||
if (image.Width <= possibleSize && image.Height <= possibleSize)
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Based on: https://www.codeproject.com/KB/cs/IconExtractor.aspx
|
||||||
|
/// And a hint from: https://www.codeproject.com/KB/cs/IconLib.aspx
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="iconStream">Stream with the icon information</param>
|
||||||
|
/// <returns>Bitmap with the Vista Icon (256x256)</returns>
|
||||||
|
private static Bitmap ExtractVistaIcon(Stream iconStream)
|
||||||
{
|
{
|
||||||
size = possibleSize;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
var imageStream = new MemoryStream();
|
catch
|
||||||
if (image.Width == size && image.Height == size)
|
|
||||||
{
|
{
|
||||||
using var clonedImage = ImageHelper.Clone(image, PixelFormat.Format32bppArgb);
|
return null;
|
||||||
clonedImage.Save(imageStream, ImageFormat.Png);
|
|
||||||
imageSizes.Add(new Size(size, size));
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
return bmpPngExtracted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms648069%28v=vs.85%29.aspx
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="location">The file (EXE or DLL) to get the icon from</param>
|
||||||
|
/// <param name="index">Index of the icon</param>
|
||||||
|
/// <param name="takeLarge">true if the large icon is wanted</param>
|
||||||
|
/// <returns>Icon</returns>
|
||||||
|
public static Icon ExtractAssociatedIcon(string location, int index, bool takeLarge)
|
||||||
{
|
{
|
||||||
// Resize to the specified size, first make sure the image is 32bpp
|
Shell32.ExtractIconEx(location, index, out var large, out var small, 1);
|
||||||
using var clonedImage = ImageHelper.Clone(image, PixelFormat.Format32bppArgb);
|
Icon returnIcon = null;
|
||||||
using var resizedImage = ImageHelper.ResizeImage(clonedImage, true, true, Color.Empty, size, size, null);
|
bool isLarge = false;
|
||||||
resizedImage.Save(imageStream, ImageFormat.Png);
|
bool isSmall = false;
|
||||||
imageSizes.Add(resizedImage.Size);
|
try
|
||||||
}
|
|
||||||
|
|
||||||
imageStream.Seek(0, SeekOrigin.Begin);
|
|
||||||
encodedImages.Add(imageStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// ICONDIRENTRY structure
|
|
||||||
//
|
|
||||||
const int iconDirSize = 6;
|
|
||||||
const int iconDirEntrySize = 16;
|
|
||||||
|
|
||||||
var offset = iconDirSize + (images.Count * iconDirEntrySize);
|
|
||||||
for (int i = 0; i < images.Count; i++)
|
|
||||||
{
|
{
|
||||||
var imageSize = imageSizes[i];
|
if (takeLarge && !IntPtr.Zero.Equals(large))
|
||||||
// Write the width / height, 0 means 256
|
{
|
||||||
binaryWriter.Write(imageSize.Width == 256 ? (byte) 0 : (byte) imageSize.Width);
|
returnIcon = Icon.FromHandle(large);
|
||||||
binaryWriter.Write(imageSize.Height == 256 ? (byte) 0 : (byte) imageSize.Height);
|
isLarge = true;
|
||||||
binaryWriter.Write((byte) 0); // no pallete
|
}
|
||||||
binaryWriter.Write((byte) 0); // reserved
|
else if (!IntPtr.Zero.Equals(small))
|
||||||
binaryWriter.Write((short) 0); // no color planes
|
{
|
||||||
binaryWriter.Write((short) 32); // 32 bpp
|
returnIcon = Icon.FromHandle(small);
|
||||||
binaryWriter.Write((int) encodedImages[i].Length); // image data length
|
isSmall = true;
|
||||||
binaryWriter.Write(offset);
|
}
|
||||||
offset += (int) encodedImages[i].Length;
|
else if (!IntPtr.Zero.Equals(large))
|
||||||
|
{
|
||||||
|
returnIcon = Icon.FromHandle(large);
|
||||||
|
isLarge = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (isLarge && !IntPtr.Zero.Equals(small))
|
||||||
|
{
|
||||||
|
User32.DestroyIcon(small);
|
||||||
}
|
}
|
||||||
|
|
||||||
binaryWriter.Flush();
|
if (isSmall && !IntPtr.Zero.Equals(large))
|
||||||
//
|
|
||||||
// Write image data
|
|
||||||
//
|
|
||||||
foreach (var encodedImage in encodedImages)
|
|
||||||
{
|
{
|
||||||
encodedImage.WriteTo(stream);
|
User32.DestroyIcon(large);
|
||||||
encodedImage.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return returnIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create an image from a stream, if an extension is supplied more formats are supported.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">Stream</param>
|
||||||
|
/// <param name="extension"></param>
|
||||||
|
/// <returns>Image</returns>
|
||||||
|
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<IFileFormatHandler>();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Load a Greenshot surface from a stream
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="surfaceFileStream">Stream</param>
|
||||||
|
/// <param name="returnSurface"></param>
|
||||||
|
/// <returns>ISurface</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,77 +0,0 @@
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Imaging;
|
|
||||||
|
|
||||||
namespace Greenshot.Base.Core
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Wrap an image, make it resizeable
|
|
||||||
/// </summary>
|
|
||||||
public class ImageWrapper : IImage
|
|
||||||
{
|
|
||||||
// Underlying image, is used to generate a resized version of it when needed
|
|
||||||
private readonly Image _image;
|
|
||||||
private Image _imageClone;
|
|
||||||
|
|
||||||
public ImageWrapper(Image image)
|
|
||||||
{
|
|
||||||
// Make sure the orientation is set correctly so Greenshot can process the image correctly
|
|
||||||
ImageHelper.Orientate(image);
|
|
||||||
_image = image;
|
|
||||||
Width = _image.Width;
|
|
||||||
Height = _image.Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_image.Dispose();
|
|
||||||
_imageClone?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Height of the image, can be set to change
|
|
||||||
/// </summary>
|
|
||||||
public int Height { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Width of the image, can be set to change.
|
|
||||||
/// </summary>
|
|
||||||
public int Width { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Size of the image
|
|
||||||
/// </summary>
|
|
||||||
public Size Size => new Size(Width, Height);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Pixelformat of the underlying image
|
|
||||||
/// </summary>
|
|
||||||
public PixelFormat PixelFormat => Image.PixelFormat;
|
|
||||||
|
|
||||||
public float HorizontalResolution => Image.HorizontalResolution;
|
|
||||||
public float VerticalResolution => Image.VerticalResolution;
|
|
||||||
|
|
||||||
public Image Image
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_imageClone == null)
|
|
||||||
{
|
|
||||||
if (_image.Height == Height && _image.Width == Width)
|
|
||||||
{
|
|
||||||
return _image;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_imageClone?.Height == Height && _imageClone?.Width == Width)
|
|
||||||
{
|
|
||||||
return _imageClone;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate new image clone
|
|
||||||
_imageClone?.Dispose();
|
|
||||||
_imageClone = ImageHelper.ResizeImage(_image, false, Width, Height, null);
|
|
||||||
return _imageClone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,11 +24,14 @@ 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;
|
||||||
|
using Greenshot.Base.Core.FileFormatHandlers;
|
||||||
using Greenshot.Base.IniFile;
|
using Greenshot.Base.IniFile;
|
||||||
using Greenshot.Base.Interfaces;
|
using Greenshot.Base.Interfaces;
|
||||||
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Base.Interfaces.Plugin;
|
using Greenshot.Base.Interfaces.Plugin;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
|
@ -87,24 +90,14 @@ namespace Greenshot.Base.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Download the uri to Bitmap
|
/// Download the uri to build an IDrawableContainer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="url">Of an image</param>
|
/// <param name="url">Of an image</param>
|
||||||
/// <returns>Bitmap</returns>
|
/// <returns>IDrawableContainer</returns>
|
||||||
public static Image DownloadImage(string url)
|
public static IDrawableContainer DownloadImageAsDrawableContainer(string url)
|
||||||
{
|
{
|
||||||
var extensions = new StringBuilder();
|
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
|
||||||
foreach (var extension in ImageHelper.StreamConverters.Keys)
|
var extensions = string.Join("|", fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadFromStream));
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(extension))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
extensions.AppendFormat(@"\.{0}|", extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
extensions.Length--;
|
|
||||||
|
|
||||||
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);
|
||||||
|
@ -113,7 +106,12 @@ namespace Greenshot.Base.Core
|
||||||
using var memoryStream = GetAsMemoryStream(url);
|
using var memoryStream = GetAsMemoryStream(url);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return ImageHelper.FromStream(memoryStream, match.Success ? match.Groups["extension"]?.Value : null);
|
var extension = match.Success ? match.Groups["extension"]?.Value : null;
|
||||||
|
var drawableContainer = fileFormatHandlers.LoadDrawablesFromStream(memoryStream, extension).FirstOrDefault();
|
||||||
|
if (drawableContainer != null)
|
||||||
|
{
|
||||||
|
return drawableContainer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
@ -136,7 +134,71 @@ namespace Greenshot.Base.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
using var memoryStream2 = GetAsMemoryStream(match.Value);
|
using var memoryStream2 = GetAsMemoryStream(match.Value);
|
||||||
return ImageHelper.FromStream(memoryStream2, match.Groups["extension"]?.Value);
|
|
||||||
|
var extension = match.Success ? match.Groups["extension"]?.Value : null;
|
||||||
|
var drawableContainer = fileFormatHandlers.LoadDrawablesFromStream(memoryStream2, extension).FirstOrDefault();
|
||||||
|
if (drawableContainer != null)
|
||||||
|
{
|
||||||
|
return drawableContainer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error("Problem downloading the image from: " + url, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Download the uri to create a Bitmap
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="url">Of an image</param>
|
||||||
|
/// <returns>Bitmap</returns>
|
||||||
|
public static Bitmap DownloadImage(string url)
|
||||||
|
{
|
||||||
|
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
|
||||||
|
|
||||||
|
var extensions = string.Join("|", fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadFromStream));
|
||||||
|
|
||||||
|
var imageUrlRegex = new Regex($@"(http|https)://.*(?<extension>{extensions})");
|
||||||
|
var match = imageUrlRegex.Match(url);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var memoryStream = GetAsMemoryStream(url);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (fileFormatHandlers.TryLoadFromStream(memoryStream, match.Success ? match.Groups["extension"]?.Value : null, out var bitmap))
|
||||||
|
{
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// If we arrive here, the image loading didn't work, try to see if the response has a http(s) URL to an image and just take this instead.
|
||||||
|
string content;
|
||||||
|
using (var streamReader = new StreamReader(memoryStream, Encoding.UTF8, true))
|
||||||
|
{
|
||||||
|
content = streamReader.ReadLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(content))
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
match = imageUrlRegex.Match(content);
|
||||||
|
if (!match.Success)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var memoryStream2 = GetAsMemoryStream(match.Value);
|
||||||
|
if (fileFormatHandlers.TryLoadFromStream(memoryStream2, match.Success ? match.Groups["extension"]?.Value : null, out var bitmap))
|
||||||
|
{
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -670,7 +732,7 @@ namespace Greenshot.Base.Core
|
||||||
public string ToBase64String(Base64FormattingOptions formattingOptions)
|
public string ToBase64String(Base64FormattingOptions formattingOptions)
|
||||||
{
|
{
|
||||||
using MemoryStream stream = new MemoryStream();
|
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);
|
return Convert.ToBase64String(stream.GetBuffer(), 0, (int) stream.Length, formattingOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,7 +744,7 @@ namespace Greenshot.Base.Core
|
||||||
public byte[] ToByteArray()
|
public byte[] ToByteArray()
|
||||||
{
|
{
|
||||||
using MemoryStream stream = new MemoryStream();
|
using MemoryStream stream = new MemoryStream();
|
||||||
ImageOutput.SaveToStream(_surface, stream, _outputSettings);
|
ImageIO.SaveToStream(_surface, stream, _outputSettings);
|
||||||
return stream.ToArray();
|
return stream.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,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";
|
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));
|
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
|
||||||
ImageOutput.SaveToStream(_surface, formDataStream, _outputSettings);
|
ImageIO.SaveToStream(_surface, formDataStream, _outputSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -708,7 +770,7 @@ namespace Greenshot.Base.Core
|
||||||
public void WriteToStream(Stream dataStream)
|
public void WriteToStream(Stream dataStream)
|
||||||
{
|
{
|
||||||
// Write the file data directly to the Stream, rather than serializing it to a string.
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -158,7 +158,7 @@ namespace Greenshot.Base.Core
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (Icon appIcon = ImageHelper.ExtractAssociatedIcon(path, index, CoreConfig.UseLargeIcons))
|
using (Icon appIcon = ImageIO.ExtractAssociatedIcon(path, index, CoreConfig.UseLargeIcons))
|
||||||
{
|
{
|
||||||
if (appIcon != null)
|
if (appIcon != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>()
|
||||||
|
|
|
@ -1,117 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Imaging;
|
|
||||||
using System.IO;
|
|
||||||
using Svg;
|
|
||||||
|
|
||||||
namespace Greenshot.Base.Core
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Create an image look like of the SVG
|
|
||||||
/// </summary>
|
|
||||||
public sealed class SvgImage : IImage
|
|
||||||
{
|
|
||||||
private readonly SvgDocument _svgDocument;
|
|
||||||
|
|
||||||
private Image _imageClone;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Factory to create via a stream
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="stream">Stream</param>
|
|
||||||
/// <returns>IImage</returns>
|
|
||||||
public static IImage FromStream(Stream stream)
|
|
||||||
{
|
|
||||||
return new SvgImage(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default constructor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="stream"></param>
|
|
||||||
public SvgImage(Stream stream)
|
|
||||||
{
|
|
||||||
_svgDocument = SvgDocument.Open<SvgDocument>(stream);
|
|
||||||
Height = (int) _svgDocument.ViewBox.Height;
|
|
||||||
Width = (int) _svgDocument.ViewBox.Width;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Height of the image, can be set to change
|
|
||||||
/// </summary>
|
|
||||||
public int Height { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Width of the image, can be set to change.
|
|
||||||
/// </summary>
|
|
||||||
public int Width { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Size of the image
|
|
||||||
/// </summary>
|
|
||||||
public Size Size => new Size(Width, Height);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Pixelformat of the underlying image
|
|
||||||
/// </summary>
|
|
||||||
public PixelFormat PixelFormat => Image.PixelFormat;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Horizontal resolution of the underlying image
|
|
||||||
/// </summary>
|
|
||||||
public float HorizontalResolution => Image.HorizontalResolution;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Vertical resolution of the underlying image
|
|
||||||
/// </summary>
|
|
||||||
public float VerticalResolution => Image.VerticalResolution;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Underlying image, or an on demand rendered version with different attributes as the original
|
|
||||||
/// </summary>
|
|
||||||
public Image Image
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_imageClone?.Height == Height && _imageClone?.Width == Width)
|
|
||||||
{
|
|
||||||
return _imageClone;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate new image clone
|
|
||||||
_imageClone?.Dispose();
|
|
||||||
_imageClone = ImageHelper.CreateEmpty(Width, Height, PixelFormat.Format32bppArgb, Color.Transparent, 96, 96);
|
|
||||||
_svgDocument.Draw((Bitmap) _imageClone);
|
|
||||||
return _imageClone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_imageClone?.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -782,7 +782,9 @@ namespace Greenshot.Base.Core
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public WindowStyleFlags WindowStyle
|
public WindowStyleFlags WindowStyle
|
||||||
{
|
{
|
||||||
get => (WindowStyleFlags) User32.GetWindowLongWrapper(Handle, (int) WindowLongIndex.GWL_STYLE);
|
get => unchecked(
|
||||||
|
(WindowStyleFlags)User32.GetWindowLongWrapper(Handle, (int)WindowLongIndex.GWL_STYLE).ToInt64()
|
||||||
|
);
|
||||||
set => User32.SetWindowLongWrapper(Handle, (int) WindowLongIndex.GWL_STYLE, new IntPtr((long) value));
|
set => User32.SetWindowLongWrapper(Handle, (int) WindowLongIndex.GWL_STYLE, new IntPtr((long) value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,14 @@ namespace Greenshot.Base.Interfaces.Drawing
|
||||||
{
|
{
|
||||||
public interface IDrawableContainer : INotifyPropertyChanged, IDisposable
|
public interface IDrawableContainer : INotifyPropertyChanged, IDisposable
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The parent surface where this IDrawableContainer is on
|
||||||
|
/// </summary>
|
||||||
ISurface Parent { get; set; }
|
ISurface Parent { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is this IDrawableContainer selected on the surface
|
||||||
|
/// </summary>
|
||||||
bool Selected { get; set; }
|
bool Selected { get; set; }
|
||||||
|
|
||||||
int Left { get; set; }
|
int Left { get; set; }
|
||||||
|
@ -54,15 +61,25 @@ namespace Greenshot.Base.Interfaces.Drawing
|
||||||
bool HasFilters { get; }
|
bool HasFilters { get; }
|
||||||
|
|
||||||
EditStatus Status { get; set; }
|
EditStatus Status { get; set; }
|
||||||
|
|
||||||
void Invalidate();
|
void Invalidate();
|
||||||
|
|
||||||
bool ClickableAt(int x, int y);
|
bool ClickableAt(int x, int y);
|
||||||
|
|
||||||
void MoveBy(int x, int y);
|
void MoveBy(int x, int y);
|
||||||
|
|
||||||
void Transform(Matrix matrix);
|
void Transform(Matrix matrix);
|
||||||
|
|
||||||
bool HandleMouseDown(int x, int y);
|
bool HandleMouseDown(int x, int y);
|
||||||
|
|
||||||
void HandleMouseUp(int x, int y);
|
void HandleMouseUp(int x, int y);
|
||||||
|
|
||||||
bool HandleMouseMove(int x, int y);
|
bool HandleMouseMove(int x, int y);
|
||||||
|
|
||||||
bool InitContent();
|
bool InitContent();
|
||||||
|
|
||||||
void MakeBoundsChangeUndoable(bool allowMerge);
|
void MakeBoundsChangeUndoable(bool allowMerge);
|
||||||
|
|
||||||
EditStatus DefaultEditMode { get; }
|
EditStatus DefaultEditMode { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
33
src/Greenshot.Base/Interfaces/Drawing/IFieldAggregator.cs
Normal file
33
src/Greenshot.Base/Interfaces/Drawing/IFieldAggregator.cs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Greenshot.Base.Interfaces.Drawing
|
||||||
|
{
|
||||||
|
public interface IFieldAggregator
|
||||||
|
{
|
||||||
|
void UnbindElement(IDrawableContainer dc);
|
||||||
|
void BindElements(IDrawableContainerList dcs);
|
||||||
|
void BindElement(IDrawableContainer dc);
|
||||||
|
IField GetField(IFieldType fieldType);
|
||||||
|
|
||||||
|
event FieldChangedEventHandler FieldChanged;
|
||||||
|
}
|
||||||
|
}
|
88
src/Greenshot.Base/Interfaces/IFileFormatHandler.cs
Normal file
88
src/Greenshot.Base/Interfaces/IFileFormatHandler.cs
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
|
using Greenshot.Base.Interfaces.Plugin;
|
||||||
|
|
||||||
|
namespace Greenshot.Base.Interfaces
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The possible actions a IFileFormatHandler might support
|
||||||
|
/// </summary>
|
||||||
|
public enum FileFormatHandlerActions
|
||||||
|
{
|
||||||
|
SaveToStream,
|
||||||
|
LoadFromStream,
|
||||||
|
LoadDrawableFromStream
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This interface is for code to implement the loading and saving of certain file formats
|
||||||
|
/// </summary>
|
||||||
|
public interface IFileFormatHandler
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Registry for all the extensions this IFileFormatHandler support
|
||||||
|
/// </summary>
|
||||||
|
IDictionary<FileFormatHandlerActions, IReadOnlyCollection<string>> SupportedExtensions { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Priority (from high int.MinValue, low int.MaxValue) of this IFileFormatHandler for the specified action and extension
|
||||||
|
/// This should be used to sort the possible IFileFormatHandler
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileFormatHandlerAction">FileFormatHandlerActions</param>
|
||||||
|
/// <param name="extension">string</param>
|
||||||
|
/// <returns>int specifying the priority for the action and extension</returns>
|
||||||
|
public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to save the specified bitmap to the stream in the format belonging to the extension
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bitmap">Bitmap</param>
|
||||||
|
/// <param name="destination">Stream</param>
|
||||||
|
/// <param name="extension">extension</param>
|
||||||
|
/// <param name="surface">ISurface with the elements for those file types which can store a surface (.greenshot)</param>
|
||||||
|
/// <param name="surfaceOutputSettings">SurfaceOutputSettings</param>
|
||||||
|
/// <returns>bool true if it was successful</returns>
|
||||||
|
public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream"></param>
|
||||||
|
/// <param name="extension"></param>
|
||||||
|
/// <param name="bitmap"></param>
|
||||||
|
/// <returns>bool true if it was successful</returns>
|
||||||
|
public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to load a drawable container from the stream
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">Stream</param>
|
||||||
|
/// <param name="extension">string</param>
|
||||||
|
/// <param name="parentSurface">ISurface</param>
|
||||||
|
/// <returns>IEnumerable{IDrawableContainer}</returns>
|
||||||
|
public IEnumerable<IDrawableContainer> LoadDrawablesFromStream(Stream stream, string extension, ISurface parentSurface = null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Greenshot.Base.Core;
|
using Greenshot.Base.Core;
|
||||||
|
@ -201,5 +202,14 @@ namespace Greenshot.Base.Interfaces
|
||||||
Rectangle ToImageCoordinates(Rectangle rc);
|
Rectangle ToImageCoordinates(Rectangle rc);
|
||||||
|
|
||||||
void MakeUndoable(IMemento memento, bool allowMerge);
|
void MakeUndoable(IMemento memento, bool allowMerge);
|
||||||
|
|
||||||
|
IFieldAggregator FieldAggregator { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This reverses a change of the background image
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="previous">Image</param>
|
||||||
|
/// <param name="matrix">Matrix</param>
|
||||||
|
void UndoBackgroundChange(Image previous, Matrix matrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,25 @@
|
||||||
using System.Collections.Generic;
|
/*
|
||||||
|
* Greenshot - a free and open source screenshot tool
|
||||||
|
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
|
||||||
|
*
|
||||||
|
* For more information see: https://getgreenshot.org/
|
||||||
|
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 1 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using Greenshot.Base.Core;
|
using Greenshot.Base.Core;
|
||||||
using Greenshot.Base.Core.Enums;
|
using Greenshot.Base.Core.Enums;
|
||||||
using Greenshot.Base.Effects;
|
using Greenshot.Base.Effects;
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace Greenshot.Base.UnmanagedHelpers.Enums
|
||||||
public enum WindowStyleFlags : int
|
public enum WindowStyleFlags : int
|
||||||
{
|
{
|
||||||
//WS_OVERLAPPED = 0x00000000,
|
//WS_OVERLAPPED = 0x00000000,
|
||||||
WS_POPUP = -2147483648,
|
WS_POPUP = -2147483648, // 0x80000000
|
||||||
WS_CHILD = 0x40000000,
|
WS_CHILD = 0x40000000,
|
||||||
WS_MINIMIZE = 0x20000000,
|
WS_MINIMIZE = 0x20000000,
|
||||||
WS_VISIBLE = 0x10000000,
|
WS_VISIBLE = 0x10000000,
|
||||||
|
|
|
@ -127,7 +127,7 @@ namespace Greenshot.Base.UnmanagedHelpers
|
||||||
public static extern IntPtr SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam);
|
public static extern IntPtr SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam);
|
||||||
|
|
||||||
[DllImport("user32", SetLastError = true, EntryPoint = "GetWindowLong")]
|
[DllImport("user32", SetLastError = true, EntryPoint = "GetWindowLong")]
|
||||||
public static extern int GetWindowLong(IntPtr hWnd, int index);
|
public static extern IntPtr GetWindowLong(IntPtr hWnd, int index);
|
||||||
|
|
||||||
[DllImport("user32", SetLastError = true, EntryPoint = "GetWindowLongPtr")]
|
[DllImport("user32", SetLastError = true, EntryPoint = "GetWindowLongPtr")]
|
||||||
public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
|
public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
|
||||||
|
@ -276,17 +276,15 @@ namespace Greenshot.Base.UnmanagedHelpers
|
||||||
/// <param name="hWnd"></param>
|
/// <param name="hWnd"></param>
|
||||||
/// <param name="nIndex"></param>
|
/// <param name="nIndex"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static long GetWindowLongWrapper(IntPtr hWnd, int nIndex)
|
public static IntPtr GetWindowLongWrapper(IntPtr hWnd, int nIndex)
|
||||||
{
|
{
|
||||||
if (IntPtr.Size == 8)
|
if (IntPtr.Size == 8)
|
||||||
{
|
{
|
||||||
return GetWindowLongPtr(hWnd, nIndex).ToInt64();
|
return GetWindowLongPtr(hWnd, nIndex);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return GetWindowLong(hWnd, nIndex);
|
return GetWindowLong(hWnd, nIndex);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Wrapper for the SetWindowLong which decides if the system is 64-bit or not and calls the right one.
|
/// Wrapper for the SetWindowLong which decides if the system is 64-bit or not and calls the right one.
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
private static readonly AdjustableArrowCap ARROW_CAP = new AdjustableArrowCap(4, 6);
|
private static readonly AdjustableArrowCap ARROW_CAP = new AdjustableArrowCap(4, 6);
|
||||||
|
|
||||||
public ArrowContainer(Surface parent) : base(parent)
|
public ArrowContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
using Greenshot.Editor.Helpers;
|
using Greenshot.Editor.Helpers;
|
||||||
|
@ -32,7 +33,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CropContainer : DrawableContainer
|
public class CropContainer : DrawableContainer
|
||||||
{
|
{
|
||||||
public CropContainer(Surface parent) : base(parent)
|
public CropContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ using System.Drawing.Drawing2D;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
protected Cursor cursor;
|
protected Cursor cursor;
|
||||||
|
|
||||||
public CursorContainer(Surface parent) : base(parent)
|
public CursorContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
@ -56,7 +57,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
CreateDefaultAdorners();
|
CreateDefaultAdorners();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CursorContainer(Surface parent, string filename) : this(parent)
|
public CursorContainer(ISurface parent, string filename) : this(parent)
|
||||||
{
|
{
|
||||||
Load(filename);
|
Load(filename);
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,12 +126,17 @@ namespace Greenshot.Editor.Drawing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[NonSerialized] internal Surface _parent;
|
[NonSerialized] internal ISurface _parent;
|
||||||
|
|
||||||
public ISurface Parent
|
public ISurface Parent
|
||||||
{
|
{
|
||||||
get => _parent;
|
get => _parent;
|
||||||
set => SwitchParent((Surface) value);
|
set => SwitchParent(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Surface InternalParent
|
||||||
|
{
|
||||||
|
get => (Surface)_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
[NonSerialized] private TargetAdorner _targetAdorner;
|
[NonSerialized] private TargetAdorner _targetAdorner;
|
||||||
|
@ -277,7 +282,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
Height = Round(newBounds.Height);
|
Height = Round(newBounds.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DrawableContainer(Surface parent)
|
public DrawableContainer(ISurface parent)
|
||||||
{
|
{
|
||||||
InitializeFields();
|
InitializeFields();
|
||||||
_parent = parent;
|
_parent = parent;
|
||||||
|
@ -505,7 +510,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
{
|
{
|
||||||
Invalidate();
|
Invalidate();
|
||||||
|
|
||||||
// reset "workrbench" rectangle to current bounds
|
// reset "workbench" rectangle to current bounds
|
||||||
_boundsAfterResize.X = _boundsBeforeResize.Left;
|
_boundsAfterResize.X = _boundsBeforeResize.Left;
|
||||||
_boundsAfterResize.Y = _boundsBeforeResize.Top;
|
_boundsAfterResize.Y = _boundsBeforeResize.Top;
|
||||||
_boundsAfterResize.Width = x - _boundsAfterResize.Left;
|
_boundsAfterResize.Width = x - _boundsAfterResize.Left;
|
||||||
|
@ -529,7 +534,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void SwitchParent(Surface newParent)
|
protected virtual void SwitchParent(ISurface newParent)
|
||||||
{
|
{
|
||||||
if (newParent == Parent)
|
if (newParent == Parent)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,7 @@ using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
using Greenshot.Editor.Helpers;
|
using Greenshot.Editor.Helpers;
|
||||||
|
@ -35,7 +36,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
[Serializable()]
|
[Serializable()]
|
||||||
public class EllipseContainer : DrawableContainer
|
public class EllipseContainer : DrawableContainer
|
||||||
{
|
{
|
||||||
public EllipseContainer(Surface parent) : base(parent)
|
public EllipseContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace Greenshot.Editor.Drawing.Fields
|
||||||
/// If the property values of the selected elements differ, the value of the last bound element wins.
|
/// If the property values of the selected elements differ, the value of the last bound element wins.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public sealed class FieldAggregator : AbstractFieldHolder
|
public sealed class FieldAggregator : AbstractFieldHolder, IFieldAggregator
|
||||||
{
|
{
|
||||||
private readonly IDrawableContainerList _boundContainers;
|
private readonly IDrawableContainerList _boundContainers;
|
||||||
private bool _internalUpdateRunning;
|
private bool _internalUpdateRunning;
|
||||||
|
@ -117,12 +117,11 @@ namespace Greenshot.Editor.Drawing.Fields
|
||||||
|
|
||||||
public void UnbindElement(IDrawableContainer dc)
|
public void UnbindElement(IDrawableContainer dc)
|
||||||
{
|
{
|
||||||
if (_boundContainers.Contains(dc))
|
if (!_boundContainers.Contains(dc)) return;
|
||||||
{
|
|
||||||
_boundContainers.Remove(dc);
|
_boundContainers.Remove(dc);
|
||||||
UpdateFromBoundElements();
|
UpdateFromBoundElements();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,7 @@ using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
using Greenshot.Editor.Helpers;
|
using Greenshot.Editor.Helpers;
|
||||||
|
@ -51,7 +52,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
MAGNIFICATION
|
MAGNIFICATION
|
||||||
};
|
};
|
||||||
|
|
||||||
public FilterContainer(Surface parent) : base(parent)
|
public FilterContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
using Greenshot.Editor.Helpers;
|
using Greenshot.Editor.Helpers;
|
||||||
|
@ -50,7 +51,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public FreehandContainer(Surface parent) : base(parent)
|
public FreehandContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
Width = parent.Image.Width;
|
Width = parent.Image.Width;
|
||||||
Height = parent.Image.Height;
|
Height = parent.Image.Height;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
using Greenshot.Editor.Drawing.Filters;
|
using Greenshot.Editor.Drawing.Filters;
|
||||||
|
@ -33,7 +34,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class HighlightContainer : FilterContainer
|
public class HighlightContainer : FilterContainer
|
||||||
{
|
{
|
||||||
public HighlightContainer(Surface parent) : base(parent)
|
public HighlightContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
protected Icon icon;
|
protected Icon icon;
|
||||||
|
|
||||||
public IconContainer(Surface parent) : base(parent)
|
public IconContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
@ -55,11 +56,16 @@ namespace Greenshot.Editor.Drawing
|
||||||
CreateDefaultAdorners();
|
CreateDefaultAdorners();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IconContainer(Surface parent, string filename) : base(parent)
|
public IconContainer(ISurface parent, string filename) : base(parent)
|
||||||
{
|
{
|
||||||
Load(filename);
|
Load(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IconContainer(ISurface parent, Stream stream) : base(parent)
|
||||||
|
{
|
||||||
|
Load(stream);
|
||||||
|
}
|
||||||
|
|
||||||
public Icon Icon
|
public Icon Icon
|
||||||
{
|
{
|
||||||
set
|
set
|
||||||
|
@ -99,6 +105,18 @@ namespace Greenshot.Editor.Drawing
|
||||||
Log.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
|
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)
|
public override void Draw(Graphics graphics, RenderMode rm)
|
||||||
{
|
{
|
||||||
if (icon == null)
|
if (icon == null)
|
||||||
|
|
|
@ -26,6 +26,7 @@ using System.IO;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using Greenshot.Base.Core;
|
using Greenshot.Base.Core;
|
||||||
using Greenshot.Base.Effects;
|
using Greenshot.Base.Effects;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
@ -40,7 +41,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
{
|
{
|
||||||
private static readonly ILog Log = LogManager.GetLogger(typeof(ImageContainer));
|
private static readonly ILog Log = LogManager.GetLogger(typeof(ImageContainer));
|
||||||
|
|
||||||
private Image image;
|
private Image _image;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the shadow version of the bitmap, rendered once to save performance
|
/// This is the shadow version of the bitmap, rendered once to save performance
|
||||||
|
@ -54,12 +55,12 @@ namespace Greenshot.Editor.Drawing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[NonSerialized] private Point _shadowOffset = new Point(-1, -1);
|
[NonSerialized] private Point _shadowOffset = new Point(-1, -1);
|
||||||
|
|
||||||
public ImageContainer(Surface parent, string filename) : this(parent)
|
public ImageContainer(ISurface parent, string filename) : this(parent)
|
||||||
{
|
{
|
||||||
Load(filename);
|
Load(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageContainer(Surface parent) : base(parent)
|
public ImageContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
FieldChanged += BitmapContainer_OnFieldChanged;
|
FieldChanged += BitmapContainer_OnFieldChanged;
|
||||||
Init();
|
Init();
|
||||||
|
@ -107,8 +108,8 @@ namespace Greenshot.Editor.Drawing
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Width = image.Width;
|
Width = _image.Width;
|
||||||
Height = image.Height;
|
Height = _image.Height;
|
||||||
if (_shadowBitmap != null)
|
if (_shadowBitmap != null)
|
||||||
{
|
{
|
||||||
Left += _shadowOffset.X;
|
Left += _shadowOffset.X;
|
||||||
|
@ -124,13 +125,13 @@ namespace Greenshot.Editor.Drawing
|
||||||
// Remove all current bitmaps
|
// Remove all current bitmaps
|
||||||
DisposeImage();
|
DisposeImage();
|
||||||
DisposeShadow();
|
DisposeShadow();
|
||||||
image = ImageHelper.Clone(value);
|
_image = ImageHelper.Clone(value);
|
||||||
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
|
||||||
CheckShadow(shadow);
|
CheckShadow(shadow);
|
||||||
if (!shadow)
|
if (!shadow)
|
||||||
{
|
{
|
||||||
Width = image.Width;
|
Width = _image.Width;
|
||||||
Height = image.Height;
|
Height = _image.Height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -140,7 +141,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
Top -= _shadowOffset.Y;
|
Top -= _shadowOffset.Y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
get { return image; }
|
get { return _image; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -162,8 +163,8 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
private void DisposeImage()
|
private void DisposeImage()
|
||||||
{
|
{
|
||||||
image?.Dispose();
|
_image?.Dispose();
|
||||||
image = null;
|
_image = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisposeShadow()
|
private void DisposeShadow()
|
||||||
|
@ -186,9 +187,9 @@ namespace Greenshot.Editor.Drawing
|
||||||
Log.DebugFormat("Rotating element with {0} degrees.", rotateAngle);
|
Log.DebugFormat("Rotating element with {0} degrees.", rotateAngle);
|
||||||
DisposeShadow();
|
DisposeShadow();
|
||||||
using var tmpMatrix = new Matrix();
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +209,8 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
// Always make sure ImageHelper.LoadBitmap results are disposed some time,
|
// Always make sure ImageHelper.LoadBitmap results are disposed some time,
|
||||||
// as we close the bitmap internally, we need to do it afterwards
|
// 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;
|
Image = tmpImage;
|
||||||
}
|
}
|
||||||
|
@ -228,7 +230,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
}
|
}
|
||||||
|
|
||||||
using var matrix = new Matrix();
|
using var matrix = new Matrix();
|
||||||
_shadowBitmap = ImageHelper.ApplyEffect(image, new DropShadowEffect(), matrix);
|
_shadowBitmap = ImageHelper.ApplyEffect(_image, new DropShadowEffect(), matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -238,7 +240,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
/// <param name="rm"></param>
|
/// <param name="rm"></param>
|
||||||
public override void Draw(Graphics graphics, RenderMode rm)
|
public override void Draw(Graphics graphics, RenderMode rm)
|
||||||
{
|
{
|
||||||
if (image == null)
|
if (_image == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -256,12 +258,12 @@ namespace Greenshot.Editor.Drawing
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
graphics.DrawImage(image, Bounds);
|
graphics.DrawImage(_image, Bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool HasDefaultSize => true;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,6 +23,7 @@ using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Adorners;
|
using Greenshot.Editor.Drawing.Adorners;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
|
@ -36,7 +37,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
[Serializable()]
|
[Serializable()]
|
||||||
public class LineContainer : DrawableContainer
|
public class LineContainer : DrawableContainer
|
||||||
{
|
{
|
||||||
public LineContainer(Surface parent) : base(parent)
|
public LineContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
81
src/Greenshot.Editor/Drawing/MetafileContainer.cs
Normal file
81
src/Greenshot.Editor/Drawing/MetafileContainer.cs
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This provides a resizable SVG container, redrawing the SVG in the size the container takes.
|
||||||
|
/// </summary>
|
||||||
|
[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;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
_metafile?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool HasDefaultSize => true;
|
||||||
|
|
||||||
|
public override Size DefaultSize => new Size(_metafile.Width, _metafile.Height);
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
using Greenshot.Editor.Drawing.Filters;
|
using Greenshot.Editor.Drawing.Filters;
|
||||||
|
@ -28,12 +29,12 @@ using Greenshot.Editor.Drawing.Filters;
|
||||||
namespace Greenshot.Editor.Drawing
|
namespace Greenshot.Editor.Drawing
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of ObfuscateContainer.
|
/// This is a FilterContainer for the obfuscator filters like blur and pixelate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class ObfuscateContainer : FilterContainer
|
public class ObfuscateContainer : FilterContainer
|
||||||
{
|
{
|
||||||
public ObfuscateContainer(Surface parent) : base(parent)
|
public ObfuscateContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
using Greenshot.Editor.Helpers;
|
using Greenshot.Editor.Helpers;
|
||||||
|
@ -35,7 +36,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class RectangleContainer : DrawableContainer
|
public class RectangleContainer : DrawableContainer
|
||||||
{
|
{
|
||||||
public RectangleContainer(Surface parent) : base(parent)
|
public RectangleContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Drawing.Text;
|
using System.Drawing.Text;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
using Greenshot.Editor.Helpers;
|
using Greenshot.Editor.Helpers;
|
||||||
|
@ -64,8 +65,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
InitAdorner(Color.Green, _storedTargetGripperLocation);
|
InitAdorner(Color.Green, _storedTargetGripperLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpeechbubbleContainer(Surface parent)
|
public SpeechbubbleContainer(ISurface parent) : base(parent)
|
||||||
: base(parent)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Drawing.Text;
|
using System.Drawing.Text;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
using Greenshot.Editor.Helpers;
|
using Greenshot.Editor.Helpers;
|
||||||
|
@ -41,9 +42,9 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
private readonly bool _drawAsRectangle = false;
|
private readonly bool _drawAsRectangle = false;
|
||||||
|
|
||||||
public StepLabelContainer(Surface parent) : base(parent)
|
public StepLabelContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
parent.AddStepLabel(this);
|
InternalParent?.AddStepLabel(this);
|
||||||
InitContent();
|
InitContent();
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
@ -72,11 +73,10 @@ namespace Greenshot.Editor.Drawing
|
||||||
[OnSerializing]
|
[OnSerializing]
|
||||||
private void SetValuesOnSerializing(StreamingContext context)
|
private void SetValuesOnSerializing(StreamingContext context)
|
||||||
{
|
{
|
||||||
if (Parent != null)
|
if (InternalParent == null) return;
|
||||||
{
|
|
||||||
Number = ((Surface) Parent).CountStepLabels(this);
|
Number = InternalParent.CountStepLabels(this);
|
||||||
_counterStart = ((Surface) Parent).CounterStart;
|
_counterStart = InternalParent.CounterStart;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -97,23 +97,23 @@ namespace Greenshot.Editor.Drawing
|
||||||
/// Add the StepLabel to the parent
|
/// Add the StepLabel to the parent
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="newParent"></param>
|
/// <param name="newParent"></param>
|
||||||
protected override void SwitchParent(Surface newParent)
|
protected override void SwitchParent(ISurface newParent)
|
||||||
{
|
{
|
||||||
if (newParent == Parent)
|
if (newParent == Parent)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
((Surface) Parent)?.RemoveStepLabel(this);
|
if (newParent is not Surface newParentSurface)
|
||||||
base.SwitchParent(newParent);
|
|
||||||
if (newParent == null)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
InternalParent?.RemoveStepLabel(this);
|
||||||
|
base.SwitchParent(newParent);
|
||||||
|
|
||||||
// Make sure the counter start is restored (this unfortunately happens multiple times... -> hack)
|
// Make sure the counter start is restored (this unfortunately happens multiple times... -> hack)
|
||||||
newParent.CounterStart = _counterStart;
|
newParentSurface.CounterStart = _counterStart;
|
||||||
newParent.AddStepLabel(this);
|
newParentSurface.AddStepLabel(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Size DefaultSize => new Size(30, 30);
|
public override Size DefaultSize => new Size(30, 30);
|
||||||
|
@ -204,7 +204,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
EllipseContainer.DrawEllipse(rect, graphics, rm, 0, Color.Transparent, fillColor, false);
|
EllipseContainer.DrawEllipse(rect, graphics, rm, 0, Color.Transparent, fillColor, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
float fontSize = Math.Min(Width, Height) / 1.4f;
|
float fontSize = Math.Min(Math.Abs(Width), Math.Abs(Height)) / 1.4f;
|
||||||
using FontFamily fam = new FontFamily(FontFamily.GenericSansSerif.Name);
|
using FontFamily fam = new FontFamily(FontFamily.GenericSansSerif.Name);
|
||||||
using Font font = new Font(fam, fontSize, FontStyle.Bold, GraphicsUnit.Pixel);
|
using Font font = new Font(fam, fontSize, FontStyle.Bold, GraphicsUnit.Pixel);
|
||||||
TextContainer.DrawText(graphics, rect, 0, lineColor, false, _stringFormat, text, font);
|
TextContainer.DrawText(graphics, rect, 0, lineColor, false, _stringFormat, text, font);
|
||||||
|
|
|
@ -49,7 +49,6 @@ namespace Greenshot.Editor.Drawing
|
||||||
public sealed class Surface : Control, ISurface, INotifyPropertyChanged
|
public sealed class Surface : Control, ISurface, INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private static readonly ILog LOG = LogManager.GetLogger(typeof(Surface));
|
private static readonly ILog LOG = LogManager.GetLogger(typeof(Surface));
|
||||||
public static int Count;
|
|
||||||
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
|
private static readonly CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
|
||||||
|
|
||||||
// Property to identify the Surface ID
|
// Property to identify the Surface ID
|
||||||
|
@ -207,7 +206,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
[NonSerialized] private IDrawableContainer _undrawnElement;
|
[NonSerialized] private IDrawableContainer _undrawnElement;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// the cropcontainer, when cropping this is set, do not serialize
|
/// the crop container, when cropping this is set, do not serialize
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[NonSerialized] private IDrawableContainer _cropContainer;
|
[NonSerialized] private IDrawableContainer _cropContainer;
|
||||||
|
|
||||||
|
@ -294,7 +293,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// all elements on the surface, needed with serialization
|
/// all elements on the surface, needed with serialization
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private FieldAggregator _fieldAggregator;
|
private IFieldAggregator _fieldAggregator;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// the cursor container, needed with serialization as we need a direct acces to it.
|
/// the cursor container, needed with serialization as we need a direct acces to it.
|
||||||
|
@ -355,7 +354,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
/// The field aggregator is that which is used to have access to all the fields inside the currently selected elements.
|
/// The field aggregator is that which is used to have access to all the fields inside the currently selected elements.
|
||||||
/// e.g. used to decided if and which line thickness is shown when multiple elements are selected.
|
/// e.g. used to decided if and which line thickness is shown when multiple elements are selected.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public FieldAggregator FieldAggregator
|
public IFieldAggregator FieldAggregator
|
||||||
{
|
{
|
||||||
get => _fieldAggregator;
|
get => _fieldAggregator;
|
||||||
set => _fieldAggregator = value;
|
set => _fieldAggregator = value;
|
||||||
|
@ -467,7 +466,6 @@ namespace Greenshot.Editor.Drawing
|
||||||
public Surface()
|
public Surface()
|
||||||
{
|
{
|
||||||
_fieldAggregator = new FieldAggregator(this);
|
_fieldAggregator = new FieldAggregator(this);
|
||||||
Count++;
|
|
||||||
_elements = new DrawableContainerList(_uniqueId);
|
_elements = new DrawableContainerList(_uniqueId);
|
||||||
selectedElements = new DrawableContainerList(_uniqueId);
|
selectedElements = new DrawableContainerList(_uniqueId);
|
||||||
LOG.Debug("Creating surface!");
|
LOG.Debug("Creating surface!");
|
||||||
|
@ -550,7 +548,6 @@ namespace Greenshot.Editor.Drawing
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
Count--;
|
|
||||||
LOG.Debug("Disposing surface!");
|
LOG.Debug("Disposing surface!");
|
||||||
if (_buffer != null)
|
if (_buffer != null)
|
||||||
{
|
{
|
||||||
|
@ -913,6 +910,27 @@ namespace Greenshot.Editor.Drawing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This will help to fit the container to the surface
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="drawableContainer">IDrawableContainer</param>
|
||||||
|
private void FitContainer(IDrawableContainer drawableContainer)
|
||||||
|
{
|
||||||
|
double factor = 1;
|
||||||
|
if (drawableContainer.Width > this.Width)
|
||||||
|
{
|
||||||
|
factor = drawableContainer.Width / (double)Width;
|
||||||
|
}
|
||||||
|
if (drawableContainer.Height > this.Height)
|
||||||
|
{
|
||||||
|
var otherFactor = drawableContainer.Height / (double)Height;
|
||||||
|
factor = Math.Max(factor, otherFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawableContainer.Width = (int)(drawableContainer.Width / factor);
|
||||||
|
drawableContainer.Height = (int)(drawableContainer.Height / factor);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handle the drag/drop
|
/// Handle the drag/drop
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -927,20 +945,25 @@ namespace Greenshot.Editor.Drawing
|
||||||
// Test if it's an url and try to download the image so we have it in the original form
|
// 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"))
|
if (possibleUrl != null && possibleUrl.StartsWith("http"))
|
||||||
{
|
{
|
||||||
using Image image = NetworkHelper.DownloadImage(possibleUrl);
|
var drawableContainer = NetworkHelper.DownloadImageAsDrawableContainer(possibleUrl);
|
||||||
if (image != null)
|
if (drawableContainer != null)
|
||||||
{
|
{
|
||||||
AddImageContainer(image, mouse.X, mouse.Y);
|
drawableContainer.Left = Location.X;
|
||||||
|
drawableContainer.Top = Location.Y;
|
||||||
|
FitContainer(drawableContainer);
|
||||||
|
AddElement(drawableContainer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Image image in ClipboardHelper.GetImages(e.Data))
|
foreach (var drawableContainer in ClipboardHelper.GetDrawables(e.Data))
|
||||||
{
|
{
|
||||||
AddImageContainer(image, mouse.X, mouse.Y);
|
drawableContainer.Left = mouse.X;
|
||||||
|
drawableContainer.Top = mouse.Y;
|
||||||
|
FitContainer(drawableContainer);
|
||||||
|
AddElement(drawableContainer);
|
||||||
mouse.Offset(10, 10);
|
mouse.Offset(10, 10);
|
||||||
image.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -987,14 +1010,12 @@ namespace Greenshot.Editor.Drawing
|
||||||
{
|
{
|
||||||
//create a blank bitmap the same size as original
|
//create a blank bitmap the same size as original
|
||||||
Bitmap newBitmap = ImageHelper.CreateEmptyLike(Image, Color.Empty);
|
Bitmap newBitmap = ImageHelper.CreateEmptyLike(Image, Color.Empty);
|
||||||
if (newBitmap != null)
|
if (newBitmap == null) return;
|
||||||
{
|
|
||||||
// Make undoable
|
// Make undoable
|
||||||
MakeUndoable(new SurfaceBackgroundChangeMemento(this, null), false);
|
MakeUndoable(new SurfaceBackgroundChangeMemento(this, null), false);
|
||||||
SetImage(newBitmap, false);
|
SetImage(newBitmap, false);
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Apply a bitmap effect to the surface
|
/// Apply a bitmap effect to the surface
|
||||||
|
@ -2057,19 +2078,18 @@ namespace Greenshot.Editor.Drawing
|
||||||
{
|
{
|
||||||
Point pasteLocation = GetPasteLocation(0.1f, 0.1f);
|
Point pasteLocation = GetPasteLocation(0.1f, 0.1f);
|
||||||
|
|
||||||
foreach (Image clipboardImage in ClipboardHelper.GetImages(clipboard))
|
foreach (var drawableContainer in ClipboardHelper.GetDrawables(clipboard))
|
||||||
{
|
|
||||||
if (clipboardImage != null)
|
|
||||||
{
|
{
|
||||||
|
if (drawableContainer == null) continue;
|
||||||
DeselectAllElements();
|
DeselectAllElements();
|
||||||
IImageContainer container = AddImageContainer(clipboardImage as Bitmap, pasteLocation.X, pasteLocation.Y);
|
drawableContainer.Left = pasteLocation.X;
|
||||||
SelectElement(container);
|
drawableContainer.Top = pasteLocation.Y;
|
||||||
clipboardImage.Dispose();
|
AddElement(drawableContainer);
|
||||||
|
SelectElement(drawableContainer);
|
||||||
pasteLocation.X += 10;
|
pasteLocation.X += 10;
|
||||||
pasteLocation.Y += 10;
|
pasteLocation.Y += 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (ClipboardHelper.ContainsText(clipboard))
|
else if (ClipboardHelper.ContainsText(clipboard))
|
||||||
{
|
{
|
||||||
Point pasteLocation = GetPasteLocation(0.4f, 0.4f);
|
Point pasteLocation = GetPasteLocation(0.4f, 0.4f);
|
||||||
|
@ -2208,8 +2228,8 @@ namespace Greenshot.Editor.Drawing
|
||||||
/// <param name="generateEvents">false to skip event generation</param>
|
/// <param name="generateEvents">false to skip event generation</param>
|
||||||
public void SelectElement(IDrawableContainer container, bool invalidate = true, bool generateEvents = true)
|
public void SelectElement(IDrawableContainer container, bool invalidate = true, bool generateEvents = true)
|
||||||
{
|
{
|
||||||
if (!selectedElements.Contains(container))
|
if (selectedElements.Contains(container)) return;
|
||||||
{
|
|
||||||
selectedElements.Add(container);
|
selectedElements.Add(container);
|
||||||
container.Selected = true;
|
container.Selected = true;
|
||||||
FieldAggregator.BindElement(container);
|
FieldAggregator.BindElement(container);
|
||||||
|
@ -2227,7 +2247,6 @@ namespace Greenshot.Editor.Drawing
|
||||||
container.Invalidate();
|
container.Invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Select all elements, this is called when Ctrl+A is pressed
|
/// Select all elements, this is called when Ctrl+A is pressed
|
||||||
|
|
61
src/Greenshot.Editor/Drawing/SvgContainer.cs
Normal file
61
src/Greenshot.Editor/Drawing/SvgContainer.cs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using Greenshot.Base.Core;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
|
using Svg;
|
||||||
|
|
||||||
|
namespace Greenshot.Editor.Drawing
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This provides a resizable SVG container, redrawing the SVG in the size the container takes.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public class SvgContainer : VectorGraphicsContainer
|
||||||
|
{
|
||||||
|
private SvgDocument _svgDocument;
|
||||||
|
|
||||||
|
public SvgContainer(SvgDocument svgDocument, ISurface parent) : base(parent)
|
||||||
|
{
|
||||||
|
_svgDocument = svgDocument;
|
||||||
|
Size = new Size((int)svgDocument.Width, (int)svgDocument.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Image ComputeBitmap()
|
||||||
|
{
|
||||||
|
//var image = ImageHelper.CreateEmpty(Width, Height, PixelFormat.Format32bppArgb, Color.Transparent);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ using System.Drawing.Text;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Greenshot.Base.Core;
|
using Greenshot.Base.Core;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
using Greenshot.Editor.Helpers;
|
using Greenshot.Editor.Helpers;
|
||||||
|
@ -83,7 +84,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
OnPropertyChanged("Text");
|
OnPropertyChanged("Text");
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextContainer(Surface parent) : base(parent)
|
public TextContainer(ISurface parent) : base(parent)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
@ -154,17 +155,17 @@ namespace Greenshot.Editor.Drawing
|
||||||
FieldChanged += TextContainer_FieldChanged;
|
FieldChanged += TextContainer_FieldChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void SwitchParent(Surface newParent)
|
protected override void SwitchParent(ISurface newParent)
|
||||||
{
|
{
|
||||||
if (_parent != null)
|
if (InternalParent != null)
|
||||||
{
|
{
|
||||||
_parent.SizeChanged -= Parent_SizeChanged;
|
InternalParent.SizeChanged -= Parent_SizeChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
base.SwitchParent(newParent);
|
base.SwitchParent(newParent);
|
||||||
if (_parent != null)
|
if (InternalParent != null)
|
||||||
{
|
{
|
||||||
_parent.SizeChanged += Parent_SizeChanged;
|
InternalParent.SizeChanged += Parent_SizeChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,10 +222,10 @@ namespace Greenshot.Editor.Drawing
|
||||||
{
|
{
|
||||||
ShowTextBox();
|
ShowTextBox();
|
||||||
}
|
}
|
||||||
else if (_parent != null && Selected && Status == EditStatus.IDLE && _textBox.Visible)
|
else if (InternalParent != null && Selected && Status == EditStatus.IDLE && _textBox.Visible)
|
||||||
{
|
{
|
||||||
// Fix (workaround) for BUG-1698
|
// Fix (workaround) for BUG-1698
|
||||||
_parent.KeysLocked = true;
|
InternalParent.KeysLocked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,10 +296,10 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
private void ShowTextBox()
|
private void ShowTextBox()
|
||||||
{
|
{
|
||||||
if (_parent != null)
|
if (InternalParent != null)
|
||||||
{
|
{
|
||||||
_parent.KeysLocked = true;
|
InternalParent.KeysLocked = true;
|
||||||
_parent.Controls.Add(_textBox);
|
InternalParent.Controls.Add(_textBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnsureTextBoxContrast();
|
EnsureTextBoxContrast();
|
||||||
|
@ -332,15 +333,15 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
private void HideTextBox()
|
private void HideTextBox()
|
||||||
{
|
{
|
||||||
_parent?.Focus();
|
InternalParent?.Focus();
|
||||||
_textBox?.Hide();
|
_textBox?.Hide();
|
||||||
if (_parent == null)
|
if (InternalParent == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_parent.KeysLocked = false;
|
InternalParent.KeysLocked = false;
|
||||||
_parent.Controls.Remove(_textBox);
|
InternalParent.Controls.Remove(_textBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
117
src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs
Normal file
117
src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
|
|
||||||
|
namespace Greenshot.Editor.Drawing
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This is the base container for vector graphics, these ae graphics which can resize without loss of quality.
|
||||||
|
/// Examples for this are SVG, WMF or EMF, but also graphics based on fonts (e.g. Emoji)
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public abstract class VectorGraphicsContainer : DrawableContainer
|
||||||
|
{
|
||||||
|
protected int RotationAngle;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is the cached version of the bitmap, pre-rendered to save performance
|
||||||
|
/// Do not serialized, it can be rebuild with some other information.
|
||||||
|
/// </summary>
|
||||||
|
[NonSerialized] private Image _cachedImage;
|
||||||
|
|
||||||
|
public VectorGraphicsContainer(ISurface parent) : base(parent)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDeserialized(StreamingContext streamingContext)
|
||||||
|
{
|
||||||
|
base.OnDeserialized(streamingContext);
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Init()
|
||||||
|
{
|
||||||
|
CreateDefaultAdorners();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The bulk of the clean-up code is implemented in Dispose(bool)
|
||||||
|
/// This Dispose is called from the Dispose and the Destructor.
|
||||||
|
/// When disposing==true all non-managed resources should be freed too!
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing"></param>
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
ResetCachedBitmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IDrawableContainer"/>
|
||||||
|
public override void Transform(Matrix matrix)
|
||||||
|
{
|
||||||
|
RotationAngle += CalculateAngle(matrix);
|
||||||
|
RotationAngle %= 360;
|
||||||
|
|
||||||
|
ResetCachedBitmap();
|
||||||
|
|
||||||
|
base.Transform(matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IDrawableContainer"/>
|
||||||
|
public override void Draw(Graphics graphics, RenderMode rm)
|
||||||
|
{
|
||||||
|
if (_cachedImage != null && _cachedImage.Size != Bounds.Size)
|
||||||
|
{
|
||||||
|
ResetCachedBitmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
_cachedImage ??= ComputeBitmap();
|
||||||
|
|
||||||
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
|
||||||
|
|
||||||
|
graphics.DrawImage(_cachedImage, Bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Image ComputeBitmap();
|
||||||
|
|
||||||
|
private void ResetCachedBitmap()
|
||||||
|
{
|
||||||
|
_cachedImage?.Dispose();
|
||||||
|
_cachedImage = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
src/Greenshot.Editor/EditorInitialize.cs
Normal file
50
src/Greenshot.Editor/EditorInitialize.cs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Greenshot.Base.Core;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
|
using Greenshot.Editor.FileFormatHandlers;
|
||||||
|
|
||||||
|
namespace Greenshot.Editor
|
||||||
|
{
|
||||||
|
public static class EditorInitialize
|
||||||
|
{
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
SimpleServiceProvider.Current.AddService<IFileFormatHandler>(
|
||||||
|
// All generic things, like gif, png, jpg etc.
|
||||||
|
new DefaultFileFormatHandler(),
|
||||||
|
// Greenshot format
|
||||||
|
new GreenshotFileFormatHandler(),
|
||||||
|
// For .svg support
|
||||||
|
new SvgFileFormatHandler(),
|
||||||
|
// For clipboard support
|
||||||
|
new DibFileFormatHandler(),
|
||||||
|
// .ico
|
||||||
|
new IconFileFormatHandler(),
|
||||||
|
// EMF & WMF
|
||||||
|
new MetaFileFormatHandler(),
|
||||||
|
// JPG XR
|
||||||
|
new WpfFileFormatHandler()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
|
using Greenshot.Base.Interfaces.Plugin;
|
||||||
|
using Greenshot.Editor.Drawing;
|
||||||
|
|
||||||
|
namespace Greenshot.Editor.FileFormatHandlers
|
||||||
|
{
|
||||||
|
public abstract class AbstractFileFormatHandler : IFileFormatHandler
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IDictionary<FileFormatHandlerActions, IReadOnlyCollection<string>> SupportedExtensions { get; } = new Dictionary<FileFormatHandlerActions, IReadOnlyCollection<string>>();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public virtual int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null);
|
||||||
|
|
||||||
|
public abstract bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default implementation taking the TryLoadFromStream image and placing it in an ImageContainer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">Stream</param>
|
||||||
|
/// <param name="extension">string</param>
|
||||||
|
/// <param name="parent">ISurface</param>
|
||||||
|
/// <returns>IEnumerable{IDrawableContainer}</returns>
|
||||||
|
public virtual IEnumerable<IDrawableContainer> LoadDrawablesFromStream(Stream stream, string extension, ISurface parent = null)
|
||||||
|
{
|
||||||
|
if (TryLoadFromStream(stream, extension, out var bitmap))
|
||||||
|
{
|
||||||
|
var imageContainer = new ImageContainer(parent)
|
||||||
|
{
|
||||||
|
Image = bitmap
|
||||||
|
};
|
||||||
|
yield return imageContainer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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.Interfaces;
|
||||||
|
using Greenshot.Base.Interfaces.Plugin;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
namespace Greenshot.Editor.FileFormatHandlers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This is the default .NET bitmap file format handler
|
||||||
|
/// </summary>
|
||||||
|
public class DefaultFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(DefaultFileFormatHandler));
|
||||||
|
private readonly IReadOnlyCollection<string> _ourExtensions = new[] { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff", ".tif" };
|
||||||
|
public DefaultFileFormatHandler()
|
||||||
|
{
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions;
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.SaveToStream] = _ourExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null)
|
||||||
|
{
|
||||||
|
ImageFormat imageFormat = extension switch
|
||||||
|
{
|
||||||
|
".png" => ImageFormat.Png,
|
||||||
|
".bmp" => ImageFormat.Bmp,
|
||||||
|
".gif" => ImageFormat.Gif,
|
||||||
|
".jpg" => ImageFormat.Jpeg,
|
||||||
|
".jpeg" => ImageFormat.Jpeg,
|
||||||
|
".tiff" => ImageFormat.Tiff,
|
||||||
|
".tif" => ImageFormat.Tiff,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
|
||||||
|
if (imageFormat == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
surfaceOutputSettings ??= new SurfaceOutputSettings();
|
||||||
|
var imageEncoder = ImageCodecInfo.GetImageEncoders().FirstOrDefault(ie => ie.FilenameExtension.ToLowerInvariant().Contains(extension));
|
||||||
|
if (imageEncoder == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
EncoderParameters parameters = new EncoderParameters(1)
|
||||||
|
{
|
||||||
|
Param =
|
||||||
|
{
|
||||||
|
[0] = new EncoderParameter(Encoder.Quality, surfaceOutputSettings.JPGQuality)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// For those images which are with Alpha, but the format doesn't support this, change it to 24bpp
|
||||||
|
if (imageFormat.Guid == ImageFormat.Jpeg.Guid && Image.IsAlphaPixelFormat(bitmap.PixelFormat))
|
||||||
|
{
|
||||||
|
var nonAlphaImage = ImageHelper.Clone(bitmap, PixelFormat.Format24bppRgb) as Bitmap;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Set that this file was written by Greenshot
|
||||||
|
nonAlphaImage.AddTag();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Warn("Couldn't set 'software used' tag on image.", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
nonAlphaImage.Save(destination, imageEncoder, parameters);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error("Couldn't save image: ", ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
nonAlphaImage.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Set that this file was written by Greenshot
|
||||||
|
bitmap.AddTag();
|
||||||
|
bitmap.Save(destination, imageEncoder, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,29 +20,112 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using Greenshot.Base.Core;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
|
using Greenshot.Base.Interfaces.Plugin;
|
||||||
using Greenshot.Base.UnmanagedHelpers;
|
using Greenshot.Base.UnmanagedHelpers;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
namespace Greenshot.Base.Core
|
namespace Greenshot.Editor.FileFormatHandlers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Though Greenshot implements the specs for the DIB image format,
|
/// This handles creating a DIB (Device Independent Bitmap) on the clipboard
|
||||||
/// it seems to cause a lot of issues when using the clipboard.
|
|
||||||
/// There is some research done about the DIB on the clipboard, this code is based upon the information
|
|
||||||
/// <a href="https://stackoverflow.com/questions/44177115/copying-from-and-to-clipboard-loses-image-transparency">here</a>
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static class DibHelper
|
public class DibFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
|
||||||
{
|
{
|
||||||
private const double DpiToPelsPerMeter = 39.3701;
|
private const double DpiToPelsPerMeter = 39.3701;
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(DibFileFormatHandler));
|
||||||
|
|
||||||
|
private readonly IReadOnlyCollection<string> _ourExtensions = new[] { ".dib", ".format17" };
|
||||||
|
|
||||||
|
public DibFileFormatHandler()
|
||||||
|
{
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions;
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.SaveToStream] = _ourExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null)
|
||||||
|
{
|
||||||
|
var dibBytes = ConvertToDib(bitmap);
|
||||||
|
destination.Write(dibBytes, 0, dibBytes.Length);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
|
||||||
|
{
|
||||||
|
byte[] dibBuffer = new byte[stream.Length];
|
||||||
|
_ = stream.Read(dibBuffer, 0, dibBuffer.Length);
|
||||||
|
var infoHeader = BinaryStructHelper.FromByteArray<BITMAPINFOHEADERV5>(dibBuffer);
|
||||||
|
if (!infoHeader.IsDibV5)
|
||||||
|
{
|
||||||
|
Log.InfoFormat("Using special DIB <v5 format reader with biCompression {0}", infoHeader.biCompression);
|
||||||
|
int fileHeaderSize = Marshal.SizeOf(typeof(BITMAPFILEHEADER));
|
||||||
|
uint infoHeaderSize = infoHeader.biSize;
|
||||||
|
int fileSize = (int)(fileHeaderSize + infoHeader.biSize + infoHeader.biSizeImage);
|
||||||
|
|
||||||
|
var fileHeader = new BITMAPFILEHEADER
|
||||||
|
{
|
||||||
|
bfType = BITMAPFILEHEADER.BM,
|
||||||
|
bfSize = fileSize,
|
||||||
|
bfReserved1 = 0,
|
||||||
|
bfReserved2 = 0,
|
||||||
|
bfOffBits = (int)(fileHeaderSize + infoHeaderSize + infoHeader.biClrUsed * 4)
|
||||||
|
};
|
||||||
|
|
||||||
|
byte[] fileHeaderBytes = BinaryStructHelper.ToByteArray(fileHeader);
|
||||||
|
|
||||||
|
using var bitmapStream = new MemoryStream();
|
||||||
|
bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize);
|
||||||
|
bitmapStream.Write(dibBuffer, 0, dibBuffer.Length);
|
||||||
|
bitmapStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
// TODO: Replace with a FileFormatHandler
|
||||||
|
bitmap = ImageIO.FromStream(bitmapStream) as Bitmap;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Log.Info("Using special DIBV5 / Format17 format reader");
|
||||||
|
// CF_DIBV5
|
||||||
|
IntPtr gcHandle = IntPtr.Zero;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GCHandle handle = GCHandle.Alloc(dibBuffer, GCHandleType.Pinned);
|
||||||
|
gcHandle = GCHandle.ToIntPtr(handle);
|
||||||
|
bitmap = new Bitmap(infoHeader.biWidth, infoHeader.biHeight,
|
||||||
|
-(int)(infoHeader.biSizeImage / infoHeader.biHeight),
|
||||||
|
infoHeader.biBitCount == 32 ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb,
|
||||||
|
new IntPtr(handle.AddrOfPinnedObject().ToInt32() + infoHeader.OffsetToPixels +
|
||||||
|
(infoHeader.biHeight - 1) * (int)(infoHeader.biSizeImage / infoHeader.biHeight))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error("Problem retrieving Format17 from clipboard.", ex);
|
||||||
|
bitmap = null;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (gcHandle == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
GCHandle.FromIntPtr(gcHandle).Free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the Bitmap to a Device Independent Bitmap format of type BITFIELDS.
|
/// Converts the Bitmap to a Device Independent Bitmap format of type BITFIELDS.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sourceBitmap">Bitmap to convert to DIB</param>
|
/// <param name="sourceBitmap">Bitmap to convert to DIB</param>
|
||||||
/// <returns>byte{} with the image converted to DIB</returns>
|
/// <returns>byte{} with the image converted to DIB</returns>
|
||||||
public static byte[] ConvertToDib(this Bitmap sourceBitmap)
|
private static byte[] ConvertToDib(Bitmap sourceBitmap)
|
||||||
{
|
{
|
||||||
if (sourceBitmap == null) throw new ArgumentNullException(nameof(sourceBitmap));
|
if (sourceBitmap == null) throw new ArgumentNullException(nameof(sourceBitmap));
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using Greenshot.Base.Core;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
|
using Greenshot.Base.Interfaces.Plugin;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
namespace Greenshot.Editor.FileFormatHandlers
|
||||||
|
{
|
||||||
|
public class GreenshotFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(GreenshotFileFormatHandler));
|
||||||
|
private readonly IReadOnlyCollection<string> _ourExtensions = new [] { ".greenshot" };
|
||||||
|
public GreenshotFileFormatHandler()
|
||||||
|
{
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions;
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.SaveToStream] = _ourExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool TrySaveToStream(Bitmap bitmap, Stream stream, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null)
|
||||||
|
{
|
||||||
|
if (surface == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bitmap.Save(stream, ImageFormat.Png);
|
||||||
|
using MemoryStream tmpStream = new MemoryStream();
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
218
src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs
Normal file
218
src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using Greenshot.Base.Core;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
|
using Greenshot.Base.Interfaces.Plugin;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
namespace Greenshot.Editor.FileFormatHandlers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// THis is the .ico format handler
|
||||||
|
/// </summary>
|
||||||
|
public class IconFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(IconFileFormatHandler));
|
||||||
|
|
||||||
|
private readonly IReadOnlyCollection<string> _ourExtensions = new[] { ".ico" };
|
||||||
|
|
||||||
|
public IconFileFormatHandler()
|
||||||
|
{
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions;
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.SaveToStream] = _ourExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool TrySaveToStream(Bitmap bitmap, Stream stream, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null)
|
||||||
|
{
|
||||||
|
IList<Image> images = new List<Image>
|
||||||
|
{
|
||||||
|
bitmap
|
||||||
|
};
|
||||||
|
|
||||||
|
var binaryWriter = new BinaryWriter(stream);
|
||||||
|
//
|
||||||
|
// ICONDIR structure
|
||||||
|
//
|
||||||
|
binaryWriter.Write((short)0); // reserved
|
||||||
|
binaryWriter.Write((short)1); // image type (icon)
|
||||||
|
binaryWriter.Write((short)images.Count); // number of images
|
||||||
|
|
||||||
|
IList<Size> imageSizes = new List<Size>();
|
||||||
|
IList<MemoryStream> encodedImages = new List<MemoryStream>();
|
||||||
|
foreach (var image in images)
|
||||||
|
{
|
||||||
|
// Pick the best fit
|
||||||
|
var sizes = new[]
|
||||||
|
{
|
||||||
|
16, 32, 48
|
||||||
|
};
|
||||||
|
int size = 256;
|
||||||
|
foreach (var possibleSize in sizes)
|
||||||
|
{
|
||||||
|
if (image.Width <= possibleSize && image.Height <= possibleSize)
|
||||||
|
{
|
||||||
|
size = possibleSize;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var imageStream = new MemoryStream();
|
||||||
|
if (image.Width == size && image.Height == size)
|
||||||
|
{
|
||||||
|
using var clonedImage = ImageHelper.Clone(image, PixelFormat.Format32bppArgb);
|
||||||
|
clonedImage.Save(imageStream, ImageFormat.Png);
|
||||||
|
imageSizes.Add(new Size(size, size));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Resize to the specified size, first make sure the image is 32bpp
|
||||||
|
using var clonedImage = ImageHelper.Clone(image, PixelFormat.Format32bppArgb);
|
||||||
|
using var resizedImage = ImageHelper.ResizeImage(clonedImage, true, true, Color.Empty, size, size, null);
|
||||||
|
resizedImage.Save(imageStream, ImageFormat.Png);
|
||||||
|
imageSizes.Add(resizedImage.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
imageStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
encodedImages.Add(imageStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ICONDIRENTRY structure
|
||||||
|
//
|
||||||
|
const int iconDirSize = 6;
|
||||||
|
const int iconDirEntrySize = 16;
|
||||||
|
|
||||||
|
var offset = iconDirSize + (images.Count * iconDirEntrySize);
|
||||||
|
for (int i = 0; i < images.Count; i++)
|
||||||
|
{
|
||||||
|
var imageSize = imageSizes[i];
|
||||||
|
// Write the width / height, 0 means 256
|
||||||
|
binaryWriter.Write(imageSize.Width == 256 ? (byte)0 : (byte)imageSize.Width);
|
||||||
|
binaryWriter.Write(imageSize.Height == 256 ? (byte)0 : (byte)imageSize.Height);
|
||||||
|
binaryWriter.Write((byte)0); // no pallete
|
||||||
|
binaryWriter.Write((byte)0); // reserved
|
||||||
|
binaryWriter.Write((short)0); // no color planes
|
||||||
|
binaryWriter.Write((short)32); // 32 bpp
|
||||||
|
binaryWriter.Write((int)encodedImages[i].Length); // image data length
|
||||||
|
binaryWriter.Write(offset);
|
||||||
|
offset += (int)encodedImages[i].Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
binaryWriter.Flush();
|
||||||
|
//
|
||||||
|
// Write image data
|
||||||
|
//
|
||||||
|
foreach (var encodedImage in encodedImages)
|
||||||
|
{
|
||||||
|
encodedImage.WriteTo(stream);
|
||||||
|
encodedImage.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement this
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
|
||||||
|
{
|
||||||
|
_ = stream.Seek(0, SeekOrigin.Current);
|
||||||
|
|
||||||
|
// Icon logic, try to get the Vista icon, else the biggest possible
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using Image tmpImage = ExtractVistaIcon(stream);
|
||||||
|
if (tmpImage != null)
|
||||||
|
{
|
||||||
|
bitmap = ImageHelper.Clone(tmpImage, PixelFormat.Format32bppArgb);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception vistaIconException)
|
||||||
|
{
|
||||||
|
Log.Warn("Can't read icon", vistaIconException);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// No vista icon, try normal icon
|
||||||
|
stream.Position = stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
// We create a copy of the bitmap, so everything else can be disposed
|
||||||
|
using Icon tmpIcon = new Icon(stream, new Size(1024, 1024));
|
||||||
|
using Image tmpImage = tmpIcon.ToBitmap();
|
||||||
|
bitmap = ImageHelper.Clone(tmpImage, PixelFormat.Format32bppArgb);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception iconException)
|
||||||
|
{
|
||||||
|
Log.Warn("Can't read icon", iconException);
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Based on: https://www.codeproject.com/KB/cs/IconExtractor.aspx
|
||||||
|
/// And a hint from: https://www.codeproject.com/KB/cs/IconLib.aspx
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="iconStream">Stream with the icon information</param>
|
||||||
|
/// <returns>Bitmap with the Vista Icon (256x256)</returns>
|
||||||
|
private static Bitmap ExtractVistaIcon(Stream iconStream)
|
||||||
|
{
|
||||||
|
const int sizeIconDir = 6;
|
||||||
|
const int sizeIconDirEntry = 16;
|
||||||
|
Bitmap bmpPngExtracted = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] srcBuf = new byte[iconStream.Length];
|
||||||
|
// TODO: Check if there is a need to process the result
|
||||||
|
_ = 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) continue;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using Greenshot.Base.Core;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
|
using Greenshot.Base.Interfaces.Plugin;
|
||||||
|
using Greenshot.Editor.Drawing;
|
||||||
|
|
||||||
|
namespace Greenshot.Editor.FileFormatHandlers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This handles the Windows metafile files
|
||||||
|
/// </summary>
|
||||||
|
public class MetaFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
|
||||||
|
{
|
||||||
|
private readonly IReadOnlyCollection<string> _ourExtensions = new[] { ".wmf", ".emf" };
|
||||||
|
|
||||||
|
public MetaFileFormatHandler()
|
||||||
|
{
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override IEnumerable<IDrawableContainer> LoadDrawablesFromStream(Stream stream, string extension, ISurface surface = null)
|
||||||
|
{
|
||||||
|
if (Image.FromStream(stream, true, true) is Metafile metaFile)
|
||||||
|
{
|
||||||
|
yield return new MetafileContainer(metaFile, surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
|
using Greenshot.Base.Interfaces.Plugin;
|
||||||
|
using Greenshot.Editor.Drawing;
|
||||||
|
using log4net;
|
||||||
|
using Svg;
|
||||||
|
|
||||||
|
namespace Greenshot.Editor.FileFormatHandlers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This handled the loading of SVG images to the editor
|
||||||
|
/// </summary>
|
||||||
|
public class SvgFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(SvgFileFormatHandler));
|
||||||
|
private readonly IReadOnlyCollection<string> _ourExtensions = new[] { ".svg" };
|
||||||
|
|
||||||
|
public SvgFileFormatHandler()
|
||||||
|
{
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;
|
||||||
|
SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
|
||||||
|
{
|
||||||
|
var svgDocument = SvgDocument.Open<SvgDocument>(stream);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bitmap = svgDocument.Draw();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error("Can't load SVG", ex);
|
||||||
|
}
|
||||||
|
bitmap = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null)
|
||||||
|
{
|
||||||
|
// TODO: Implement this
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<IDrawableContainer> LoadDrawablesFromStream(Stream stream, string extension, ISurface parent = null)
|
||||||
|
{
|
||||||
|
SvgDocument svgDocument = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
svgDocument = SvgDocument.Open<SvgDocument>(stream);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error("Can't load SVG", ex);
|
||||||
|
}
|
||||||
|
if (svgDocument != null)
|
||||||
|
{
|
||||||
|
yield return new SvgContainer(svgDocument, parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
144
src/Greenshot.Editor/FileFormatHandlers/WpfFileFormatHandler.cs
Normal file
144
src/Greenshot.Editor/FileFormatHandlers/WpfFileFormatHandler.cs
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This is the System.Windows.Media.Imaging (WPF) file format handler, which uses WIC
|
||||||
|
/// </summary>
|
||||||
|
public class WpfFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger(typeof(WpfFileFormatHandler));
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
surfaceOutputSettings ??= new SurfaceOutputSettings();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var bitmapSource = bitmap.ToBitmapSource();
|
||||||
|
var bitmapFrame = BitmapFrame.Create(bitmapSource);
|
||||||
|
var jpegXrEncoder = new WmpBitmapEncoder();
|
||||||
|
jpegXrEncoder.Frames.Add(bitmapFrame);
|
||||||
|
// TODO: Support supplying a quality
|
||||||
|
jpegXrEncoder.ImageQualityLevel = surfaceOutputSettings.JPGQuality / 100f;
|
||||||
|
jpegXrEncoder.Save(destination);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error("Couldn't save image as JPEG XR: ", ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var bitmapDecoder = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);
|
||||||
|
var bitmapSource = bitmapDecoder.Frames[0];
|
||||||
|
bitmap = bitmapSource.ToBitmap();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error("Couldn't load image: ", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -56,13 +56,13 @@ namespace Greenshot.Editor.Forms
|
||||||
private static readonly ILog Log = LogManager.GetLogger(typeof(ImageEditorForm));
|
private static readonly ILog Log = LogManager.GetLogger(typeof(ImageEditorForm));
|
||||||
private static readonly EditorConfiguration EditorConfiguration = IniConfig.GetIniSection<EditorConfiguration>();
|
private static readonly EditorConfiguration EditorConfiguration = IniConfig.GetIniSection<EditorConfiguration>();
|
||||||
|
|
||||||
private static readonly List<string> IgnoreDestinations = new List<string>
|
private static readonly List<string> IgnoreDestinations = new()
|
||||||
{
|
{
|
||||||
nameof(WellKnownDestinations.Picker),
|
nameof(WellKnownDestinations.Picker),
|
||||||
EditorDestination.DESIGNATION
|
EditorDestination.DESIGNATION
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly List<IImageEditor> EditorList = new List<IImageEditor>();
|
private static readonly List<IImageEditor> EditorList = new();
|
||||||
|
|
||||||
private Surface _surface;
|
private Surface _surface;
|
||||||
private GreenshotToolStripButton[] _toolbarButtons;
|
private GreenshotToolStripButton[] _toolbarButtons;
|
||||||
|
@ -78,7 +78,7 @@ namespace Greenshot.Editor.Forms
|
||||||
// whether part of the editor controls are disabled depending on selected item(s)
|
// whether part of the editor controls are disabled depending on selected item(s)
|
||||||
private bool _controlsDisabledDueToConfirmable;
|
private bool _controlsDisabledDueToConfirmable;
|
||||||
|
|
||||||
// Used for tracking the mouse scrollwheel changes
|
// Used for tracking the mouse scroll wheel changes
|
||||||
private DateTime _zoomStartTime = DateTime.Now;
|
private DateTime _zoomStartTime = DateTime.Now;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -181,6 +181,20 @@ namespace Greenshot.Editor.Forms
|
||||||
|
|
||||||
UpdateUi();
|
UpdateUi();
|
||||||
|
|
||||||
|
// Use best fit, for those capture modes where we can get huge images
|
||||||
|
bool useBestFit = _surface.CaptureDetails.CaptureMode switch
|
||||||
|
{
|
||||||
|
CaptureMode.File => true,
|
||||||
|
CaptureMode.Clipboard => true,
|
||||||
|
CaptureMode.IE => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (useBestFit)
|
||||||
|
{
|
||||||
|
ZoomBestFitMenuItemClick(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
// Workaround: As the cursor is (mostly) selected on the surface a funny artifact is visible, this fixes it.
|
// Workaround: As the cursor is (mostly) selected on the surface a funny artifact is visible, this fixes it.
|
||||||
HideToolstripItems();
|
HideToolstripItems();
|
||||||
}
|
}
|
||||||
|
@ -1290,7 +1304,7 @@ namespace Greenshot.Editor.Forms
|
||||||
propertiesToolStrip.SuspendLayout();
|
propertiesToolStrip.SuspendLayout();
|
||||||
if (_surface.HasSelectedElements || _surface.DrawingMode != DrawingModes.None)
|
if (_surface.HasSelectedElements || _surface.DrawingMode != DrawingModes.None)
|
||||||
{
|
{
|
||||||
FieldAggregator props = _surface.FieldAggregator;
|
var props = (FieldAggregator)_surface.FieldAggregator;
|
||||||
btnFillColor.Visible = props.HasFieldValue(FieldType.FILL_COLOR);
|
btnFillColor.Visible = props.HasFieldValue(FieldType.FILL_COLOR);
|
||||||
btnLineColor.Visible = props.HasFieldValue(FieldType.LINE_COLOR);
|
btnLineColor.Visible = props.HasFieldValue(FieldType.LINE_COLOR);
|
||||||
lineThicknessLabel.Visible = lineThicknessUpDown.Visible = props.HasFieldValue(FieldType.LINE_THICKNESS);
|
lineThicknessLabel.Visible = lineThicknessUpDown.Visible = props.HasFieldValue(FieldType.LINE_THICKNESS);
|
||||||
|
@ -1350,7 +1364,7 @@ namespace Greenshot.Editor.Forms
|
||||||
btnStepLabel.Image = icon;
|
btnStepLabel.Image = icon;
|
||||||
addCounterToolStripMenuItem.Image = icon;
|
addCounterToolStripMenuItem.Image = icon;
|
||||||
|
|
||||||
FieldAggregator props = _surface.FieldAggregator;
|
FieldAggregator props = (FieldAggregator)_surface.FieldAggregator;
|
||||||
// if a confirmable element is selected, we must disable most of the controls
|
// if a confirmable element is selected, we must disable most of the controls
|
||||||
// since we demand confirmation or cancel for confirmable element
|
// since we demand confirmation or cancel for confirmable element
|
||||||
if (props.HasFieldValue(FieldType.FLAGS) && ((FieldFlag) props.GetFieldValue(FieldType.FLAGS) & FieldFlag.CONFIRMABLE) == FieldFlag.CONFIRMABLE)
|
if (props.HasFieldValue(FieldType.FLAGS) && ((FieldFlag) props.GetFieldValue(FieldType.FLAGS) & FieldFlag.CONFIRMABLE) == FieldFlag.CONFIRMABLE)
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||||
|
<PropertyGroup>
|
||||||
|
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Languages\language*.xml">
|
<None Include="Languages\language*.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
|
|
@ -20,9 +20,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing;
|
|
||||||
|
|
||||||
namespace Greenshot.Editor.Memento
|
namespace Greenshot.Editor.Memento
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -31,9 +30,9 @@ namespace Greenshot.Editor.Memento
|
||||||
public class AddElementMemento : IMemento
|
public class AddElementMemento : IMemento
|
||||||
{
|
{
|
||||||
private IDrawableContainer _drawableContainer;
|
private IDrawableContainer _drawableContainer;
|
||||||
private Surface _surface;
|
private ISurface _surface;
|
||||||
|
|
||||||
public AddElementMemento(Surface surface, IDrawableContainer drawableContainer)
|
public AddElementMemento(ISurface surface, IDrawableContainer drawableContainer)
|
||||||
{
|
{
|
||||||
_surface = surface;
|
_surface = surface;
|
||||||
_drawableContainer = drawableContainer;
|
_drawableContainer = drawableContainer;
|
||||||
|
|
|
@ -19,8 +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.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing;
|
|
||||||
|
|
||||||
namespace Greenshot.Editor.Memento
|
namespace Greenshot.Editor.Memento
|
||||||
{
|
{
|
||||||
|
@ -30,9 +30,9 @@ namespace Greenshot.Editor.Memento
|
||||||
public class AddElementsMemento : IMemento
|
public class AddElementsMemento : IMemento
|
||||||
{
|
{
|
||||||
private IDrawableContainerList _containerList;
|
private IDrawableContainerList _containerList;
|
||||||
private Surface _surface;
|
private ISurface _surface;
|
||||||
|
|
||||||
public AddElementsMemento(Surface surface, IDrawableContainerList containerList)
|
public AddElementsMemento(ISurface surface, IDrawableContainerList containerList)
|
||||||
{
|
{
|
||||||
_surface = surface;
|
_surface = surface;
|
||||||
_containerList = containerList;
|
_containerList = containerList;
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing;
|
|
||||||
|
|
||||||
namespace Greenshot.Editor.Memento
|
namespace Greenshot.Editor.Memento
|
||||||
{
|
{
|
||||||
|
@ -31,9 +31,9 @@ namespace Greenshot.Editor.Memento
|
||||||
public class DeleteElementMemento : IMemento
|
public class DeleteElementMemento : IMemento
|
||||||
{
|
{
|
||||||
private IDrawableContainer _drawableContainer;
|
private IDrawableContainer _drawableContainer;
|
||||||
private readonly Surface _surface;
|
private readonly ISurface _surface;
|
||||||
|
|
||||||
public DeleteElementMemento(Surface surface, IDrawableContainer drawableContainer)
|
public DeleteElementMemento(ISurface surface, IDrawableContainer drawableContainer)
|
||||||
{
|
{
|
||||||
_surface = surface;
|
_surface = surface;
|
||||||
_drawableContainer = drawableContainer;
|
_drawableContainer = drawableContainer;
|
||||||
|
|
|
@ -19,8 +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.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing;
|
|
||||||
|
|
||||||
namespace Greenshot.Editor.Memento
|
namespace Greenshot.Editor.Memento
|
||||||
{
|
{
|
||||||
|
@ -30,9 +30,9 @@ namespace Greenshot.Editor.Memento
|
||||||
public class DeleteElementsMemento : IMemento
|
public class DeleteElementsMemento : IMemento
|
||||||
{
|
{
|
||||||
private IDrawableContainerList _containerList;
|
private IDrawableContainerList _containerList;
|
||||||
private Surface _surface;
|
private ISurface _surface;
|
||||||
|
|
||||||
public DeleteElementsMemento(Surface surface, IDrawableContainerList containerList)
|
public DeleteElementsMemento(ISurface surface, IDrawableContainerList containerList)
|
||||||
{
|
{
|
||||||
_surface = surface;
|
_surface = surface;
|
||||||
_containerList = containerList;
|
_containerList = containerList;
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
|
using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Drawing;
|
|
||||||
|
|
||||||
namespace Greenshot.Editor.Memento
|
namespace Greenshot.Editor.Memento
|
||||||
{
|
{
|
||||||
|
@ -32,10 +32,10 @@ namespace Greenshot.Editor.Memento
|
||||||
public class SurfaceBackgroundChangeMemento : IMemento
|
public class SurfaceBackgroundChangeMemento : IMemento
|
||||||
{
|
{
|
||||||
private Image _image;
|
private Image _image;
|
||||||
private Surface _surface;
|
private ISurface _surface;
|
||||||
private Matrix _matrix;
|
private Matrix _matrix;
|
||||||
|
|
||||||
public SurfaceBackgroundChangeMemento(Surface surface, Matrix matrix)
|
public SurfaceBackgroundChangeMemento(ISurface surface, Matrix matrix)
|
||||||
{
|
{
|
||||||
_surface = surface;
|
_surface = surface;
|
||||||
_image = surface.Image;
|
_image = surface.Image;
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace Greenshot.Plugin.Box.Forms {
|
||||||
this.combobox_uploadimageformat.FormattingEnabled = true;
|
this.combobox_uploadimageformat.FormattingEnabled = true;
|
||||||
this.combobox_uploadimageformat.Location = new System.Drawing.Point(208, 12);
|
this.combobox_uploadimageformat.Location = new System.Drawing.Point(208, 12);
|
||||||
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
||||||
this.combobox_uploadimageformat.PropertyName = "UploadFormat";
|
this.combobox_uploadimageformat.PropertyName = nameof(BoxConfiguration.UploadFormat);
|
||||||
this.combobox_uploadimageformat.SectionName = "Box";
|
this.combobox_uploadimageformat.SectionName = "Box";
|
||||||
this.combobox_uploadimageformat.Size = new System.Drawing.Size(215, 21);
|
this.combobox_uploadimageformat.Size = new System.Drawing.Size(215, 21);
|
||||||
this.combobox_uploadimageformat.TabIndex = 5;
|
this.combobox_uploadimageformat.TabIndex = 5;
|
||||||
|
@ -115,7 +115,7 @@ namespace Greenshot.Plugin.Box.Forms {
|
||||||
this.checkboxAfterUploadLinkToClipBoard.LanguageKey = "box.label_AfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.LanguageKey = "box.label_AfterUploadLinkToClipBoard";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Location = new System.Drawing.Point(208, 45);
|
this.checkboxAfterUploadLinkToClipBoard.Location = new System.Drawing.Point(208, 45);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Name = "checkboxAfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.Name = "checkboxAfterUploadLinkToClipBoard";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.PropertyName = "AfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.PropertyName = nameof(BoxConfiguration.AfterUploadLinkToClipBoard);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.SectionName = "Box";
|
this.checkboxAfterUploadLinkToClipBoard.SectionName = "Box";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Size = new System.Drawing.Size(104, 17);
|
this.checkboxAfterUploadLinkToClipBoard.Size = new System.Drawing.Size(104, 17);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.TabIndex = 10;
|
this.checkboxAfterUploadLinkToClipBoard.TabIndex = 10;
|
||||||
|
|
|
@ -54,8 +54,8 @@ namespace Greenshot.Plugin.Confluence
|
||||||
Uri confluenceIconUri = new Uri("/Greenshot.Plugin.Confluence;component/Images/Confluence.ico", UriKind.Relative);
|
Uri confluenceIconUri = new Uri("/Greenshot.Plugin.Confluence;component/Images/Confluence.ico", UriKind.Relative);
|
||||||
using (Stream iconStream = Application.GetResourceStream(confluenceIconUri)?.Stream)
|
using (Stream iconStream = Application.GetResourceStream(confluenceIconUri)?.Stream)
|
||||||
{
|
{
|
||||||
// TODO: Check what to do with the IImage
|
// TODO: Replace with FileFormatHandler
|
||||||
ConfluenceIcon = ImageHelper.FromStream(iconStream);
|
ConfluenceIcon = ImageIO.FromStream(iconStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
IsInitialized = true;
|
IsInitialized = true;
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Greenshot.Base.Core;
|
|
||||||
using Greenshot.Base.Core.Enums;
|
using Greenshot.Base.Core.Enums;
|
||||||
using Greenshot.Base.IniFile;
|
using Greenshot.Base.IniFile;
|
||||||
using Greenshot.Plugin.Dropbox.Forms;
|
using Greenshot.Plugin.Dropbox.Forms;
|
||||||
|
@ -29,10 +28,10 @@ using Greenshot.Plugin.Dropbox.Forms;
|
||||||
namespace Greenshot.Plugin.Dropbox
|
namespace Greenshot.Plugin.Dropbox
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of ImgurConfiguration.
|
/// The configuration for Dropbox
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IniSection("Dropbox", Description = "Greenshot Dropbox Plugin configuration")]
|
[IniSection("Dropbox", Description = "Greenshot Dropbox Plugin configuration")]
|
||||||
public class DropboxPluginConfiguration : IniSection
|
public class DropboxConfiguration : IniSection
|
||||||
{
|
{
|
||||||
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
||||||
public OutputFormat UploadFormat { get; set; }
|
public OutputFormat UploadFormat { get; set; }
|
|
@ -29,7 +29,7 @@ namespace Greenshot.Plugin.Dropbox
|
||||||
{
|
{
|
||||||
internal class DropboxDestination : AbstractDestination
|
internal class DropboxDestination : AbstractDestination
|
||||||
{
|
{
|
||||||
private static readonly DropboxPluginConfiguration DropboxConfig = IniConfig.GetIniSection<DropboxPluginConfiguration>();
|
private static readonly DropboxConfiguration DropboxConfig = IniConfig.GetIniSection<DropboxConfiguration>();
|
||||||
|
|
||||||
private readonly DropboxPlugin _plugin;
|
private readonly DropboxPlugin _plugin;
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace Greenshot.Plugin.Dropbox
|
||||||
public class DropboxPlugin : IGreenshotPlugin
|
public class DropboxPlugin : IGreenshotPlugin
|
||||||
{
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(DropboxPlugin));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(DropboxPlugin));
|
||||||
private static DropboxPluginConfiguration _config;
|
private static DropboxConfiguration _config;
|
||||||
private ComponentResourceManager _resources;
|
private ComponentResourceManager _resources;
|
||||||
private ToolStripMenuItem _itemPlugInConfig;
|
private ToolStripMenuItem _itemPlugInConfig;
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ namespace Greenshot.Plugin.Dropbox
|
||||||
public bool Initialize()
|
public bool Initialize()
|
||||||
{
|
{
|
||||||
// Register configuration (don't need the configuration itself)
|
// Register configuration (don't need the configuration itself)
|
||||||
_config = IniConfig.GetIniSection<DropboxPluginConfiguration>();
|
_config = IniConfig.GetIniSection<DropboxConfiguration>();
|
||||||
_resources = new ComponentResourceManager(typeof(DropboxPlugin));
|
_resources = new ComponentResourceManager(typeof(DropboxPlugin));
|
||||||
SimpleServiceProvider.Current.AddService<IDestination>(new DropboxDestination(this));
|
SimpleServiceProvider.Current.AddService<IDestination>(new DropboxDestination(this));
|
||||||
_itemPlugInConfig = new ToolStripMenuItem
|
_itemPlugInConfig = new ToolStripMenuItem
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace Greenshot.Plugin.Dropbox
|
||||||
public class DropboxUtils
|
public class DropboxUtils
|
||||||
{
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(DropboxUtils));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(DropboxUtils));
|
||||||
private static readonly DropboxPluginConfiguration DropboxConfig = IniConfig.GetIniSection<DropboxPluginConfiguration>();
|
private static readonly DropboxConfiguration DropboxConfig = IniConfig.GetIniSection<DropboxConfiguration>();
|
||||||
|
|
||||||
private DropboxUtils()
|
private DropboxUtils()
|
||||||
{
|
{
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace Greenshot.Plugin.Dropbox.Forms {
|
||||||
this.combobox_uploadimageformat.FormattingEnabled = true;
|
this.combobox_uploadimageformat.FormattingEnabled = true;
|
||||||
this.combobox_uploadimageformat.Location = new System.Drawing.Point(116, 9);
|
this.combobox_uploadimageformat.Location = new System.Drawing.Point(116, 9);
|
||||||
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
||||||
this.combobox_uploadimageformat.PropertyName = "UploadFormat";
|
this.combobox_uploadimageformat.PropertyName = nameof(DropboxConfiguration.UploadFormat);
|
||||||
this.combobox_uploadimageformat.SectionName = "Dropbox";
|
this.combobox_uploadimageformat.SectionName = "Dropbox";
|
||||||
this.combobox_uploadimageformat.Size = new System.Drawing.Size(309, 21);
|
this.combobox_uploadimageformat.Size = new System.Drawing.Size(309, 21);
|
||||||
this.combobox_uploadimageformat.TabIndex = 1;
|
this.combobox_uploadimageformat.TabIndex = 1;
|
||||||
|
@ -112,7 +112,7 @@ namespace Greenshot.Plugin.Dropbox.Forms {
|
||||||
this.checkboxAfterUploadLinkToClipBoard.LanguageKey = "dropbox.label_AfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.LanguageKey = "dropbox.label_AfterUploadLinkToClipBoard";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Location = new System.Drawing.Point(116, 37);
|
this.checkboxAfterUploadLinkToClipBoard.Location = new System.Drawing.Point(116, 37);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Name = "checkboxAfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.Name = "checkboxAfterUploadLinkToClipBoard";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.PropertyName = "AfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.PropertyName = nameof(DropboxConfiguration.AfterUploadLinkToClipBoard);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.SectionName = "Dropbox";
|
this.checkboxAfterUploadLinkToClipBoard.SectionName = "Dropbox";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Size = new System.Drawing.Size(104, 17);
|
this.checkboxAfterUploadLinkToClipBoard.Size = new System.Drawing.Size(104, 17);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.TabIndex = 2;
|
this.checkboxAfterUploadLinkToClipBoard.TabIndex = 2;
|
||||||
|
|
|
@ -77,7 +77,7 @@ namespace Greenshot.Plugin.ExternalCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
bool runInBackground = config.RunInbackground[_presetCommand];
|
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 output;
|
||||||
string error;
|
string error;
|
||||||
|
|
|
@ -93,7 +93,7 @@ namespace Greenshot.Plugin.Flickr.Forms {
|
||||||
this.combobox_uploadimageformat.FormattingEnabled = true;
|
this.combobox_uploadimageformat.FormattingEnabled = true;
|
||||||
this.combobox_uploadimageformat.Location = new System.Drawing.Point(174, 6);
|
this.combobox_uploadimageformat.Location = new System.Drawing.Point(174, 6);
|
||||||
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
||||||
this.combobox_uploadimageformat.PropertyName = "UploadFormat";
|
this.combobox_uploadimageformat.PropertyName = nameof(FlickrConfiguration.UploadFormat);
|
||||||
this.combobox_uploadimageformat.SectionName = "Flickr";
|
this.combobox_uploadimageformat.SectionName = "Flickr";
|
||||||
this.combobox_uploadimageformat.Size = new System.Drawing.Size(251, 21);
|
this.combobox_uploadimageformat.Size = new System.Drawing.Size(251, 21);
|
||||||
this.combobox_uploadimageformat.TabIndex = 1;
|
this.combobox_uploadimageformat.TabIndex = 1;
|
||||||
|
@ -111,7 +111,7 @@ namespace Greenshot.Plugin.Flickr.Forms {
|
||||||
this.checkBoxPublic.LanguageKey = "flickr.public";
|
this.checkBoxPublic.LanguageKey = "flickr.public";
|
||||||
this.checkBoxPublic.Location = new System.Drawing.Point(174, 88);
|
this.checkBoxPublic.Location = new System.Drawing.Point(174, 88);
|
||||||
this.checkBoxPublic.Name = "checkBoxPublic";
|
this.checkBoxPublic.Name = "checkBoxPublic";
|
||||||
this.checkBoxPublic.PropertyName = "flickrIsPublic";
|
this.checkBoxPublic.PropertyName = nameof(FlickrConfiguration.IsPublic);
|
||||||
this.checkBoxPublic.SectionName = "Flickr";
|
this.checkBoxPublic.SectionName = "Flickr";
|
||||||
this.checkBoxPublic.Size = new System.Drawing.Size(55, 17);
|
this.checkBoxPublic.Size = new System.Drawing.Size(55, 17);
|
||||||
this.checkBoxPublic.TabIndex = 4;
|
this.checkBoxPublic.TabIndex = 4;
|
||||||
|
@ -122,7 +122,7 @@ namespace Greenshot.Plugin.Flickr.Forms {
|
||||||
this.checkBoxFamily.LanguageKey = "flickr.family";
|
this.checkBoxFamily.LanguageKey = "flickr.family";
|
||||||
this.checkBoxFamily.Location = new System.Drawing.Point(265, 88);
|
this.checkBoxFamily.Location = new System.Drawing.Point(265, 88);
|
||||||
this.checkBoxFamily.Name = "checkBoxFamily";
|
this.checkBoxFamily.Name = "checkBoxFamily";
|
||||||
this.checkBoxFamily.PropertyName = "flickrIsFamily";
|
this.checkBoxFamily.PropertyName = nameof(FlickrConfiguration.IsFamily);
|
||||||
this.checkBoxFamily.SectionName = "Flickr";
|
this.checkBoxFamily.SectionName = "Flickr";
|
||||||
this.checkBoxFamily.Size = new System.Drawing.Size(55, 17);
|
this.checkBoxFamily.Size = new System.Drawing.Size(55, 17);
|
||||||
this.checkBoxFamily.TabIndex = 5;
|
this.checkBoxFamily.TabIndex = 5;
|
||||||
|
@ -133,7 +133,7 @@ namespace Greenshot.Plugin.Flickr.Forms {
|
||||||
this.checkBoxFriend.LanguageKey = "flickr.friend";
|
this.checkBoxFriend.LanguageKey = "flickr.friend";
|
||||||
this.checkBoxFriend.Location = new System.Drawing.Point(350, 88);
|
this.checkBoxFriend.Location = new System.Drawing.Point(350, 88);
|
||||||
this.checkBoxFriend.Name = "checkBoxFriend";
|
this.checkBoxFriend.Name = "checkBoxFriend";
|
||||||
this.checkBoxFriend.PropertyName = "flickrIsFriend";
|
this.checkBoxFriend.PropertyName = nameof(FlickrConfiguration.IsFriend);
|
||||||
this.checkBoxFriend.SectionName = "Flickr";
|
this.checkBoxFriend.SectionName = "Flickr";
|
||||||
this.checkBoxFriend.Size = new System.Drawing.Size(55, 17);
|
this.checkBoxFriend.Size = new System.Drawing.Size(55, 17);
|
||||||
this.checkBoxFriend.TabIndex = 6;
|
this.checkBoxFriend.TabIndex = 6;
|
||||||
|
@ -155,7 +155,7 @@ namespace Greenshot.Plugin.Flickr.Forms {
|
||||||
this.combobox_safetyLevel.FormattingEnabled = true;
|
this.combobox_safetyLevel.FormattingEnabled = true;
|
||||||
this.combobox_safetyLevel.Location = new System.Drawing.Point(174, 33);
|
this.combobox_safetyLevel.Location = new System.Drawing.Point(174, 33);
|
||||||
this.combobox_safetyLevel.Name = "combobox_safetyLevel";
|
this.combobox_safetyLevel.Name = "combobox_safetyLevel";
|
||||||
this.combobox_safetyLevel.PropertyName = "SafetyLevel";
|
this.combobox_safetyLevel.PropertyName = nameof(FlickrConfiguration.SafetyLevel);
|
||||||
this.combobox_safetyLevel.SectionName = "Flickr";
|
this.combobox_safetyLevel.SectionName = "Flickr";
|
||||||
this.combobox_safetyLevel.Size = new System.Drawing.Size(251, 21);
|
this.combobox_safetyLevel.Size = new System.Drawing.Size(251, 21);
|
||||||
this.combobox_safetyLevel.TabIndex = 2;
|
this.combobox_safetyLevel.TabIndex = 2;
|
||||||
|
@ -173,7 +173,7 @@ namespace Greenshot.Plugin.Flickr.Forms {
|
||||||
this.checkboxAfterUploadLinkToClipBoard.LanguageKey = "flickr.label_AfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.LanguageKey = "flickr.label_AfterUploadLinkToClipBoard";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Location = new System.Drawing.Point(173, 116);
|
this.checkboxAfterUploadLinkToClipBoard.Location = new System.Drawing.Point(173, 116);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Name = "checkboxAfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.Name = "checkboxAfterUploadLinkToClipBoard";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.PropertyName = "AfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.PropertyName = nameof(FlickrConfiguration.AfterUploadLinkToClipBoard);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.SectionName = "Flickr";
|
this.checkboxAfterUploadLinkToClipBoard.SectionName = "Flickr";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Size = new System.Drawing.Size(104, 17);
|
this.checkboxAfterUploadLinkToClipBoard.Size = new System.Drawing.Size(104, 17);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.TabIndex = 7;
|
this.checkboxAfterUploadLinkToClipBoard.TabIndex = 7;
|
||||||
|
@ -184,7 +184,7 @@ namespace Greenshot.Plugin.Flickr.Forms {
|
||||||
this.checkBox_hiddenfromsearch.LanguageKey = "flickr.label_HiddenFromSearch";
|
this.checkBox_hiddenfromsearch.LanguageKey = "flickr.label_HiddenFromSearch";
|
||||||
this.checkBox_hiddenfromsearch.Location = new System.Drawing.Point(174, 60);
|
this.checkBox_hiddenfromsearch.Location = new System.Drawing.Point(174, 60);
|
||||||
this.checkBox_hiddenfromsearch.Name = "checkBox_hiddenfromsearch";
|
this.checkBox_hiddenfromsearch.Name = "checkBox_hiddenfromsearch";
|
||||||
this.checkBox_hiddenfromsearch.PropertyName = "HiddenFromSearch";
|
this.checkBox_hiddenfromsearch.PropertyName = nameof(FlickrConfiguration.HiddenFromSearch);
|
||||||
this.checkBox_hiddenfromsearch.SectionName = "Flickr";
|
this.checkBox_hiddenfromsearch.SectionName = "Flickr";
|
||||||
this.checkBox_hiddenfromsearch.Size = new System.Drawing.Size(118, 17);
|
this.checkBox_hiddenfromsearch.Size = new System.Drawing.Size(118, 17);
|
||||||
this.checkBox_hiddenfromsearch.TabIndex = 3;
|
this.checkBox_hiddenfromsearch.TabIndex = 3;
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace Greenshot.Plugin.GooglePhotos.Forms {
|
||||||
this.combobox_uploadimageformat.FormattingEnabled = true;
|
this.combobox_uploadimageformat.FormattingEnabled = true;
|
||||||
this.combobox_uploadimageformat.Location = new System.Drawing.Point(197, 12);
|
this.combobox_uploadimageformat.Location = new System.Drawing.Point(197, 12);
|
||||||
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
||||||
this.combobox_uploadimageformat.PropertyName = "UploadFormat";
|
this.combobox_uploadimageformat.PropertyName = nameof(GooglePhotosConfiguration.UploadFormat);
|
||||||
this.combobox_uploadimageformat.SectionName = "GooglePhotos";
|
this.combobox_uploadimageformat.SectionName = "GooglePhotos";
|
||||||
this.combobox_uploadimageformat.Size = new System.Drawing.Size(225, 21);
|
this.combobox_uploadimageformat.Size = new System.Drawing.Size(225, 21);
|
||||||
this.combobox_uploadimageformat.TabIndex = 1;
|
this.combobox_uploadimageformat.TabIndex = 1;
|
||||||
|
@ -114,7 +114,7 @@ namespace Greenshot.Plugin.GooglePhotos.Forms {
|
||||||
this.checkboxAfterUploadLinkToClipBoard.LanguageKey = "googlephotos.label_AfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.LanguageKey = "googlephotos.label_AfterUploadLinkToClipBoard";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Location = new System.Drawing.Point(197, 50);
|
this.checkboxAfterUploadLinkToClipBoard.Location = new System.Drawing.Point(197, 50);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Name = "checkboxAfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.Name = "checkboxAfterUploadLinkToClipBoard";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.PropertyName = "AfterUploadLinkToClipBoard";
|
this.checkboxAfterUploadLinkToClipBoard.PropertyName = nameof(GooglePhotosConfiguration.AfterUploadLinkToClipBoard);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.SectionName = "GooglePhotos";
|
this.checkboxAfterUploadLinkToClipBoard.SectionName = "GooglePhotos";
|
||||||
this.checkboxAfterUploadLinkToClipBoard.Size = new System.Drawing.Size(104, 17);
|
this.checkboxAfterUploadLinkToClipBoard.Size = new System.Drawing.Size(104, 17);
|
||||||
this.checkboxAfterUploadLinkToClipBoard.TabIndex = 2;
|
this.checkboxAfterUploadLinkToClipBoard.TabIndex = 2;
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace Greenshot.Plugin.Imgur.Forms {
|
||||||
this.combobox_uploadimageformat.FormattingEnabled = true;
|
this.combobox_uploadimageformat.FormattingEnabled = true;
|
||||||
this.combobox_uploadimageformat.Location = new System.Drawing.Point(168, 7);
|
this.combobox_uploadimageformat.Location = new System.Drawing.Point(168, 7);
|
||||||
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
||||||
this.combobox_uploadimageformat.PropertyName = "UploadFormat";
|
this.combobox_uploadimageformat.PropertyName = nameof(ImgurConfiguration.UploadFormat);
|
||||||
this.combobox_uploadimageformat.SectionName = "Imgur";
|
this.combobox_uploadimageformat.SectionName = "Imgur";
|
||||||
this.combobox_uploadimageformat.Size = new System.Drawing.Size(210, 21);
|
this.combobox_uploadimageformat.Size = new System.Drawing.Size(210, 21);
|
||||||
this.combobox_uploadimageformat.TabIndex = 1;
|
this.combobox_uploadimageformat.TabIndex = 1;
|
||||||
|
@ -115,7 +115,7 @@ namespace Greenshot.Plugin.Imgur.Forms {
|
||||||
this.checkbox_anonymous_access.LanguageKey = "imgur.anonymous_access";
|
this.checkbox_anonymous_access.LanguageKey = "imgur.anonymous_access";
|
||||||
this.checkbox_anonymous_access.Location = new System.Drawing.Point(15, 38);
|
this.checkbox_anonymous_access.Location = new System.Drawing.Point(15, 38);
|
||||||
this.checkbox_anonymous_access.Name = "checkbox_anonymous_access";
|
this.checkbox_anonymous_access.Name = "checkbox_anonymous_access";
|
||||||
this.checkbox_anonymous_access.PropertyName = "AnonymousAccess";
|
this.checkbox_anonymous_access.PropertyName = nameof(ImgurConfiguration.AnonymousAccess);
|
||||||
this.checkbox_anonymous_access.SectionName = "Imgur";
|
this.checkbox_anonymous_access.SectionName = "Imgur";
|
||||||
this.checkbox_anonymous_access.Size = new System.Drawing.Size(139, 17);
|
this.checkbox_anonymous_access.Size = new System.Drawing.Size(139, 17);
|
||||||
this.checkbox_anonymous_access.TabIndex = 2;
|
this.checkbox_anonymous_access.TabIndex = 2;
|
||||||
|
@ -126,7 +126,7 @@ namespace Greenshot.Plugin.Imgur.Forms {
|
||||||
this.checkbox_usepagelink.LanguageKey = "imgur.use_page_link";
|
this.checkbox_usepagelink.LanguageKey = "imgur.use_page_link";
|
||||||
this.checkbox_usepagelink.Location = new System.Drawing.Point(15, 57);
|
this.checkbox_usepagelink.Location = new System.Drawing.Point(15, 57);
|
||||||
this.checkbox_usepagelink.Name = "checkbox_usepagelink";
|
this.checkbox_usepagelink.Name = "checkbox_usepagelink";
|
||||||
this.checkbox_usepagelink.PropertyName = "UsePageLink";
|
this.checkbox_usepagelink.PropertyName = nameof(ImgurConfiguration.UsePageLink);
|
||||||
this.checkbox_usepagelink.SectionName = "Imgur";
|
this.checkbox_usepagelink.SectionName = "Imgur";
|
||||||
this.checkbox_usepagelink.Size = new System.Drawing.Size(251, 17);
|
this.checkbox_usepagelink.Size = new System.Drawing.Size(251, 17);
|
||||||
this.checkbox_usepagelink.TabIndex = 3;
|
this.checkbox_usepagelink.TabIndex = 3;
|
||||||
|
|
|
@ -179,7 +179,7 @@ namespace Greenshot.Plugin.Imgur
|
||||||
{
|
{
|
||||||
using (var requestStream = webRequest.GetRequestStream())
|
using (var requestStream = webRequest.GetRequestStream())
|
||||||
{
|
{
|
||||||
ImageOutput.SaveToStream(surfaceToUpload, requestStream, outputSettings);
|
ImageIO.SaveToStream(surfaceToUpload, requestStream, outputSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
using WebResponse response = webRequest.GetResponse();
|
using WebResponse response = webRequest.GetResponse();
|
||||||
|
@ -265,7 +265,8 @@ namespace Greenshot.Plugin.Imgur
|
||||||
Stream responseStream = response.GetResponseStream();
|
Stream responseStream = response.GetResponseStream();
|
||||||
if (responseStream != null)
|
if (responseStream != null)
|
||||||
{
|
{
|
||||||
imgurInfo.Image = ImageHelper.FromStream(responseStream);
|
// TODO: Replace with some other code, like the file format handler
|
||||||
|
imgurInfo.Image = ImageIO.FromStream(responseStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ namespace Greenshot.Plugin.Jira.Forms {
|
||||||
this.textBoxUrl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
this.textBoxUrl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.textBoxUrl.Location = new System.Drawing.Point(164, 21);
|
this.textBoxUrl.Location = new System.Drawing.Point(164, 21);
|
||||||
this.textBoxUrl.Name = "textBoxUrl";
|
this.textBoxUrl.Name = "textBoxUrl";
|
||||||
this.textBoxUrl.PropertyName = "Url";
|
this.textBoxUrl.PropertyName = nameof(JiraConfiguration.Url);
|
||||||
this.textBoxUrl.SectionName = "Jira";
|
this.textBoxUrl.SectionName = "Jira";
|
||||||
this.textBoxUrl.Size = new System.Drawing.Size(214, 20);
|
this.textBoxUrl.Size = new System.Drawing.Size(214, 20);
|
||||||
this.textBoxUrl.TabIndex = 6;
|
this.textBoxUrl.TabIndex = 6;
|
||||||
|
@ -105,7 +105,7 @@ namespace Greenshot.Plugin.Jira.Forms {
|
||||||
this.combobox_uploadimageformat.FormattingEnabled = true;
|
this.combobox_uploadimageformat.FormattingEnabled = true;
|
||||||
this.combobox_uploadimageformat.Location = new System.Drawing.Point(164, 47);
|
this.combobox_uploadimageformat.Location = new System.Drawing.Point(164, 47);
|
||||||
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
||||||
this.combobox_uploadimageformat.PropertyName = "UploadFormat";
|
this.combobox_uploadimageformat.PropertyName = nameof(JiraConfiguration.UploadFormat);
|
||||||
this.combobox_uploadimageformat.SectionName = "Jira";
|
this.combobox_uploadimageformat.SectionName = "Jira";
|
||||||
this.combobox_uploadimageformat.Size = new System.Drawing.Size(214, 21);
|
this.combobox_uploadimageformat.Size = new System.Drawing.Size(214, 21);
|
||||||
this.combobox_uploadimageformat.TabIndex = 8;
|
this.combobox_uploadimageformat.TabIndex = 8;
|
||||||
|
|
|
@ -89,7 +89,7 @@ namespace Greenshot.Plugin.Office.Destinations
|
||||||
string imageFile = captureDetails.Filename;
|
string imageFile = captureDetails.Filename;
|
||||||
if (imageFile == null || surface.Modified || !Regex.IsMatch(imageFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$"))
|
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;
|
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
|
// Cleanup imageFile if we created it here, so less tmp-files are generated and left
|
||||||
if (createdFile)
|
if (createdFile)
|
||||||
{
|
{
|
||||||
ImageOutput.DeleteNamedTmpFile(imageFile);
|
ImageIO.DeleteNamedTmpFile(imageFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
|
|
|
@ -160,7 +160,7 @@ namespace Greenshot.Plugin.Office.Destinations
|
||||||
string tmpFile = captureDetails.Filename;
|
string tmpFile = captureDetails.Filename;
|
||||||
if (tmpFile == null || surface.Modified || !Regex.IsMatch(tmpFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$"))
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -114,7 +114,7 @@ namespace Greenshot.Plugin.Office.Destinations
|
||||||
Size imageSize = Size.Empty;
|
Size imageSize = Size.Empty;
|
||||||
if (tmpFile == null || surface.Modified || !Regex.IsMatch(tmpFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$"))
|
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;
|
imageSize = surface.Image.Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ namespace Greenshot.Plugin.Office.Destinations
|
||||||
string tmpFile = captureDetails.Filename;
|
string tmpFile = captureDetails.Filename;
|
||||||
if (tmpFile == null || surface.Modified || !Regex.IsMatch(tmpFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$"))
|
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)
|
if (_documentCaption != null)
|
||||||
|
|
|
@ -97,7 +97,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
|
|
||||||
using var pngStream = new MemoryStream();
|
using var pngStream = new MemoryStream();
|
||||||
var pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false);
|
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 base64String = Convert.ToBase64String(pngStream.GetBuffer());
|
||||||
var imageXmlStr = string.Format(XmlImageContent, base64String, surfaceToUpload.Image.Width, surfaceToUpload.Image.Height);
|
var imageXmlStr = string.Format(XmlImageContent, base64String, surfaceToUpload.Image.Width, surfaceToUpload.Image.Height);
|
||||||
var pageChangesXml = string.Format(XmlOutline, imageXmlStr, page.Id, OnenoteNamespace2010, page.Name);
|
var pageChangesXml = string.Format(XmlOutline, imageXmlStr, page.Id, OnenoteNamespace2010, page.Name);
|
||||||
|
|
|
@ -84,7 +84,7 @@ namespace Greenshot.Plugin.Photobucket.Forms {
|
||||||
this.combobox_uploadimageformat.FormattingEnabled = true;
|
this.combobox_uploadimageformat.FormattingEnabled = true;
|
||||||
this.combobox_uploadimageformat.Location = new System.Drawing.Point(102, 11);
|
this.combobox_uploadimageformat.Location = new System.Drawing.Point(102, 11);
|
||||||
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
this.combobox_uploadimageformat.Name = "combobox_uploadimageformat";
|
||||||
this.combobox_uploadimageformat.PropertyName = "UploadFormat";
|
this.combobox_uploadimageformat.PropertyName = nameof(PhotobucketConfiguration.UploadFormat);
|
||||||
this.combobox_uploadimageformat.SectionName = "Photobucket";
|
this.combobox_uploadimageformat.SectionName = "Photobucket";
|
||||||
this.combobox_uploadimageformat.Size = new System.Drawing.Size(276, 21);
|
this.combobox_uploadimageformat.Size = new System.Drawing.Size(276, 21);
|
||||||
this.combobox_uploadimageformat.TabIndex = 1;
|
this.combobox_uploadimageformat.TabIndex = 1;
|
||||||
|
@ -102,7 +102,7 @@ namespace Greenshot.Plugin.Photobucket.Forms {
|
||||||
this.checkbox_usepagelink.LanguageKey = "photobucket.use_page_link";
|
this.checkbox_usepagelink.LanguageKey = "photobucket.use_page_link";
|
||||||
this.checkbox_usepagelink.Location = new System.Drawing.Point(15, 43);
|
this.checkbox_usepagelink.Location = new System.Drawing.Point(15, 43);
|
||||||
this.checkbox_usepagelink.Name = "checkbox_usepagelink";
|
this.checkbox_usepagelink.Name = "checkbox_usepagelink";
|
||||||
this.checkbox_usepagelink.PropertyName = "UsePageLink";
|
this.checkbox_usepagelink.PropertyName = nameof(PhotobucketConfiguration.UsePageLink);
|
||||||
this.checkbox_usepagelink.SectionName = "Photobucket";
|
this.checkbox_usepagelink.SectionName = "Photobucket";
|
||||||
this.checkbox_usepagelink.Size = new System.Drawing.Size(251, 17);
|
this.checkbox_usepagelink.Size = new System.Drawing.Size(251, 17);
|
||||||
this.checkbox_usepagelink.TabIndex = 2;
|
this.checkbox_usepagelink.TabIndex = 2;
|
||||||
|
|
|
@ -151,7 +151,7 @@ namespace Greenshot.Plugin.Win10.Destinations
|
||||||
outputSettings.PreventGreenshotFormat();
|
outputSettings.PreventGreenshotFormat();
|
||||||
|
|
||||||
// Create capture for export
|
// Create capture for export
|
||||||
ImageOutput.SaveToStream(surface, imageStream, outputSettings);
|
ImageIO.SaveToStream(surface, imageStream, outputSettings);
|
||||||
imageStream.Position = 0;
|
imageStream.Position = 0;
|
||||||
Log.Debug("Created RandomAccessStreamReference for the image");
|
Log.Debug("Created RandomAccessStreamReference for the image");
|
||||||
var imageRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(imageStream);
|
var imageRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(imageStream);
|
||||||
|
@ -161,7 +161,7 @@ namespace Greenshot.Plugin.Win10.Destinations
|
||||||
using (var tmpImageForThumbnail = surface.GetImageForExport())
|
using (var tmpImageForThumbnail = surface.GetImageForExport())
|
||||||
using (var thumbnail = ImageHelper.CreateThumbnail(tmpImageForThumbnail, 240, 160))
|
using (var thumbnail = ImageHelper.CreateThumbnail(tmpImageForThumbnail, 240, 160))
|
||||||
{
|
{
|
||||||
ImageOutput.SaveToStream(thumbnail, null, thumbnailStream, outputSettings);
|
ImageIO.SaveToStream(thumbnail, null, thumbnailStream, outputSettings);
|
||||||
thumbnailStream.Position = 0;
|
thumbnailStream.Position = 0;
|
||||||
thumbnailRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(thumbnailStream);
|
thumbnailRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(thumbnailStream);
|
||||||
Log.Debug("Created RandomAccessStreamReference for the thumbnail");
|
Log.Debug("Created RandomAccessStreamReference for the thumbnail");
|
||||||
|
@ -172,7 +172,7 @@ namespace Greenshot.Plugin.Win10.Destinations
|
||||||
using (var logo = GreenshotResources.GetGreenshotIcon().ToBitmap())
|
using (var logo = GreenshotResources.GetGreenshotIcon().ToBitmap())
|
||||||
using (var logoThumbnail = ImageHelper.CreateThumbnail(logo, 30, 30))
|
using (var logoThumbnail = ImageHelper.CreateThumbnail(logo, 30, 30))
|
||||||
{
|
{
|
||||||
ImageOutput.SaveToStream(logoThumbnail, null, logoStream, outputSettings);
|
ImageIO.SaveToStream(logoThumbnail, null, logoStream, outputSettings);
|
||||||
logoStream.Position = 0;
|
logoStream.Position = 0;
|
||||||
logoRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(logoStream);
|
logoRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(logoStream);
|
||||||
Log.Info("Created RandomAccessStreamReference for the logo");
|
Log.Info("Created RandomAccessStreamReference for the logo");
|
||||||
|
|
|
@ -97,7 +97,7 @@ namespace Greenshot.Plugin.Win10
|
||||||
IEffect effect = new ResizeCanvasEffect(addedWidth, addedWidth, addedHeight, addedHeight);
|
IEffect effect = new ResizeCanvasEffect(addedWidth, addedWidth, addedHeight, addedHeight);
|
||||||
outputSettings.Effects.Add(effect);
|
outputSettings.Effects.Add(effect);
|
||||||
}
|
}
|
||||||
ImageOutput.SaveToStream(surface, imageStream, outputSettings);
|
ImageIO.SaveToStream(surface, imageStream, outputSettings);
|
||||||
imageStream.Position = 0;
|
imageStream.Position = 0;
|
||||||
var randomAccessStream = imageStream.AsRandomAccessStream();
|
var randomAccessStream = imageStream.AsRandomAccessStream();
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ namespace Greenshot.Plugin.Win10
|
||||||
OcrInformation result;
|
OcrInformation result;
|
||||||
using (var imageStream = new MemoryStream())
|
using (var imageStream = new MemoryStream())
|
||||||
{
|
{
|
||||||
ImageOutput.SaveToStream(image, null, imageStream, new SurfaceOutputSettings());
|
ImageIO.SaveToStream(image, null, imageStream, new SurfaceOutputSettings());
|
||||||
imageStream.Position = 0;
|
imageStream.Position = 0;
|
||||||
var randomAccessStream = imageStream.AsRandomAccessStream();
|
var randomAccessStream = imageStream.AsRandomAccessStream();
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<!--<system.windows.forms jitDebugging="true" />-->
|
|
||||||
<startup>
|
<startup>
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||||
</startup>
|
</startup>
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace Greenshot.Destinations
|
||||||
overwrite = true;
|
overwrite = true;
|
||||||
Log.InfoFormat("Using previous filename");
|
Log.InfoFormat("Using previous filename");
|
||||||
fullPath = captureDetails.Filename;
|
fullPath = captureDetails.Filename;
|
||||||
outputSettings.Format = ImageOutput.FormatForFilename(fullPath);
|
outputSettings.Format = ImageIO.FormatForFilename(fullPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -87,7 +87,7 @@ namespace Greenshot.Destinations
|
||||||
// This is done for e.g. bugs #2974608, #2963943, #2816163, #2795317, #2789218, #3004642
|
// This is done for e.g. bugs #2974608, #2963943, #2816163, #2795317, #2789218, #3004642
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ImageOutput.Save(surface, fullPath, overwrite, outputSettings, CoreConfig.OutputFileCopyPathToClipboard);
|
ImageIO.Save(surface, fullPath, overwrite, outputSettings, CoreConfig.OutputFileCopyPathToClipboard);
|
||||||
outputMade = true;
|
outputMade = true;
|
||||||
}
|
}
|
||||||
catch (ArgumentException ex1)
|
catch (ArgumentException ex1)
|
||||||
|
@ -95,7 +95,7 @@ namespace Greenshot.Destinations
|
||||||
// Our generated filename exists, display 'save-as'
|
// Our generated filename exists, display 'save-as'
|
||||||
Log.InfoFormat("Not overwriting: {0}", ex1.Message);
|
Log.InfoFormat("Not overwriting: {0}", ex1.Message);
|
||||||
// when we don't allow to overwrite present a new SaveWithDialog
|
// when we don't allow to overwrite present a new SaveWithDialog
|
||||||
fullPath = ImageOutput.SaveWithDialog(surface, captureDetails);
|
fullPath = ImageIO.SaveWithDialog(surface, captureDetails);
|
||||||
outputMade = fullPath != null;
|
outputMade = fullPath != null;
|
||||||
}
|
}
|
||||||
catch (Exception ex2)
|
catch (Exception ex2)
|
||||||
|
@ -104,7 +104,7 @@ namespace Greenshot.Destinations
|
||||||
// Show the problem
|
// Show the problem
|
||||||
MessageBox.Show(Language.GetString(LangKey.error_save), Language.GetString(LangKey.error));
|
MessageBox.Show(Language.GetString(LangKey.error_save), Language.GetString(LangKey.error));
|
||||||
// when save failed we present a SaveWithDialog
|
// when save failed we present a SaveWithDialog
|
||||||
fullPath = ImageOutput.SaveWithDialog(surface, captureDetails);
|
fullPath = ImageIO.SaveWithDialog(surface, captureDetails);
|
||||||
outputMade = fullPath != null;
|
outputMade = fullPath != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace Greenshot.Destinations
|
||||||
{
|
{
|
||||||
ExportInformation exportInformation = new ExportInformation(Designation, Description);
|
ExportInformation exportInformation = new ExportInformation(Designation, Description);
|
||||||
// Bug #2918756 don't overwrite path if SaveWithDialog returns null!
|
// 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)
|
if (savedTo != null)
|
||||||
{
|
{
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
|
|
|
@ -36,6 +36,7 @@ using Greenshot.Base;
|
||||||
using Greenshot.Base.Controls;
|
using Greenshot.Base.Controls;
|
||||||
using Greenshot.Base.Core;
|
using Greenshot.Base.Core;
|
||||||
using Greenshot.Base.Core.Enums;
|
using Greenshot.Base.Core.Enums;
|
||||||
|
using Greenshot.Base.Core.FileFormatHandlers;
|
||||||
using Greenshot.Base.Help;
|
using Greenshot.Base.Help;
|
||||||
using Greenshot.Base.IniFile;
|
using Greenshot.Base.IniFile;
|
||||||
using Greenshot.Base.Interfaces;
|
using Greenshot.Base.Interfaces;
|
||||||
|
@ -43,6 +44,7 @@ using Greenshot.Base.Interfaces.Plugin;
|
||||||
using Greenshot.Base.UnmanagedHelpers;
|
using Greenshot.Base.UnmanagedHelpers;
|
||||||
using Greenshot.Configuration;
|
using Greenshot.Configuration;
|
||||||
using Greenshot.Destinations;
|
using Greenshot.Destinations;
|
||||||
|
using Greenshot.Editor;
|
||||||
using Greenshot.Editor.Destinations;
|
using Greenshot.Editor.Destinations;
|
||||||
using Greenshot.Editor.Drawing;
|
using Greenshot.Editor.Drawing;
|
||||||
using Greenshot.Editor.Forms;
|
using Greenshot.Editor.Forms;
|
||||||
|
@ -162,7 +164,7 @@ namespace Greenshot.Forms
|
||||||
|
|
||||||
if (argument.ToLower().Equals("/exit"))
|
if (argument.ToLower().Equals("/exit"))
|
||||||
{
|
{
|
||||||
// unregister application on uninstall (allow uninstall)
|
// un-register application on uninstall (allow uninstall)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LOG.Info("Sending all instances the exit command.");
|
LOG.Info("Sending all instances the exit command.");
|
||||||
|
@ -387,6 +389,8 @@ namespace Greenshot.Forms
|
||||||
|
|
||||||
_instance = this;
|
_instance = this;
|
||||||
|
|
||||||
|
EditorInitialize.Initialize();
|
||||||
|
|
||||||
// Factory for surface objects
|
// Factory for surface objects
|
||||||
ISurface SurfaceFactory() => new Surface();
|
ISurface SurfaceFactory() => new Surface();
|
||||||
|
|
||||||
|
@ -923,10 +927,10 @@ namespace Greenshot.Forms
|
||||||
Hide();
|
Hide();
|
||||||
ShowInTaskbar = false;
|
ShowInTaskbar = false;
|
||||||
|
|
||||||
|
// TODO: Do we really need this?
|
||||||
using var loProcess = Process.GetCurrentProcess();
|
//using var loProcess = Process.GetCurrentProcess();
|
||||||
loProcess.MaxWorkingSet = (IntPtr)750000;
|
//loProcess.MaxWorkingSet = (IntPtr)750000;
|
||||||
loProcess.MinWorkingSet = (IntPtr)300000;
|
//loProcess.MinWorkingSet = (IntPtr)300000;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CaptureRegion()
|
private void CaptureRegion()
|
||||||
|
@ -936,9 +940,12 @@ namespace Greenshot.Forms
|
||||||
|
|
||||||
private void CaptureFile(IDestination destination = null)
|
private void CaptureFile(IDestination destination = null)
|
||||||
{
|
{
|
||||||
|
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
|
||||||
|
var extensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).Select(e => $"*{e}").ToList();
|
||||||
|
|
||||||
var openFileDialog = new OpenFileDialog
|
var openFileDialog = new OpenFileDialog
|
||||||
{
|
{
|
||||||
Filter = @"Image files (*.greenshot, *.png, *.jpg, *.gif, *.bmp, *.ico, *.tiff, *.wmf)|*.greenshot; *.png; *.jpg; *.jpeg; *.gif; *.bmp; *.ico; *.tiff; *.tif; *.wmf"
|
Filter = @$"Image files ({string.Join(", ", extensions)})|{string.Join("; ", extensions)}"
|
||||||
};
|
};
|
||||||
if (openFileDialog.ShowDialog() != DialogResult.OK)
|
if (openFileDialog.ShowDialog() != DialogResult.OK)
|
||||||
{
|
{
|
||||||
|
@ -1904,7 +1911,7 @@ namespace Greenshot.Forms
|
||||||
LOG.Error("Error closing application!", e);
|
LOG.Error("Error closing application!", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageOutput.RemoveTmpFiles();
|
ImageIO.RemoveTmpFiles();
|
||||||
|
|
||||||
// Store any open configuration changes
|
// Store any open configuration changes
|
||||||
try
|
try
|
||||||
|
|
17
src/Greenshot/Forms/PrintOptionsDialog.Designer.cs
generated
17
src/Greenshot/Forms/PrintOptionsDialog.Designer.cs
generated
|
@ -89,7 +89,7 @@ namespace Greenshot.Forms
|
||||||
this.checkboxAllowShrink.LanguageKey = "printoptions_allowshrink";
|
this.checkboxAllowShrink.LanguageKey = "printoptions_allowshrink";
|
||||||
this.checkboxAllowShrink.Location = new System.Drawing.Point(13, 23);
|
this.checkboxAllowShrink.Location = new System.Drawing.Point(13, 23);
|
||||||
this.checkboxAllowShrink.Name = "checkboxAllowShrink";
|
this.checkboxAllowShrink.Name = "checkboxAllowShrink";
|
||||||
this.checkboxAllowShrink.PropertyName = "OutputPrintAllowShrink";
|
this.checkboxAllowShrink.PropertyName = nameof(coreConfiguration.OutputPrintAllowShrink);
|
||||||
this.checkboxAllowShrink.Size = new System.Drawing.Size(168, 17);
|
this.checkboxAllowShrink.Size = new System.Drawing.Size(168, 17);
|
||||||
this.checkboxAllowShrink.TabIndex = 2;
|
this.checkboxAllowShrink.TabIndex = 2;
|
||||||
this.checkboxAllowShrink.Text = "Shrink printout to fit paper size";
|
this.checkboxAllowShrink.Text = "Shrink printout to fit paper size";
|
||||||
|
@ -103,7 +103,7 @@ namespace Greenshot.Forms
|
||||||
this.checkboxAllowEnlarge.LanguageKey = "printoptions_allowenlarge";
|
this.checkboxAllowEnlarge.LanguageKey = "printoptions_allowenlarge";
|
||||||
this.checkboxAllowEnlarge.Location = new System.Drawing.Point(13, 46);
|
this.checkboxAllowEnlarge.Location = new System.Drawing.Point(13, 46);
|
||||||
this.checkboxAllowEnlarge.Name = "checkboxAllowEnlarge";
|
this.checkboxAllowEnlarge.Name = "checkboxAllowEnlarge";
|
||||||
this.checkboxAllowEnlarge.PropertyName = "OutputPrintAllowEnlarge";
|
this.checkboxAllowEnlarge.PropertyName = nameof(coreConfiguration.OutputPrintAllowEnlarge);
|
||||||
this.checkboxAllowEnlarge.Size = new System.Drawing.Size(174, 17);
|
this.checkboxAllowEnlarge.Size = new System.Drawing.Size(174, 17);
|
||||||
this.checkboxAllowEnlarge.TabIndex = 3;
|
this.checkboxAllowEnlarge.TabIndex = 3;
|
||||||
this.checkboxAllowEnlarge.Text = "Enlarge printout to fit paper size";
|
this.checkboxAllowEnlarge.Text = "Enlarge printout to fit paper size";
|
||||||
|
@ -117,7 +117,7 @@ namespace Greenshot.Forms
|
||||||
this.checkboxAllowCenter.LanguageKey = "printoptions_allowcenter";
|
this.checkboxAllowCenter.LanguageKey = "printoptions_allowcenter";
|
||||||
this.checkboxAllowCenter.Location = new System.Drawing.Point(13, 92);
|
this.checkboxAllowCenter.Location = new System.Drawing.Point(13, 92);
|
||||||
this.checkboxAllowCenter.Name = "checkboxAllowCenter";
|
this.checkboxAllowCenter.Name = "checkboxAllowCenter";
|
||||||
this.checkboxAllowCenter.PropertyName = "OutputPrintCenter";
|
this.checkboxAllowCenter.PropertyName = nameof(coreConfiguration.OutputPrintCenter);
|
||||||
this.checkboxAllowCenter.Size = new System.Drawing.Size(137, 17);
|
this.checkboxAllowCenter.Size = new System.Drawing.Size(137, 17);
|
||||||
this.checkboxAllowCenter.TabIndex = 5;
|
this.checkboxAllowCenter.TabIndex = 5;
|
||||||
this.checkboxAllowCenter.Text = "Center printout on page";
|
this.checkboxAllowCenter.Text = "Center printout on page";
|
||||||
|
@ -131,7 +131,7 @@ namespace Greenshot.Forms
|
||||||
this.checkboxAllowRotate.LanguageKey = "printoptions_allowrotate";
|
this.checkboxAllowRotate.LanguageKey = "printoptions_allowrotate";
|
||||||
this.checkboxAllowRotate.Location = new System.Drawing.Point(13, 69);
|
this.checkboxAllowRotate.Location = new System.Drawing.Point(13, 69);
|
||||||
this.checkboxAllowRotate.Name = "checkboxAllowRotate";
|
this.checkboxAllowRotate.Name = "checkboxAllowRotate";
|
||||||
this.checkboxAllowRotate.PropertyName = "OutputPrintAllowRotate";
|
this.checkboxAllowRotate.PropertyName = nameof(coreConfiguration.OutputPrintAllowRotate);
|
||||||
this.checkboxAllowRotate.Size = new System.Drawing.Size(187, 17);
|
this.checkboxAllowRotate.Size = new System.Drawing.Size(187, 17);
|
||||||
this.checkboxAllowRotate.TabIndex = 4;
|
this.checkboxAllowRotate.TabIndex = 4;
|
||||||
this.checkboxAllowRotate.Text = "Rotate printout to page orientation";
|
this.checkboxAllowRotate.Text = "Rotate printout to page orientation";
|
||||||
|
@ -158,7 +158,7 @@ namespace Greenshot.Forms
|
||||||
this.checkboxDateTime.LanguageKey = "printoptions_timestamp";
|
this.checkboxDateTime.LanguageKey = "printoptions_timestamp";
|
||||||
this.checkboxDateTime.Location = new System.Drawing.Point(13, 115);
|
this.checkboxDateTime.Location = new System.Drawing.Point(13, 115);
|
||||||
this.checkboxDateTime.Name = "checkboxDateTime";
|
this.checkboxDateTime.Name = "checkboxDateTime";
|
||||||
this.checkboxDateTime.PropertyName = "OutputPrintFooter";
|
this.checkboxDateTime.PropertyName = nameof(coreConfiguration.OutputPrintFooter);
|
||||||
this.checkboxDateTime.Size = new System.Drawing.Size(187, 17);
|
this.checkboxDateTime.Size = new System.Drawing.Size(187, 17);
|
||||||
this.checkboxDateTime.TabIndex = 6;
|
this.checkboxDateTime.TabIndex = 6;
|
||||||
this.checkboxDateTime.Text = "Print date / time at bottom of page";
|
this.checkboxDateTime.Text = "Print date / time at bottom of page";
|
||||||
|
@ -184,7 +184,7 @@ namespace Greenshot.Forms
|
||||||
this.checkboxPrintInverted.LanguageKey = "printoptions_inverted";
|
this.checkboxPrintInverted.LanguageKey = "printoptions_inverted";
|
||||||
this.checkboxPrintInverted.Location = new System.Drawing.Point(13, 88);
|
this.checkboxPrintInverted.Location = new System.Drawing.Point(13, 88);
|
||||||
this.checkboxPrintInverted.Name = "checkboxPrintInverted";
|
this.checkboxPrintInverted.Name = "checkboxPrintInverted";
|
||||||
this.checkboxPrintInverted.PropertyName = "OutputPrintInverted";
|
this.checkboxPrintInverted.PropertyName = nameof(coreConfiguration.OutputPrintInverted);
|
||||||
this.checkboxPrintInverted.Size = new System.Drawing.Size(141, 17);
|
this.checkboxPrintInverted.Size = new System.Drawing.Size(141, 17);
|
||||||
this.checkboxPrintInverted.TabIndex = 14;
|
this.checkboxPrintInverted.TabIndex = 14;
|
||||||
this.checkboxPrintInverted.Text = "Print with inverted colors";
|
this.checkboxPrintInverted.Text = "Print with inverted colors";
|
||||||
|
@ -198,7 +198,7 @@ namespace Greenshot.Forms
|
||||||
this.radioBtnGrayScale.LanguageKey = "printoptions_printgrayscale";
|
this.radioBtnGrayScale.LanguageKey = "printoptions_printgrayscale";
|
||||||
this.radioBtnGrayScale.Location = new System.Drawing.Point(13, 42);
|
this.radioBtnGrayScale.Location = new System.Drawing.Point(13, 42);
|
||||||
this.radioBtnGrayScale.Name = "radioBtnGrayScale";
|
this.radioBtnGrayScale.Name = "radioBtnGrayScale";
|
||||||
this.radioBtnGrayScale.PropertyName = "OutputPrintGrayscale";
|
this.radioBtnGrayScale.PropertyName = nameof(coreConfiguration.OutputPrintGrayscale);
|
||||||
this.radioBtnGrayScale.Size = new System.Drawing.Size(137, 17);
|
this.radioBtnGrayScale.Size = new System.Drawing.Size(137, 17);
|
||||||
this.radioBtnGrayScale.TabIndex = 12;
|
this.radioBtnGrayScale.TabIndex = 12;
|
||||||
this.radioBtnGrayScale.Text = "Force grayscale printing";
|
this.radioBtnGrayScale.Text = "Force grayscale printing";
|
||||||
|
@ -212,7 +212,7 @@ namespace Greenshot.Forms
|
||||||
this.radioBtnMonochrome.LanguageKey = "printoptions_printmonochrome";
|
this.radioBtnMonochrome.LanguageKey = "printoptions_printmonochrome";
|
||||||
this.radioBtnMonochrome.Location = new System.Drawing.Point(13, 65);
|
this.radioBtnMonochrome.Location = new System.Drawing.Point(13, 65);
|
||||||
this.radioBtnMonochrome.Name = "radioBtnMonochrome";
|
this.radioBtnMonochrome.Name = "radioBtnMonochrome";
|
||||||
this.radioBtnMonochrome.PropertyName = "OutputPrintMonochrome";
|
this.radioBtnMonochrome.PropertyName = nameof(coreConfiguration.OutputPrintMonochrome);
|
||||||
this.radioBtnMonochrome.Size = new System.Drawing.Size(148, 17);
|
this.radioBtnMonochrome.Size = new System.Drawing.Size(148, 17);
|
||||||
this.radioBtnMonochrome.TabIndex = 13;
|
this.radioBtnMonochrome.TabIndex = 13;
|
||||||
this.radioBtnMonochrome.Text = "Force black/white printing";
|
this.radioBtnMonochrome.Text = "Force black/white printing";
|
||||||
|
@ -255,7 +255,6 @@ namespace Greenshot.Forms
|
||||||
this.radioBtnColorPrint.LanguageKey = "printoptions_printcolor";
|
this.radioBtnColorPrint.LanguageKey = "printoptions_printcolor";
|
||||||
this.radioBtnColorPrint.Location = new System.Drawing.Point(13, 19);
|
this.radioBtnColorPrint.Location = new System.Drawing.Point(13, 19);
|
||||||
this.radioBtnColorPrint.Name = "radioBtnColorPrint";
|
this.radioBtnColorPrint.Name = "radioBtnColorPrint";
|
||||||
this.radioBtnColorPrint.PropertyName = "OutputPrintColor";
|
|
||||||
this.radioBtnColorPrint.Size = new System.Drawing.Size(90, 17);
|
this.radioBtnColorPrint.Size = new System.Drawing.Size(90, 17);
|
||||||
this.radioBtnColorPrint.TabIndex = 11;
|
this.radioBtnColorPrint.TabIndex = 11;
|
||||||
this.radioBtnColorPrint.TextAlign = System.Drawing.ContentAlignment.TopLeft;
|
this.radioBtnColorPrint.TextAlign = System.Drawing.ContentAlignment.TopLeft;
|
||||||
|
|
77
src/Greenshot/Forms/SettingsForm.Designer.cs
generated
77
src/Greenshot/Forms/SettingsForm.Designer.cs
generated
|
@ -20,6 +20,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Greenshot.Base.Controls;
|
using Greenshot.Base.Controls;
|
||||||
|
using Greenshot.Base.Core;
|
||||||
|
using Greenshot.Editor.Configuration;
|
||||||
using Greenshot.Editor.Controls;
|
using Greenshot.Editor.Controls;
|
||||||
|
|
||||||
namespace Greenshot.Forms {
|
namespace Greenshot.Forms {
|
||||||
|
@ -248,7 +250,7 @@ namespace Greenshot.Forms {
|
||||||
this.textbox_screenshotname.Location = new System.Drawing.Point(205, 42);
|
this.textbox_screenshotname.Location = new System.Drawing.Point(205, 42);
|
||||||
this.textbox_screenshotname.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.textbox_screenshotname.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.textbox_screenshotname.Name = "textbox_screenshotname";
|
this.textbox_screenshotname.Name = "textbox_screenshotname";
|
||||||
this.textbox_screenshotname.PropertyName = "OutputFileFilenamePattern";
|
this.textbox_screenshotname.PropertyName = nameof(coreConfiguration.OutputFileFilenamePattern);
|
||||||
this.textbox_screenshotname.Size = new System.Drawing.Size(205, 20);
|
this.textbox_screenshotname.Size = new System.Drawing.Size(205, 20);
|
||||||
this.textbox_screenshotname.TabIndex = 3;
|
this.textbox_screenshotname.TabIndex = 3;
|
||||||
this.textbox_screenshotname.TextChanged += new System.EventHandler(this.FilenamePatternChanged);
|
this.textbox_screenshotname.TextChanged += new System.EventHandler(this.FilenamePatternChanged);
|
||||||
|
@ -281,7 +283,7 @@ namespace Greenshot.Forms {
|
||||||
this.combobox_primaryimageformat.Location = new System.Drawing.Point(205, 66);
|
this.combobox_primaryimageformat.Location = new System.Drawing.Point(205, 66);
|
||||||
this.combobox_primaryimageformat.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.combobox_primaryimageformat.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.combobox_primaryimageformat.Name = "combobox_primaryimageformat";
|
this.combobox_primaryimageformat.Name = "combobox_primaryimageformat";
|
||||||
this.combobox_primaryimageformat.PropertyName = "OutputFileFormat";
|
this.combobox_primaryimageformat.PropertyName = nameof(coreConfiguration.OutputFileFormat);
|
||||||
this.combobox_primaryimageformat.Size = new System.Drawing.Size(235, 21);
|
this.combobox_primaryimageformat.Size = new System.Drawing.Size(235, 21);
|
||||||
this.combobox_primaryimageformat.TabIndex = 5;
|
this.combobox_primaryimageformat.TabIndex = 5;
|
||||||
//
|
//
|
||||||
|
@ -333,7 +335,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_copypathtoclipboard.Location = new System.Drawing.Point(8, 93);
|
this.checkbox_copypathtoclipboard.Location = new System.Drawing.Point(8, 93);
|
||||||
this.checkbox_copypathtoclipboard.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_copypathtoclipboard.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_copypathtoclipboard.Name = "checkbox_copypathtoclipboard";
|
this.checkbox_copypathtoclipboard.Name = "checkbox_copypathtoclipboard";
|
||||||
this.checkbox_copypathtoclipboard.PropertyName = "OutputFileCopyPathToClipboard";
|
this.checkbox_copypathtoclipboard.PropertyName = nameof(coreConfiguration.OutputFileCopyPathToClipboard);
|
||||||
this.checkbox_copypathtoclipboard.Size = new System.Drawing.Size(358, 20);
|
this.checkbox_copypathtoclipboard.Size = new System.Drawing.Size(358, 20);
|
||||||
this.checkbox_copypathtoclipboard.TabIndex = 6;
|
this.checkbox_copypathtoclipboard.TabIndex = 6;
|
||||||
this.checkbox_copypathtoclipboard.Text = "Copy file path to clipboard every time an image is saved";
|
this.checkbox_copypathtoclipboard.Text = "Copy file path to clipboard every time an image is saved";
|
||||||
|
@ -345,7 +347,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_zoomer.Location = new System.Drawing.Point(4, 82);
|
this.checkbox_zoomer.Location = new System.Drawing.Point(4, 82);
|
||||||
this.checkbox_zoomer.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_zoomer.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_zoomer.Name = "checkbox_zoomer";
|
this.checkbox_zoomer.Name = "checkbox_zoomer";
|
||||||
this.checkbox_zoomer.PropertyName = "ZoomerEnabled";
|
this.checkbox_zoomer.PropertyName = nameof(coreConfiguration.ZoomerEnabled);
|
||||||
this.checkbox_zoomer.Size = new System.Drawing.Size(362, 20);
|
this.checkbox_zoomer.Size = new System.Drawing.Size(362, 20);
|
||||||
this.checkbox_zoomer.TabIndex = 4;
|
this.checkbox_zoomer.TabIndex = 4;
|
||||||
this.checkbox_zoomer.Text = "Show magnifier";
|
this.checkbox_zoomer.Text = "Show magnifier";
|
||||||
|
@ -440,7 +442,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_reducecolors.Location = new System.Drawing.Point(8, 95);
|
this.checkbox_reducecolors.Location = new System.Drawing.Point(8, 95);
|
||||||
this.checkbox_reducecolors.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_reducecolors.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_reducecolors.Name = "checkbox_reducecolors";
|
this.checkbox_reducecolors.Name = "checkbox_reducecolors";
|
||||||
this.checkbox_reducecolors.PropertyName = "OutputFileReduceColors";
|
this.checkbox_reducecolors.PropertyName = nameof(coreConfiguration.OutputFileReduceColors);
|
||||||
this.checkbox_reducecolors.Size = new System.Drawing.Size(358, 20);
|
this.checkbox_reducecolors.Size = new System.Drawing.Size(358, 20);
|
||||||
this.checkbox_reducecolors.TabIndex = 10;
|
this.checkbox_reducecolors.TabIndex = 10;
|
||||||
this.checkbox_reducecolors.Text = "Reduce the amount of colors to a maximum of 256";
|
this.checkbox_reducecolors.Text = "Reduce the amount of colors to a maximum of 256";
|
||||||
|
@ -452,7 +454,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_alwaysshowqualitydialog.Location = new System.Drawing.Point(8, 69);
|
this.checkbox_alwaysshowqualitydialog.Location = new System.Drawing.Point(8, 69);
|
||||||
this.checkbox_alwaysshowqualitydialog.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_alwaysshowqualitydialog.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_alwaysshowqualitydialog.Name = "checkbox_alwaysshowqualitydialog";
|
this.checkbox_alwaysshowqualitydialog.Name = "checkbox_alwaysshowqualitydialog";
|
||||||
this.checkbox_alwaysshowqualitydialog.PropertyName = "OutputFilePromptQuality";
|
this.checkbox_alwaysshowqualitydialog.PropertyName = nameof(coreConfiguration.OutputFilePromptQuality);
|
||||||
this.checkbox_alwaysshowqualitydialog.Size = new System.Drawing.Size(358, 20);
|
this.checkbox_alwaysshowqualitydialog.Size = new System.Drawing.Size(358, 20);
|
||||||
this.checkbox_alwaysshowqualitydialog.TabIndex = 9;
|
this.checkbox_alwaysshowqualitydialog.TabIndex = 9;
|
||||||
this.checkbox_alwaysshowqualitydialog.Text = "Show quality dialog every time an image is saved";
|
this.checkbox_alwaysshowqualitydialog.Text = "Show quality dialog every time an image is saved";
|
||||||
|
@ -620,7 +622,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_usedefaultproxy.Location = new System.Drawing.Point(7, 19);
|
this.checkbox_usedefaultproxy.Location = new System.Drawing.Point(7, 19);
|
||||||
this.checkbox_usedefaultproxy.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_usedefaultproxy.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_usedefaultproxy.Name = "checkbox_usedefaultproxy";
|
this.checkbox_usedefaultproxy.Name = "checkbox_usedefaultproxy";
|
||||||
this.checkbox_usedefaultproxy.PropertyName = "UseProxy";
|
this.checkbox_usedefaultproxy.PropertyName = nameof(coreConfiguration.UseProxy);
|
||||||
this.checkbox_usedefaultproxy.Size = new System.Drawing.Size(359, 20);
|
this.checkbox_usedefaultproxy.Size = new System.Drawing.Size(359, 20);
|
||||||
this.checkbox_usedefaultproxy.TabIndex = 7;
|
this.checkbox_usedefaultproxy.TabIndex = 7;
|
||||||
this.checkbox_usedefaultproxy.Text = "Use default system proxy";
|
this.checkbox_usedefaultproxy.Text = "Use default system proxy";
|
||||||
|
@ -665,7 +667,7 @@ namespace Greenshot.Forms {
|
||||||
this.lastregion_hotkeyControl.Location = new System.Drawing.Point(280, 81);
|
this.lastregion_hotkeyControl.Location = new System.Drawing.Point(280, 81);
|
||||||
this.lastregion_hotkeyControl.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.lastregion_hotkeyControl.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.lastregion_hotkeyControl.Name = "lastregion_hotkeyControl";
|
this.lastregion_hotkeyControl.Name = "lastregion_hotkeyControl";
|
||||||
this.lastregion_hotkeyControl.PropertyName = "LastregionHotkey";
|
this.lastregion_hotkeyControl.PropertyName = nameof(coreConfiguration.LastregionHotkey);
|
||||||
this.lastregion_hotkeyControl.Size = new System.Drawing.Size(158, 20);
|
this.lastregion_hotkeyControl.Size = new System.Drawing.Size(158, 20);
|
||||||
this.lastregion_hotkeyControl.TabIndex = 5;
|
this.lastregion_hotkeyControl.TabIndex = 5;
|
||||||
//
|
//
|
||||||
|
@ -686,7 +688,7 @@ namespace Greenshot.Forms {
|
||||||
this.ie_hotkeyControl.Location = new System.Drawing.Point(280, 104);
|
this.ie_hotkeyControl.Location = new System.Drawing.Point(280, 104);
|
||||||
this.ie_hotkeyControl.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.ie_hotkeyControl.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.ie_hotkeyControl.Name = "ie_hotkeyControl";
|
this.ie_hotkeyControl.Name = "ie_hotkeyControl";
|
||||||
this.ie_hotkeyControl.PropertyName = "IEHotkey";
|
this.ie_hotkeyControl.PropertyName = nameof(coreConfiguration.IEHotkey);
|
||||||
this.ie_hotkeyControl.Size = new System.Drawing.Size(158, 20);
|
this.ie_hotkeyControl.Size = new System.Drawing.Size(158, 20);
|
||||||
this.ie_hotkeyControl.TabIndex = 6;
|
this.ie_hotkeyControl.TabIndex = 6;
|
||||||
//
|
//
|
||||||
|
@ -727,7 +729,7 @@ namespace Greenshot.Forms {
|
||||||
this.region_hotkeyControl.Location = new System.Drawing.Point(280, 59);
|
this.region_hotkeyControl.Location = new System.Drawing.Point(280, 59);
|
||||||
this.region_hotkeyControl.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.region_hotkeyControl.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.region_hotkeyControl.Name = "region_hotkeyControl";
|
this.region_hotkeyControl.Name = "region_hotkeyControl";
|
||||||
this.region_hotkeyControl.PropertyName = "RegionHotkey";
|
this.region_hotkeyControl.PropertyName = nameof(coreConfiguration.RegionHotkey);
|
||||||
this.region_hotkeyControl.Size = new System.Drawing.Size(158, 20);
|
this.region_hotkeyControl.Size = new System.Drawing.Size(158, 20);
|
||||||
this.region_hotkeyControl.TabIndex = 4;
|
this.region_hotkeyControl.TabIndex = 4;
|
||||||
//
|
//
|
||||||
|
@ -738,7 +740,7 @@ namespace Greenshot.Forms {
|
||||||
this.window_hotkeyControl.Location = new System.Drawing.Point(280, 36);
|
this.window_hotkeyControl.Location = new System.Drawing.Point(280, 36);
|
||||||
this.window_hotkeyControl.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.window_hotkeyControl.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.window_hotkeyControl.Name = "window_hotkeyControl";
|
this.window_hotkeyControl.Name = "window_hotkeyControl";
|
||||||
this.window_hotkeyControl.PropertyName = "WindowHotkey";
|
this.window_hotkeyControl.PropertyName = nameof(coreConfiguration.WindowHotkey);
|
||||||
this.window_hotkeyControl.Size = new System.Drawing.Size(158, 20);
|
this.window_hotkeyControl.Size = new System.Drawing.Size(158, 20);
|
||||||
this.window_hotkeyControl.TabIndex = 3;
|
this.window_hotkeyControl.TabIndex = 3;
|
||||||
//
|
//
|
||||||
|
@ -749,7 +751,7 @@ namespace Greenshot.Forms {
|
||||||
this.fullscreen_hotkeyControl.Location = new System.Drawing.Point(280, 14);
|
this.fullscreen_hotkeyControl.Location = new System.Drawing.Point(280, 14);
|
||||||
this.fullscreen_hotkeyControl.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.fullscreen_hotkeyControl.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.fullscreen_hotkeyControl.Name = "fullscreen_hotkeyControl";
|
this.fullscreen_hotkeyControl.Name = "fullscreen_hotkeyControl";
|
||||||
this.fullscreen_hotkeyControl.PropertyName = "FullscreenHotkey";
|
this.fullscreen_hotkeyControl.PropertyName = nameof(coreConfiguration.FullscreenHotkey);
|
||||||
this.fullscreen_hotkeyControl.Size = new System.Drawing.Size(158, 20);
|
this.fullscreen_hotkeyControl.Size = new System.Drawing.Size(158, 20);
|
||||||
this.fullscreen_hotkeyControl.TabIndex = 2;
|
this.fullscreen_hotkeyControl.TabIndex = 2;
|
||||||
//
|
//
|
||||||
|
@ -787,7 +789,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_editor_match_capture_size.Location = new System.Drawing.Point(4, 17);
|
this.checkbox_editor_match_capture_size.Location = new System.Drawing.Point(4, 17);
|
||||||
this.checkbox_editor_match_capture_size.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_editor_match_capture_size.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_editor_match_capture_size.Name = "checkbox_editor_match_capture_size";
|
this.checkbox_editor_match_capture_size.Name = "checkbox_editor_match_capture_size";
|
||||||
this.checkbox_editor_match_capture_size.PropertyName = "MatchSizeToCapture";
|
this.checkbox_editor_match_capture_size.PropertyName = nameof(EditorConfiguration.MatchSizeToCapture);
|
||||||
this.checkbox_editor_match_capture_size.SectionName = "Editor";
|
this.checkbox_editor_match_capture_size.SectionName = "Editor";
|
||||||
this.checkbox_editor_match_capture_size.Size = new System.Drawing.Size(362, 20);
|
this.checkbox_editor_match_capture_size.Size = new System.Drawing.Size(362, 20);
|
||||||
this.checkbox_editor_match_capture_size.TabIndex = 11;
|
this.checkbox_editor_match_capture_size.TabIndex = 11;
|
||||||
|
@ -813,7 +815,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_ie_capture.Location = new System.Drawing.Point(4, 16);
|
this.checkbox_ie_capture.Location = new System.Drawing.Point(4, 16);
|
||||||
this.checkbox_ie_capture.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_ie_capture.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_ie_capture.Name = "checkbox_ie_capture";
|
this.checkbox_ie_capture.Name = "checkbox_ie_capture";
|
||||||
this.checkbox_ie_capture.PropertyName = "IECapture";
|
this.checkbox_ie_capture.PropertyName = nameof(coreConfiguration.IECapture);
|
||||||
this.checkbox_ie_capture.Size = new System.Drawing.Size(362, 20);
|
this.checkbox_ie_capture.Size = new System.Drawing.Size(362, 20);
|
||||||
this.checkbox_ie_capture.TabIndex = 10;
|
this.checkbox_ie_capture.TabIndex = 10;
|
||||||
this.checkbox_ie_capture.Text = "Internet Explorer capture";
|
this.checkbox_ie_capture.Text = "Internet Explorer capture";
|
||||||
|
@ -864,7 +866,7 @@ namespace Greenshot.Forms {
|
||||||
this.radiobuttonInteractiveCapture.Location = new System.Drawing.Point(4, 17);
|
this.radiobuttonInteractiveCapture.Location = new System.Drawing.Point(4, 17);
|
||||||
this.radiobuttonInteractiveCapture.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.radiobuttonInteractiveCapture.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.radiobuttonInteractiveCapture.Name = "radiobuttonInteractiveCapture";
|
this.radiobuttonInteractiveCapture.Name = "radiobuttonInteractiveCapture";
|
||||||
this.radiobuttonInteractiveCapture.PropertyName = "CaptureWindowsInteractive";
|
this.radiobuttonInteractiveCapture.PropertyName = nameof(coreConfiguration.CaptureWindowsInteractive);
|
||||||
this.radiobuttonInteractiveCapture.Size = new System.Drawing.Size(362, 20);
|
this.radiobuttonInteractiveCapture.Size = new System.Drawing.Size(362, 20);
|
||||||
this.radiobuttonInteractiveCapture.TabIndex = 6;
|
this.radiobuttonInteractiveCapture.TabIndex = 6;
|
||||||
this.radiobuttonInteractiveCapture.TabStop = true;
|
this.radiobuttonInteractiveCapture.TabStop = true;
|
||||||
|
@ -910,7 +912,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_notifications.Location = new System.Drawing.Point(4, 60);
|
this.checkbox_notifications.Location = new System.Drawing.Point(4, 60);
|
||||||
this.checkbox_notifications.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_notifications.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_notifications.Name = "checkbox_notifications";
|
this.checkbox_notifications.Name = "checkbox_notifications";
|
||||||
this.checkbox_notifications.PropertyName = "ShowTrayNotification";
|
this.checkbox_notifications.PropertyName = nameof(coreConfiguration.ShowTrayNotification);
|
||||||
this.checkbox_notifications.Size = new System.Drawing.Size(362, 20);
|
this.checkbox_notifications.Size = new System.Drawing.Size(362, 20);
|
||||||
this.checkbox_notifications.TabIndex = 3;
|
this.checkbox_notifications.TabIndex = 3;
|
||||||
this.checkbox_notifications.Text = "Show notifications";
|
this.checkbox_notifications.Text = "Show notifications";
|
||||||
|
@ -922,7 +924,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_playsound.Location = new System.Drawing.Point(4, 38);
|
this.checkbox_playsound.Location = new System.Drawing.Point(4, 38);
|
||||||
this.checkbox_playsound.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_playsound.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_playsound.Name = "checkbox_playsound";
|
this.checkbox_playsound.Name = "checkbox_playsound";
|
||||||
this.checkbox_playsound.PropertyName = "PlayCameraSound";
|
this.checkbox_playsound.PropertyName = nameof(coreConfiguration.PlayCameraSound);
|
||||||
this.checkbox_playsound.Size = new System.Drawing.Size(362, 20);
|
this.checkbox_playsound.Size = new System.Drawing.Size(362, 20);
|
||||||
this.checkbox_playsound.TabIndex = 2;
|
this.checkbox_playsound.TabIndex = 2;
|
||||||
this.checkbox_playsound.Text = "Play camera sound";
|
this.checkbox_playsound.Text = "Play camera sound";
|
||||||
|
@ -934,7 +936,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_capture_mousepointer.Location = new System.Drawing.Point(4, 16);
|
this.checkbox_capture_mousepointer.Location = new System.Drawing.Point(4, 16);
|
||||||
this.checkbox_capture_mousepointer.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_capture_mousepointer.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_capture_mousepointer.Name = "checkbox_capture_mousepointer";
|
this.checkbox_capture_mousepointer.Name = "checkbox_capture_mousepointer";
|
||||||
this.checkbox_capture_mousepointer.PropertyName = "CaptureMousepointer";
|
this.checkbox_capture_mousepointer.PropertyName = nameof(coreConfiguration.CaptureMousepointer);
|
||||||
this.checkbox_capture_mousepointer.Size = new System.Drawing.Size(362, 20);
|
this.checkbox_capture_mousepointer.Size = new System.Drawing.Size(362, 20);
|
||||||
this.checkbox_capture_mousepointer.TabIndex = 1;
|
this.checkbox_capture_mousepointer.TabIndex = 1;
|
||||||
this.checkbox_capture_mousepointer.Text = "Capture mousepointer";
|
this.checkbox_capture_mousepointer.Text = "Capture mousepointer";
|
||||||
|
@ -1035,7 +1037,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkboxPrintInverted.Location = new System.Drawing.Point(10, 94);
|
this.checkboxPrintInverted.Location = new System.Drawing.Point(10, 94);
|
||||||
this.checkboxPrintInverted.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkboxPrintInverted.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkboxPrintInverted.Name = "checkboxPrintInverted";
|
this.checkboxPrintInverted.Name = "checkboxPrintInverted";
|
||||||
this.checkboxPrintInverted.PropertyName = "OutputPrintInverted";
|
this.checkboxPrintInverted.PropertyName = nameof(coreConfiguration.OutputPrintInverted);
|
||||||
this.checkboxPrintInverted.Size = new System.Drawing.Size(355, 20);
|
this.checkboxPrintInverted.Size = new System.Drawing.Size(355, 20);
|
||||||
this.checkboxPrintInverted.TabIndex = 14;
|
this.checkboxPrintInverted.TabIndex = 14;
|
||||||
this.checkboxPrintInverted.Text = "Print with inverted colors";
|
this.checkboxPrintInverted.Text = "Print with inverted colors";
|
||||||
|
@ -1050,7 +1052,8 @@ namespace Greenshot.Forms {
|
||||||
this.radioBtnColorPrint.Location = new System.Drawing.Point(10, 16);
|
this.radioBtnColorPrint.Location = new System.Drawing.Point(10, 16);
|
||||||
this.radioBtnColorPrint.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.radioBtnColorPrint.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.radioBtnColorPrint.Name = "radioBtnColorPrint";
|
this.radioBtnColorPrint.Name = "radioBtnColorPrint";
|
||||||
this.radioBtnColorPrint.PropertyName = "OutputPrintColor";
|
//TODO missing property in coreConfiguration
|
||||||
|
//this.radioBtnColorPrint.PropertyName = nameof(coreConfiguration.OutputPrintColor);
|
||||||
this.radioBtnColorPrint.Size = new System.Drawing.Size(355, 20);
|
this.radioBtnColorPrint.Size = new System.Drawing.Size(355, 20);
|
||||||
this.radioBtnColorPrint.TabIndex = 11;
|
this.radioBtnColorPrint.TabIndex = 11;
|
||||||
this.radioBtnColorPrint.Text = "Full color print";
|
this.radioBtnColorPrint.Text = "Full color print";
|
||||||
|
@ -1065,7 +1068,7 @@ namespace Greenshot.Forms {
|
||||||
this.radioBtnGrayScale.Location = new System.Drawing.Point(10, 42);
|
this.radioBtnGrayScale.Location = new System.Drawing.Point(10, 42);
|
||||||
this.radioBtnGrayScale.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.radioBtnGrayScale.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.radioBtnGrayScale.Name = "radioBtnGrayScale";
|
this.radioBtnGrayScale.Name = "radioBtnGrayScale";
|
||||||
this.radioBtnGrayScale.PropertyName = "OutputPrintGrayscale";
|
this.radioBtnGrayScale.PropertyName = nameof(coreConfiguration.OutputPrintGrayscale);
|
||||||
this.radioBtnGrayScale.Size = new System.Drawing.Size(355, 20);
|
this.radioBtnGrayScale.Size = new System.Drawing.Size(355, 20);
|
||||||
this.radioBtnGrayScale.TabIndex = 12;
|
this.radioBtnGrayScale.TabIndex = 12;
|
||||||
this.radioBtnGrayScale.Text = "Force grayscale printing";
|
this.radioBtnGrayScale.Text = "Force grayscale printing";
|
||||||
|
@ -1080,7 +1083,7 @@ namespace Greenshot.Forms {
|
||||||
this.radioBtnMonochrome.Location = new System.Drawing.Point(10, 68);
|
this.radioBtnMonochrome.Location = new System.Drawing.Point(10, 68);
|
||||||
this.radioBtnMonochrome.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.radioBtnMonochrome.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.radioBtnMonochrome.Name = "radioBtnMonochrome";
|
this.radioBtnMonochrome.Name = "radioBtnMonochrome";
|
||||||
this.radioBtnMonochrome.PropertyName = "OutputPrintMonochrome";
|
this.radioBtnMonochrome.PropertyName = nameof(coreConfiguration.OutputPrintMonochrome);
|
||||||
this.radioBtnMonochrome.Size = new System.Drawing.Size(355, 20);
|
this.radioBtnMonochrome.Size = new System.Drawing.Size(355, 20);
|
||||||
this.radioBtnMonochrome.TabIndex = 13;
|
this.radioBtnMonochrome.TabIndex = 13;
|
||||||
this.radioBtnMonochrome.Text = "Force black/white printing";
|
this.radioBtnMonochrome.Text = "Force black/white printing";
|
||||||
|
@ -1112,7 +1115,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkboxDateTime.Location = new System.Drawing.Point(10, 116);
|
this.checkboxDateTime.Location = new System.Drawing.Point(10, 116);
|
||||||
this.checkboxDateTime.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkboxDateTime.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkboxDateTime.Name = "checkboxDateTime";
|
this.checkboxDateTime.Name = "checkboxDateTime";
|
||||||
this.checkboxDateTime.PropertyName = "OutputPrintFooter";
|
this.checkboxDateTime.PropertyName = nameof(coreConfiguration.OutputPrintFooter);
|
||||||
this.checkboxDateTime.Size = new System.Drawing.Size(355, 20);
|
this.checkboxDateTime.Size = new System.Drawing.Size(355, 20);
|
||||||
this.checkboxDateTime.TabIndex = 6;
|
this.checkboxDateTime.TabIndex = 6;
|
||||||
this.checkboxDateTime.Text = "Print date / time at bottom of page";
|
this.checkboxDateTime.Text = "Print date / time at bottom of page";
|
||||||
|
@ -1127,7 +1130,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkboxAllowShrink.Location = new System.Drawing.Point(10, 20);
|
this.checkboxAllowShrink.Location = new System.Drawing.Point(10, 20);
|
||||||
this.checkboxAllowShrink.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkboxAllowShrink.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkboxAllowShrink.Name = "checkboxAllowShrink";
|
this.checkboxAllowShrink.Name = "checkboxAllowShrink";
|
||||||
this.checkboxAllowShrink.PropertyName = "OutputPrintAllowShrink";
|
this.checkboxAllowShrink.PropertyName = nameof(coreConfiguration.OutputPrintAllowShrink);
|
||||||
this.checkboxAllowShrink.Size = new System.Drawing.Size(355, 20);
|
this.checkboxAllowShrink.Size = new System.Drawing.Size(355, 20);
|
||||||
this.checkboxAllowShrink.TabIndex = 2;
|
this.checkboxAllowShrink.TabIndex = 2;
|
||||||
this.checkboxAllowShrink.Text = "Shrink printout to fit paper size";
|
this.checkboxAllowShrink.Text = "Shrink printout to fit paper size";
|
||||||
|
@ -1142,7 +1145,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkboxAllowEnlarge.Location = new System.Drawing.Point(10, 44);
|
this.checkboxAllowEnlarge.Location = new System.Drawing.Point(10, 44);
|
||||||
this.checkboxAllowEnlarge.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkboxAllowEnlarge.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkboxAllowEnlarge.Name = "checkboxAllowEnlarge";
|
this.checkboxAllowEnlarge.Name = "checkboxAllowEnlarge";
|
||||||
this.checkboxAllowEnlarge.PropertyName = "OutputPrintAllowEnlarge";
|
this.checkboxAllowEnlarge.PropertyName = nameof(coreConfiguration.OutputPrintAllowEnlarge);
|
||||||
this.checkboxAllowEnlarge.Size = new System.Drawing.Size(355, 20);
|
this.checkboxAllowEnlarge.Size = new System.Drawing.Size(355, 20);
|
||||||
this.checkboxAllowEnlarge.TabIndex = 3;
|
this.checkboxAllowEnlarge.TabIndex = 3;
|
||||||
this.checkboxAllowEnlarge.Text = "Enlarge printout to fit paper size";
|
this.checkboxAllowEnlarge.Text = "Enlarge printout to fit paper size";
|
||||||
|
@ -1157,7 +1160,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkboxAllowRotate.Location = new System.Drawing.Point(10, 68);
|
this.checkboxAllowRotate.Location = new System.Drawing.Point(10, 68);
|
||||||
this.checkboxAllowRotate.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkboxAllowRotate.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkboxAllowRotate.Name = "checkboxAllowRotate";
|
this.checkboxAllowRotate.Name = "checkboxAllowRotate";
|
||||||
this.checkboxAllowRotate.PropertyName = "OutputPrintAllowRotate";
|
this.checkboxAllowRotate.PropertyName = nameof(coreConfiguration.OutputPrintAllowRotate);
|
||||||
this.checkboxAllowRotate.Size = new System.Drawing.Size(355, 20);
|
this.checkboxAllowRotate.Size = new System.Drawing.Size(355, 20);
|
||||||
this.checkboxAllowRotate.TabIndex = 4;
|
this.checkboxAllowRotate.TabIndex = 4;
|
||||||
this.checkboxAllowRotate.Text = "Rotate printout to page orientation";
|
this.checkboxAllowRotate.Text = "Rotate printout to page orientation";
|
||||||
|
@ -1172,7 +1175,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkboxAllowCenter.Location = new System.Drawing.Point(10, 92);
|
this.checkboxAllowCenter.Location = new System.Drawing.Point(10, 92);
|
||||||
this.checkboxAllowCenter.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkboxAllowCenter.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkboxAllowCenter.Name = "checkboxAllowCenter";
|
this.checkboxAllowCenter.Name = "checkboxAllowCenter";
|
||||||
this.checkboxAllowCenter.PropertyName = "OutputPrintCenter";
|
this.checkboxAllowCenter.PropertyName = nameof(coreConfiguration.OutputPrintCenter);
|
||||||
this.checkboxAllowCenter.Size = new System.Drawing.Size(355, 20);
|
this.checkboxAllowCenter.Size = new System.Drawing.Size(355, 20);
|
||||||
this.checkboxAllowCenter.TabIndex = 5;
|
this.checkboxAllowCenter.TabIndex = 5;
|
||||||
this.checkboxAllowCenter.Text = "Center printout on page";
|
this.checkboxAllowCenter.Text = "Center printout on page";
|
||||||
|
@ -1185,7 +1188,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_alwaysshowprintoptionsdialog.Location = new System.Drawing.Point(14, 282);
|
this.checkbox_alwaysshowprintoptionsdialog.Location = new System.Drawing.Point(14, 282);
|
||||||
this.checkbox_alwaysshowprintoptionsdialog.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_alwaysshowprintoptionsdialog.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_alwaysshowprintoptionsdialog.Name = "checkbox_alwaysshowprintoptionsdialog";
|
this.checkbox_alwaysshowprintoptionsdialog.Name = "checkbox_alwaysshowprintoptionsdialog";
|
||||||
this.checkbox_alwaysshowprintoptionsdialog.PropertyName = "OutputPrintPromptOptions";
|
this.checkbox_alwaysshowprintoptionsdialog.PropertyName = nameof(coreConfiguration.OutputPrintPromptOptions);
|
||||||
this.checkbox_alwaysshowprintoptionsdialog.Size = new System.Drawing.Size(355, 20);
|
this.checkbox_alwaysshowprintoptionsdialog.Size = new System.Drawing.Size(355, 20);
|
||||||
this.checkbox_alwaysshowprintoptionsdialog.TabIndex = 15;
|
this.checkbox_alwaysshowprintoptionsdialog.TabIndex = 15;
|
||||||
this.checkbox_alwaysshowprintoptionsdialog.Text = "Show print options dialog every time an image is printed";
|
this.checkbox_alwaysshowprintoptionsdialog.Text = "Show print options dialog every time an image is printed";
|
||||||
|
@ -1293,7 +1296,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_reuseeditor.Location = new System.Drawing.Point(8, 240);
|
this.checkbox_reuseeditor.Location = new System.Drawing.Point(8, 240);
|
||||||
this.checkbox_reuseeditor.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_reuseeditor.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_reuseeditor.Name = "checkbox_reuseeditor";
|
this.checkbox_reuseeditor.Name = "checkbox_reuseeditor";
|
||||||
this.checkbox_reuseeditor.PropertyName = "ReuseEditor";
|
this.checkbox_reuseeditor.PropertyName = nameof(EditorConfiguration.ReuseEditor);
|
||||||
this.checkbox_reuseeditor.SectionName = "Editor";
|
this.checkbox_reuseeditor.SectionName = "Editor";
|
||||||
this.checkbox_reuseeditor.Size = new System.Drawing.Size(410, 20);
|
this.checkbox_reuseeditor.Size = new System.Drawing.Size(410, 20);
|
||||||
this.checkbox_reuseeditor.TabIndex = 9;
|
this.checkbox_reuseeditor.TabIndex = 9;
|
||||||
|
@ -1306,7 +1309,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_minimizememoryfootprint.Location = new System.Drawing.Point(8, 216);
|
this.checkbox_minimizememoryfootprint.Location = new System.Drawing.Point(8, 216);
|
||||||
this.checkbox_minimizememoryfootprint.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_minimizememoryfootprint.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_minimizememoryfootprint.Name = "checkbox_minimizememoryfootprint";
|
this.checkbox_minimizememoryfootprint.Name = "checkbox_minimizememoryfootprint";
|
||||||
this.checkbox_minimizememoryfootprint.PropertyName = "MinimizeWorkingSetSize";
|
this.checkbox_minimizememoryfootprint.PropertyName = nameof(coreConfiguration.MinimizeWorkingSetSize);
|
||||||
this.checkbox_minimizememoryfootprint.Size = new System.Drawing.Size(410, 20);
|
this.checkbox_minimizememoryfootprint.Size = new System.Drawing.Size(410, 20);
|
||||||
this.checkbox_minimizememoryfootprint.TabIndex = 8;
|
this.checkbox_minimizememoryfootprint.TabIndex = 8;
|
||||||
this.checkbox_minimizememoryfootprint.Text = "Minimize memory footprint, but with a performance penalty (not advised).";
|
this.checkbox_minimizememoryfootprint.Text = "Minimize memory footprint, but with a performance penalty (not advised).";
|
||||||
|
@ -1318,7 +1321,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_checkunstableupdates.Location = new System.Drawing.Point(8, 192);
|
this.checkbox_checkunstableupdates.Location = new System.Drawing.Point(8, 192);
|
||||||
this.checkbox_checkunstableupdates.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_checkunstableupdates.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_checkunstableupdates.Name = "checkbox_checkunstableupdates";
|
this.checkbox_checkunstableupdates.Name = "checkbox_checkunstableupdates";
|
||||||
this.checkbox_checkunstableupdates.PropertyName = "CheckForUnstable";
|
this.checkbox_checkunstableupdates.PropertyName = nameof(coreConfiguration.CheckForUnstable);
|
||||||
this.checkbox_checkunstableupdates.Size = new System.Drawing.Size(410, 20);
|
this.checkbox_checkunstableupdates.Size = new System.Drawing.Size(410, 20);
|
||||||
this.checkbox_checkunstableupdates.TabIndex = 7;
|
this.checkbox_checkunstableupdates.TabIndex = 7;
|
||||||
this.checkbox_checkunstableupdates.Text = "Check for unstable updates";
|
this.checkbox_checkunstableupdates.Text = "Check for unstable updates";
|
||||||
|
@ -1330,7 +1333,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_suppresssavedialogatclose.Location = new System.Drawing.Point(8, 168);
|
this.checkbox_suppresssavedialogatclose.Location = new System.Drawing.Point(8, 168);
|
||||||
this.checkbox_suppresssavedialogatclose.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_suppresssavedialogatclose.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_suppresssavedialogatclose.Name = "checkbox_suppresssavedialogatclose";
|
this.checkbox_suppresssavedialogatclose.Name = "checkbox_suppresssavedialogatclose";
|
||||||
this.checkbox_suppresssavedialogatclose.PropertyName = "SuppressSaveDialogAtClose";
|
this.checkbox_suppresssavedialogatclose.PropertyName = nameof(EditorConfiguration.SuppressSaveDialogAtClose);
|
||||||
this.checkbox_suppresssavedialogatclose.SectionName = "Editor";
|
this.checkbox_suppresssavedialogatclose.SectionName = "Editor";
|
||||||
this.checkbox_suppresssavedialogatclose.Size = new System.Drawing.Size(410, 20);
|
this.checkbox_suppresssavedialogatclose.Size = new System.Drawing.Size(410, 20);
|
||||||
this.checkbox_suppresssavedialogatclose.TabIndex = 6;
|
this.checkbox_suppresssavedialogatclose.TabIndex = 6;
|
||||||
|
@ -1352,7 +1355,7 @@ namespace Greenshot.Forms {
|
||||||
this.textbox_counter.Location = new System.Drawing.Point(304, 288);
|
this.textbox_counter.Location = new System.Drawing.Point(304, 288);
|
||||||
this.textbox_counter.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.textbox_counter.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.textbox_counter.Name = "textbox_counter";
|
this.textbox_counter.Name = "textbox_counter";
|
||||||
this.textbox_counter.PropertyName = "OutputFileIncrementingNumber";
|
this.textbox_counter.PropertyName = nameof(coreConfiguration.OutputFileIncrementingNumber);
|
||||||
this.textbox_counter.Size = new System.Drawing.Size(134, 20);
|
this.textbox_counter.Size = new System.Drawing.Size(134, 20);
|
||||||
this.textbox_counter.TabIndex = 11;
|
this.textbox_counter.TabIndex = 11;
|
||||||
//
|
//
|
||||||
|
@ -1371,7 +1374,7 @@ namespace Greenshot.Forms {
|
||||||
this.textbox_footerpattern.Location = new System.Drawing.Point(155, 264);
|
this.textbox_footerpattern.Location = new System.Drawing.Point(155, 264);
|
||||||
this.textbox_footerpattern.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.textbox_footerpattern.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.textbox_footerpattern.Name = "textbox_footerpattern";
|
this.textbox_footerpattern.Name = "textbox_footerpattern";
|
||||||
this.textbox_footerpattern.PropertyName = "OutputPrintFooterPattern";
|
this.textbox_footerpattern.PropertyName = nameof(coreConfiguration.OutputPrintFooterPattern);
|
||||||
this.textbox_footerpattern.Size = new System.Drawing.Size(283, 20);
|
this.textbox_footerpattern.Size = new System.Drawing.Size(283, 20);
|
||||||
this.textbox_footerpattern.TabIndex = 10;
|
this.textbox_footerpattern.TabIndex = 10;
|
||||||
//
|
//
|
||||||
|
@ -1381,7 +1384,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_thumbnailpreview.Location = new System.Drawing.Point(8, 144);
|
this.checkbox_thumbnailpreview.Location = new System.Drawing.Point(8, 144);
|
||||||
this.checkbox_thumbnailpreview.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_thumbnailpreview.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_thumbnailpreview.Name = "checkbox_thumbnailpreview";
|
this.checkbox_thumbnailpreview.Name = "checkbox_thumbnailpreview";
|
||||||
this.checkbox_thumbnailpreview.PropertyName = "ThumnailPreview";
|
this.checkbox_thumbnailpreview.PropertyName = nameof(coreConfiguration.ThumnailPreview);
|
||||||
this.checkbox_thumbnailpreview.Size = new System.Drawing.Size(410, 20);
|
this.checkbox_thumbnailpreview.Size = new System.Drawing.Size(410, 20);
|
||||||
this.checkbox_thumbnailpreview.TabIndex = 5;
|
this.checkbox_thumbnailpreview.TabIndex = 5;
|
||||||
this.checkbox_thumbnailpreview.Text = "Show window thumbnails in context menu (for Vista and windows 7)";
|
this.checkbox_thumbnailpreview.Text = "Show window thumbnails in context menu (for Vista and windows 7)";
|
||||||
|
@ -1393,7 +1396,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_optimizeforrdp.Location = new System.Drawing.Point(8, 120);
|
this.checkbox_optimizeforrdp.Location = new System.Drawing.Point(8, 120);
|
||||||
this.checkbox_optimizeforrdp.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_optimizeforrdp.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_optimizeforrdp.Name = "checkbox_optimizeforrdp";
|
this.checkbox_optimizeforrdp.Name = "checkbox_optimizeforrdp";
|
||||||
this.checkbox_optimizeforrdp.PropertyName = "OptimizeForRDP";
|
this.checkbox_optimizeforrdp.PropertyName = nameof(coreConfiguration.OptimizeForRDP);
|
||||||
this.checkbox_optimizeforrdp.Size = new System.Drawing.Size(410, 20);
|
this.checkbox_optimizeforrdp.Size = new System.Drawing.Size(410, 20);
|
||||||
this.checkbox_optimizeforrdp.TabIndex = 4;
|
this.checkbox_optimizeforrdp.TabIndex = 4;
|
||||||
this.checkbox_optimizeforrdp.Text = "Make some optimizations for usage with remote desktop";
|
this.checkbox_optimizeforrdp.Text = "Make some optimizations for usage with remote desktop";
|
||||||
|
@ -1405,7 +1408,7 @@ namespace Greenshot.Forms {
|
||||||
this.checkbox_autoreducecolors.Location = new System.Drawing.Point(8, 102);
|
this.checkbox_autoreducecolors.Location = new System.Drawing.Point(8, 102);
|
||||||
this.checkbox_autoreducecolors.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
this.checkbox_autoreducecolors.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
|
||||||
this.checkbox_autoreducecolors.Name = "checkbox_autoreducecolors";
|
this.checkbox_autoreducecolors.Name = "checkbox_autoreducecolors";
|
||||||
this.checkbox_autoreducecolors.PropertyName = "OutputFileAutoReduceColors";
|
this.checkbox_autoreducecolors.PropertyName = nameof(coreConfiguration.OutputFileAutoReduceColors);
|
||||||
this.checkbox_autoreducecolors.Size = new System.Drawing.Size(410, 20);
|
this.checkbox_autoreducecolors.Size = new System.Drawing.Size(410, 20);
|
||||||
this.checkbox_autoreducecolors.TabIndex = 3;
|
this.checkbox_autoreducecolors.TabIndex = 3;
|
||||||
this.checkbox_autoreducecolors.Text = "Create an 8-bit image if the colors are less than 256 while having a > 8 bits ima" +
|
this.checkbox_autoreducecolors.Text = "Create an 8-bit image if the colors are less than 256 while having a > 8 bits ima" +
|
||||||
|
|
|
@ -37,7 +37,6 @@ using Greenshot.Base.Interfaces;
|
||||||
using Greenshot.Base.Interfaces.Plugin;
|
using Greenshot.Base.Interfaces.Plugin;
|
||||||
using Greenshot.Base.UnmanagedHelpers;
|
using Greenshot.Base.UnmanagedHelpers;
|
||||||
using Greenshot.Configuration;
|
using Greenshot.Configuration;
|
||||||
using Greenshot.Destinations;
|
|
||||||
using Greenshot.Helpers;
|
using Greenshot.Helpers;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
|
@ -320,7 +319,7 @@ namespace Greenshot.Forms
|
||||||
combobox_language.SelectedValue = Language.CurrentLanguage;
|
combobox_language.SelectedValue = Language.CurrentLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delaying the SelectedIndexChanged events untill all is initiated
|
// Delaying the SelectedIndexChanged events until all is initiated
|
||||||
combobox_language.SelectedIndexChanged += Combobox_languageSelectedIndexChanged;
|
combobox_language.SelectedIndexChanged += Combobox_languageSelectedIndexChanged;
|
||||||
UpdateDestinationDescriptions();
|
UpdateDestinationDescriptions();
|
||||||
UpdateClipboardFormatDescriptions();
|
UpdateClipboardFormatDescriptions();
|
||||||
|
@ -832,22 +831,19 @@ namespace Greenshot.Forms
|
||||||
{
|
{
|
||||||
public int Compare(object x, object y)
|
public int Compare(object x, object y)
|
||||||
{
|
{
|
||||||
if (!(x is ListViewItem))
|
if (x is not ListViewItem listViewItemX)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(y is ListViewItem))
|
if (y is not ListViewItem listViewItemY)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListViewItem l1 = (ListViewItem) x;
|
IDestination firstDestination = listViewItemX.Tag as IDestination;
|
||||||
ListViewItem l2 = (ListViewItem) y;
|
|
||||||
|
|
||||||
IDestination firstDestination = l1.Tag as IDestination;
|
if (listViewItemY.Tag is not IDestination secondDestination)
|
||||||
|
|
||||||
if (!(l2.Tag is IDestination secondDestination))
|
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -389,6 +389,7 @@ namespace Greenshot.Helpers
|
||||||
HandleCapture();
|
HandleCapture();
|
||||||
break;
|
break;
|
||||||
case CaptureMode.Clipboard:
|
case CaptureMode.Clipboard:
|
||||||
|
// TODO: Fix getting image vs. drawablecontainer
|
||||||
Image clipboardImage = ClipboardHelper.GetImage();
|
Image clipboardImage = ClipboardHelper.GetImage();
|
||||||
if (clipboardImage != null)
|
if (clipboardImage != null)
|
||||||
{
|
{
|
||||||
|
@ -430,12 +431,13 @@ namespace Greenshot.Helpers
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(filename))
|
if (!string.IsNullOrEmpty(filename))
|
||||||
{
|
{
|
||||||
|
// TODO: Fix that the Greenshot format needs a separate code path
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (filename.ToLower().EndsWith("." + OutputFormat.greenshot))
|
if (filename.ToLower().EndsWith("." + OutputFormat.greenshot))
|
||||||
{
|
{
|
||||||
ISurface surface = new Surface();
|
ISurface surface = new Surface();
|
||||||
surface = ImageOutput.LoadGreenshotSurface(filename, surface);
|
surface = ImageIO.LoadGreenshotSurface(filename, surface);
|
||||||
surface.CaptureDetails = _capture.CaptureDetails;
|
surface.CaptureDetails = _capture.CaptureDetails;
|
||||||
DestinationHelper.GetDestination(EditorDestination.DESIGNATION).ExportCapture(true, surface, _capture.CaptureDetails);
|
DestinationHelper.GetDestination(EditorDestination.DESIGNATION).ExportCapture(true, surface, _capture.CaptureDetails);
|
||||||
break;
|
break;
|
||||||
|
@ -447,9 +449,10 @@ namespace Greenshot.Helpers
|
||||||
MessageBox.Show(Language.GetFormattedString(LangKey.error_openfile, filename));
|
MessageBox.Show(Language.GetFormattedString(LangKey.error_openfile, filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Remove Image loading for here
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fileImage = ImageHelper.LoadImage(filename);
|
fileImage = ImageIO.LoadImage(filename);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,7 +82,7 @@ namespace Greenshot.Helpers
|
||||||
/// <param name="captureDetails">ICaptureDetails</param>
|
/// <param name="captureDetails">ICaptureDetails</param>
|
||||||
public static void SendImage(ISurface surface, ICaptureDetails captureDetails)
|
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;
|
if (tmpFile == null) return;
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,7 @@ namespace Greenshot.Helpers
|
||||||
|
|
||||||
ApplyEffects(printOutputSettings);
|
ApplyEffects(printOutputSettings);
|
||||||
|
|
||||||
bool disposeImage = ImageOutput.CreateImageFromSurface(_surface, printOutputSettings, out var image);
|
bool disposeImage = ImageIO.CreateImageFromSurface(_surface, printOutputSettings, out var image);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ContentAlignment alignment = CoreConfig.OutputPrintCenter ? ContentAlignment.MiddleCenter : ContentAlignment.TopLeft;
|
ContentAlignment alignment = CoreConfig.OutputPrintCenter ? ContentAlignment.MiddleCenter : ContentAlignment.TopLeft;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue