diff --git a/Greenshot.ImageEditor/Configuration/CoreConfiguration.cs b/Greenshot.ImageEditor/Configuration/CoreConfiguration.cs
deleted file mode 100644
index 1ee896ea4..000000000
--- a/Greenshot.ImageEditor/Configuration/CoreConfiguration.cs
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using Greenshot.IniFile;
-using Greenshot.Plugin;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
-using System.IO;
-using System.Reflection;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Core
-{
- public enum ClipboardFormat
- {
- PNG, DIB, HTML, HTMLDATAURL, BITMAP, DIBV5
- }
- public enum OutputFormat
- {
- bmp, gif, jpg, png, tiff, greenshot
- }
- public enum WindowCaptureMode
- {
- Screen, GDI, Aero, AeroTransparent, Auto
- }
-
- public enum BuildStates
- {
- UNSTABLE,
- RELEASE_CANDIDATE,
- RELEASE
- }
-
- public enum ClickActions
- {
- DO_NOTHING,
- OPEN_LAST_IN_EXPLORER,
- OPEN_LAST_IN_EDITOR,
- OPEN_SETTINGS,
- SHOW_CONTEXT_MENU
- }
-
- ///
- /// Description of CoreConfiguration.
- ///
- [IniSection("Core", Description = "Greenshot core configuration")]
- public class CoreConfiguration : IniSection, INotifyPropertyChanged
- {
- public event PropertyChangedEventHandler PropertyChanged;
-
- [IniProperty("Language", Description = "The language in IETF format (e.g. en-US)")]
- public string Language;
-
- [IniProperty("RegionHotkey", Description = "Hotkey for starting the region capture", DefaultValue = "PrintScreen")]
- public string RegionHotkey;
- [IniProperty("WindowHotkey", Description = "Hotkey for starting the window capture", DefaultValue = "Alt + PrintScreen")]
- public string WindowHotkey;
- [IniProperty("FullscreenHotkey", Description = "Hotkey for starting the fullscreen capture", DefaultValue = "Ctrl + PrintScreen")]
- public string FullscreenHotkey;
- [IniProperty("LastregionHotkey", Description = "Hotkey for starting the last region capture", DefaultValue = "Shift + PrintScreen")]
- public string LastregionHotkey;
- [IniProperty("IEHotkey", Description = "Hotkey for starting the IE capture", DefaultValue = "Shift + Ctrl + PrintScreen")]
- public string IEHotkey;
-
- [IniProperty("IsFirstLaunch", Description = "Is this the first time launch?", DefaultValue = "true")]
- public bool IsFirstLaunch;
- [IniProperty("Destinations", Separator = ",", Description = "Which destinations? Possible options (more might be added by plugins) are: Editor, FileDefault, FileWithDialog, Clipboard, Printer, EMail, Picker", DefaultValue = "Picker")]
- public List OutputDestinations = new List();
- [IniProperty("ClipboardFormats", Separator = ",", Description = "Specify which formats we copy on the clipboard? Options are: PNG, HTML, HTMLDATAURL and DIB", DefaultValue = "PNG,DIB")]
- public List ClipboardFormats = new List();
-
- [IniProperty("CaptureMousepointer", Description = "Should the mouse be captured?", DefaultValue = "true")]
- public bool CaptureMousepointer;
- [IniProperty("CaptureWindowsInteractive", Description = "Use interactive window selection to capture? (false=Capture active window)", DefaultValue = "false")]
- public bool CaptureWindowsInteractive;
- [IniProperty("CaptureDelay", Description = "Capture delay in millseconds.", DefaultValue = "100")]
- public int CaptureDelay;
- [IniProperty("ScreenCaptureMode", Description = "The capture mode used to capture a screen. (Auto, FullScreen, Fixed)", DefaultValue = "Auto")]
- public ScreenCaptureMode ScreenCaptureMode;
- [IniProperty("ScreenToCapture", Description = "The screen number to capture when using ScreenCaptureMode Fixed.", DefaultValue = "1")]
- public int ScreenToCapture;
- [IniProperty("WindowCaptureMode", Description = "The capture mode used to capture a Window (Screen, GDI, Aero, AeroTransparent, Auto).", DefaultValue = "Auto")]
- public WindowCaptureMode WindowCaptureMode;
- [IniProperty("WindowCaptureAllChildLocations", Description = "Enable/disable capture all children, very slow but will make it possible to use this information in the editor.", DefaultValue = "False")]
- public bool WindowCaptureAllChildLocations;
-
- [IniProperty("DWMBackgroundColor", Description = "The background color for a DWM window capture.")]
- public Color DWMBackgroundColor;
-
- [IniProperty("PlayCameraSound", LanguageKey = "settings_playsound", Description = "Play a camera sound after taking a capture.", DefaultValue = "false")]
- public bool PlayCameraSound = false;
- [IniProperty("ShowTrayNotification", LanguageKey = "settings_shownotify", Description = "Show a notification from the systray when a capture is taken.", DefaultValue = "true")]
- public bool ShowTrayNotification = true;
-
- [IniProperty("OutputFilePath", Description = "Output file path.")]
- public string OutputFilePath;
- [IniProperty("OutputFileAllowOverwrite", Description = "If the target file already exists True will make Greenshot always overwrite and False will display a 'Save-As' dialog.", DefaultValue = "true")]
- public bool OutputFileAllowOverwrite;
- [IniProperty("OutputFileFilenamePattern", Description = "Filename pattern for screenshot.", DefaultValue = "${capturetime:d\"yyyy-MM-dd HH_mm_ss\"}-${title}")]
- public string OutputFileFilenamePattern;
- [IniProperty("OutputFileFormat", Description = "Default file type for writing screenshots. (bmp, gif, jpg, png, tiff)", DefaultValue = "png")]
- public OutputFormat OutputFileFormat = OutputFormat.png;
- [IniProperty("OutputFileReduceColors", Description = "If set to true, than the colors of the output file are reduced to 256 (8-bit) colors", DefaultValue = "false")]
- public bool OutputFileReduceColors;
- [IniProperty("OutputFileAutoReduceColors", Description = "If set to true the amount of colors is counted and if smaller than 256 the color reduction is automatically used.", DefaultValue = "false")]
- public bool OutputFileAutoReduceColors;
- [IniProperty("OutputFileReduceColorsTo", Description = "Amount of colors to reduce to, when reducing", DefaultValue = "256")]
- public int OutputFileReduceColorsTo;
-
- [IniProperty("OutputFileCopyPathToClipboard", Description = "When saving a screenshot, copy the path to the clipboard?", DefaultValue = "true")]
- public bool OutputFileCopyPathToClipboard;
- [IniProperty("OutputFileAsFullpath", Description = "SaveAs Full path?")]
- public string OutputFileAsFullpath;
-
- [IniProperty("OutputFileJpegQuality", Description = "JPEG file save quality in %.", DefaultValue = "80")]
- public int OutputFileJpegQuality;
- [IniProperty("OutputFilePromptQuality", Description = "Ask for the quality before saving?", DefaultValue = "false")]
- public bool OutputFilePromptQuality;
- [IniProperty("OutputFileIncrementingNumber", Description = "The number for the ${NUM} in the filename pattern, is increased automatically after each save.", DefaultValue = "1")]
- public uint OutputFileIncrementingNumber;
-
- [IniProperty("OutputPrintPromptOptions", LanguageKey = "settings_alwaysshowprintoptionsdialog", Description = "Ask for print options when printing?", DefaultValue = "true")]
- public bool OutputPrintPromptOptions;
- [IniProperty("OutputPrintAllowRotate", LanguageKey = "printoptions_allowrotate", Description = "Allow rotating the picture for fitting on paper?", DefaultValue = "false")]
- public bool OutputPrintAllowRotate;
- [IniProperty("OutputPrintAllowEnlarge", LanguageKey = "printoptions_allowenlarge", Description = "Allow growing the picture for fitting on paper?", DefaultValue = "false")]
- public bool OutputPrintAllowEnlarge;
- [IniProperty("OutputPrintAllowShrink", LanguageKey = "printoptions_allowshrink", Description = "Allow shrinking the picture for fitting on paper?", DefaultValue = "true")]
- public bool OutputPrintAllowShrink;
- [IniProperty("OutputPrintCenter", LanguageKey = "printoptions_allowcenter", Description = "Center image when printing?", DefaultValue = "true")]
- public bool OutputPrintCenter;
- [IniProperty("OutputPrintInverted", LanguageKey = "printoptions_inverted", Description = "Print image inverted (use e.g. for console captures)", DefaultValue = "false")]
- public bool OutputPrintInverted;
- [IniProperty("OutputPrintGrayscale", LanguageKey = "printoptions_printgrayscale", Description = "Force grayscale printing", DefaultValue = "false")]
- public bool OutputPrintGrayscale;
- [IniProperty("OutputPrintMonochrome", LanguageKey = "printoptions_printmonochrome", Description = "Force monorchrome printing", DefaultValue = "false")]
- public bool OutputPrintMonochrome;
- [IniProperty("OutputPrintMonochromeThreshold", Description = "Threshold for monochrome filter (0 - 255), lower value means less black", DefaultValue = "127")]
- public byte OutputPrintMonochromeThreshold;
- [IniProperty("OutputPrintFooter", LanguageKey = "printoptions_timestamp", Description = "Print footer on print?", DefaultValue = "true")]
- public bool OutputPrintFooter;
- [IniProperty("OutputPrintFooterPattern", Description = "Footer pattern", DefaultValue = "${capturetime:d\"D\"} ${capturetime:d\"T\"} - ${title}")]
- public string OutputPrintFooterPattern;
- [IniProperty("NotificationSound", Description = "The wav-file to play when a capture is taken, loaded only once at the Greenshot startup", DefaultValue = "default")]
- public string NotificationSound;
- [IniProperty("UseProxy", Description = "Use your global proxy?", DefaultValue = "True")]
- public bool UseProxy;
- [IniProperty("IECapture", Description = "Enable/disable IE capture", DefaultValue = "True")]
- public bool IECapture;
- [IniProperty("IEFieldCapture", Description = "Enable/disable IE field capture, very slow but will make it possible to annotate the fields of a capture in the editor.", DefaultValue = "False")]
- public bool IEFieldCapture;
- [IniProperty("WindowClassesToCheckForIE", Description = "Comma separated list of Window-Classes which need to be checked for a IE instance!", DefaultValue = "AfxFrameOrView70,IMWindowClass")]
- public List WindowClassesToCheckForIE;
- [IniProperty("AutoCropDifference", Description = "Sets how to compare the colors for the autocrop detection, the higher the more is 'selected'. Possible values are from 0 to 255, where everything above ~150 doesn't make much sense!", DefaultValue = "10")]
- public int AutoCropDifference;
-
- [IniProperty("IncludePlugins", Description = "Comma separated list of Plugins which are allowed. If something in the list, than every plugin not in the list will not be loaded!")]
- public List IncludePlugins;
- [IniProperty("ExcludePlugins", Description = "Comma separated list of Plugins which are NOT allowed.")]
- public List ExcludePlugins;
- [IniProperty("ExcludeDestinations", Description = "Comma separated list of destinations which should be disabled.")]
- public List ExcludeDestinations;
-
- [IniProperty("UpdateCheckInterval", Description = "How many days between every update check? (0=no checks)", DefaultValue = "1")]
- public int UpdateCheckInterval;
- [IniProperty("LastUpdateCheck", Description = "Last update check")]
- public DateTime LastUpdateCheck;
-
- [IniProperty("DisableSettings", Description = "Enable/disable the access to the settings, can only be changed manually in this .ini", DefaultValue = "False")]
- public bool DisableSettings;
- [IniProperty("DisableQuickSettings", Description = "Enable/disable the access to the quick settings, can only be changed manually in this .ini", DefaultValue = "False")]
- public bool DisableQuickSettings;
- [IniProperty("DisableTrayicon", Description = "Disable the trayicon, can only be changed manually in this .ini", DefaultValue = "False")]
- public bool HideTrayicon;
- [IniProperty("HideExpertSettings", Description = "Hide expert tab in the settings, can only be changed manually in this .ini", DefaultValue = "False")]
- public bool HideExpertSettings;
-
- [IniProperty("ThumnailPreview", Description = "Enable/disable thumbnail previews", DefaultValue = "True")]
- public bool ThumnailPreview;
-
- [IniProperty("NoGDICaptureForProduct", Description = "List of productnames for which GDI capturing is skipped (using fallback).", DefaultValue = "IntelliJ IDEA")]
- public List NoGDICaptureForProduct;
- [IniProperty("NoDWMCaptureForProduct", Description = "List of productnames for which DWM capturing is skipped (using fallback).", DefaultValue = "Citrix ICA Client")]
- public List NoDWMCaptureForProduct;
-
- [IniProperty("OptimizeForRDP", Description = "Make some optimizations for usage with remote desktop", DefaultValue = "False")]
- public bool OptimizeForRDP;
- [IniProperty("DisableRDPOptimizing", Description = "Disable all optimizations for usage with remote desktop", DefaultValue = "False")]
- public bool DisableRDPOptimizing;
-
- [IniProperty("MinimizeWorkingSetSize", Description = "Optimize memory footprint, but with a performance penalty!", DefaultValue = "False")]
- public bool MinimizeWorkingSetSize;
-
- [IniProperty("WindowCaptureRemoveCorners", Description = "Remove the corners from a window capture", DefaultValue = "True")]
- public bool WindowCaptureRemoveCorners;
-
- [IniProperty("CheckForUnstable", Description = "Also check for unstable version updates", DefaultValue = "False")]
- public bool CheckForUnstable;
-
- [IniProperty("ActiveTitleFixes", Description = "The fixes that are active.")]
- public List ActiveTitleFixes;
-
- [IniProperty("TitleFixMatcher", Description = "The regular expressions to match the title with.")]
- public Dictionary TitleFixMatcher;
-
- [IniProperty("TitleFixReplacer", Description = "The replacements for the matchers.")]
- public Dictionary TitleFixReplacer;
-
- [IniProperty("ExperimentalFeatures", Description = "A list of experimental features, this allows us to test certain features before releasing them.", ExcludeIfNull = true)]
- public List ExperimentalFeatures;
-
- [IniProperty("EnableSpecialDIBClipboardReader", Description = "Enable a special DIB clipboard reader", DefaultValue = "True")]
- public bool EnableSpecialDIBClipboardReader;
-
- [IniProperty("WindowCornerCutShape", Description = "The cutshape which is used to remove the window corners, is mirrorred for all corners", DefaultValue = "5,3,2,1,1")]
- public List WindowCornerCutShape;
-
- [IniProperty("LeftClickAction", Description = "Specify what action is made if the tray icon is left clicked, if a double-click action is specified this action is initiated after a delay (configurable via the windows double-click speed)", DefaultValue = "SHOW_CONTEXT_MENU")]
- public ClickActions LeftClickAction;
-
- [IniProperty("DoubleClickAction", Description = "Specify what action is made if the tray icon is double clicked", DefaultValue = "OPEN_LAST_IN_EXPLORER")]
- public ClickActions DoubleClickAction;
-
- [IniProperty("ZoomerEnabled", Description = "Sets if the zoomer is enabled", DefaultValue = "True")]
- public bool ZoomerEnabled;
- [IniProperty("ZoomerOpacity", Description = "Specify the transparency for the zoomer, from 0-1 (where 1 is no transparency and 0 is complete transparent. An usefull setting would be 0.7)", DefaultValue = "1")]
- public float ZoomerOpacity;
-
- [IniProperty("MaxMenuItemLength", Description = "Maximum length of submenu items in the context menu, making this longer might cause context menu issues on dual screen systems.", DefaultValue = "25")]
- public int MaxMenuItemLength;
-
- [IniProperty("MailApiTo", Description = "The 'to' field for the email destination (settings for Outlook can be found under the Office section)", DefaultValue = "")]
- public string MailApiTo;
- [IniProperty("MailApiCC", Description = "The 'CC' field for the email destination (settings for Outlook can be found under the Office section)", DefaultValue = "")]
- public string MailApiCC;
- [IniProperty("MailApiBCC", Description = "The 'BCC' field for the email destination (settings for Outlook can be found under the Office section)", DefaultValue = "")]
- public string MailApiBCC;
-
- [IniProperty("OptimizePNGCommand", Description = "Optional command to execute on a temporary PNG file, the command should overwrite the file and Greenshot will read it back. Note: this command is also executed when uploading PNG's!", DefaultValue = "")]
- public string OptimizePNGCommand;
- [IniProperty("OptimizePNGCommandArguments", Description = "Arguments for the optional command to execute on a PNG, {0} is replaced by the temp-filename from Greenshot. Note: Temp-file is deleted afterwards by Greenshot.", DefaultValue = "\"{0}\"")]
- public string OptimizePNGCommandArguments;
-
- [IniProperty("LastSaveWithVersion", Description = "Version of Greenshot which created this .ini")]
- public string LastSaveWithVersion;
-
- [IniProperty("ProcessEXIFOrientation", Description = "When reading images from files or clipboard, use the EXIF information to correct the orientation", DefaultValue = "True")]
- public bool ProcessEXIFOrientation;
-
- [IniProperty("LastCapturedRegion", Description = "The last used region, for reuse in the capture last region")]
- public Rectangle LastCapturedRegion;
-
- private Size _iconSize;
- [IniProperty("IconSize", Description = "Defines the size of the icons (e.g. for the buttons in the editor), default value 16,16 anything bigger will cause scaling", DefaultValue = "16,16")]
- public Size IconSize
- {
- get
- {
- return _iconSize;
- }
- set
- {
- Size newSize = value;
- if (newSize != Size.Empty)
- {
- if (newSize.Width < 16)
- {
- newSize.Width = 16;
- }
- else if (newSize.Width > 256)
- {
- newSize.Width = 256;
- }
- newSize.Width = (newSize.Width / 8) * 8;
- if (newSize.Height < 16)
- {
- newSize.Height = 16;
- }
- else if (IconSize.Height > 256)
- {
- newSize.Height = 256;
- }
- newSize.Height = (newSize.Height / 8) * 8;
- }
- if (_iconSize != newSize)
- {
- _iconSize = value;
- if (PropertyChanged != null)
- {
- PropertyChanged(this, new PropertyChangedEventArgs("IconSize"));
- }
- }
- }
- }
-
- [IniProperty("WebRequestTimeout", Description = "The connect timeout value for webrequets, these are seconds", DefaultValue = "100")]
- public int WebRequestTimeout;
- [IniProperty("WebRequestReadWriteTimeout", Description = "The read/write timeout value for webrequets, these are seconds", DefaultValue = "100")]
- public int WebRequestReadWriteTimeout;
-
- ///
- /// Specifies what THIS build is
- ///
- public BuildStates BuildState
- {
- get
- {
- string informationalVersion = Application.ProductVersion;
- if (informationalVersion != null)
- {
- if (informationalVersion.ToLowerInvariant().Contains("-rc"))
- {
- return BuildStates.RELEASE_CANDIDATE;
- }
- if (informationalVersion.ToLowerInvariant().Contains("-unstable"))
- {
- return BuildStates.UNSTABLE;
- }
- }
- return BuildStates.RELEASE;
- }
- }
-
- public bool UseLargeIcons
- {
- get
- {
- return IconSize.Width >= 32 || IconSize.Height >= 32;
- }
- }
-
- ///
- /// A helper method which returns true if the supplied experimental feature is enabled
- ///
- ///
- ///
- public bool isExperimentalFeatureEnabled(string experimentalFeature)
- {
- return (ExperimentalFeatures != null && ExperimentalFeatures.Contains(experimentalFeature));
- }
-
- ///
- /// Supply values we can't put as defaults
- ///
- /// The property to return a default for
- /// object with the default value for the supplied property
- public override object GetDefault(string property)
- {
- switch (property)
- {
- case "PluginWhitelist":
- case "PluginBacklist":
- return new List();
- case "OutputFileAsFullpath":
- if (IniConfig.IsPortable)
- {
- return Path.Combine(Application.StartupPath, @"..\..\Documents\Pictures\Greenshots\dummy.png");
- }
- else
- {
- return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "dummy.png");
- }
- case "OutputFilePath":
- if (IniConfig.IsPortable)
- {
- string pafOutputFilePath = Path.Combine(Application.StartupPath, @"..\..\Documents\Pictures\Greenshots");
- if (!Directory.Exists(pafOutputFilePath))
- {
- try
- {
- Directory.CreateDirectory(pafOutputFilePath);
- return pafOutputFilePath;
- }
- catch (Exception ex)
- {
- LOG.Warn(ex);
- // Problem creating directory, fallback to Desktop
- }
- }
- else
- {
- return pafOutputFilePath;
- }
- }
- return Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
- case "DWMBackgroundColor":
- return Color.Transparent;
- case "ActiveTitleFixes":
- List activeDefaults = new List();
- activeDefaults.Add("Firefox");
- activeDefaults.Add("IE");
- activeDefaults.Add("Chrome");
- return activeDefaults;
- case "TitleFixMatcher":
- Dictionary matcherDefaults = new Dictionary();
- matcherDefaults.Add("Firefox", " - Mozilla Firefox.*");
- matcherDefaults.Add("IE", " - (Microsoft|Windows) Internet Explorer.*");
- matcherDefaults.Add("Chrome", " - Google Chrome.*");
- return matcherDefaults;
- case "TitleFixReplacer":
- Dictionary replacerDefaults = new Dictionary();
- replacerDefaults.Add("Firefox", "");
- replacerDefaults.Add("IE", "");
- replacerDefaults.Add("Chrome", "");
- return replacerDefaults;
- }
- return null;
- }
-
- ///
- /// This method will be called before converting the property, making to possible to correct a certain value
- /// Can be used when migration is needed
- ///
- /// The name of the property
- /// The string value of the property
- /// string with the propertyValue, modified or not...
- public override string PreCheckValue(string propertyName, string propertyValue)
- {
- // Changed the separator, now we need to correct this
- if ("Destinations".Equals(propertyName))
- {
- if (propertyValue != null)
- {
- return propertyValue.Replace('|', ',');
- }
- }
- if ("OutputFilePath".Equals(propertyName))
- {
- if (string.IsNullOrEmpty(propertyValue))
- {
- return null;
- }
- }
- return base.PreCheckValue(propertyName, propertyValue);
- }
-
- ///
- /// This method will be called before writing the configuration
- ///
- public override void BeforeSave()
- {
- try
- {
- // Store version, this can be used later to fix settings after an update
- LastSaveWithVersion = Assembly.GetEntryAssembly().GetName().Version.ToString();
- }
- catch
- {
- }
- }
-
- ///
- /// This method will be called after reading the configuration, so eventually some corrections can be made
- ///
- public override void AfterLoad()
- {
- // Comment with releases
- // CheckForUnstable = true;
-
- if (string.IsNullOrEmpty(LastSaveWithVersion))
- {
- try
- {
- // Store version, this can be used later to fix settings after an update
- LastSaveWithVersion = Assembly.GetEntryAssembly().GetName().Version.ToString();
- }
- catch
- {
- }
- // Disable the AutoReduceColors as it causes issues with Mozzila applications and some others
- OutputFileAutoReduceColors = false;
- }
-
- // Enable OneNote if upgrading from 1.1
- if (ExcludeDestinations != null && ExcludeDestinations.Contains("OneNote"))
- {
- if (LastSaveWithVersion != null && LastSaveWithVersion.StartsWith("1.1"))
- {
- ExcludeDestinations.Remove("OneNote");
- }
- else
- {
- // Remove with the release
- ExcludeDestinations.Remove("OneNote");
- }
- }
-
- if (OutputDestinations == null)
- {
- OutputDestinations = new List();
- }
-
- // Make sure there is an output!
- if (OutputDestinations.Count == 0)
- {
- OutputDestinations.Add("Editor");
- }
-
- // Prevent both settings at once, bug #3435056
- if (OutputDestinations.Contains("Clipboard") && OutputFileCopyPathToClipboard)
- {
- OutputFileCopyPathToClipboard = false;
- }
-
- // Make sure we have clipboard formats, otherwise a paste doesn't make sense!
- if (ClipboardFormats == null || ClipboardFormats.Count == 0)
- {
- ClipboardFormats = new List();
- ClipboardFormats.Add(ClipboardFormat.PNG);
- ClipboardFormats.Add(ClipboardFormat.HTML);
- ClipboardFormats.Add(ClipboardFormat.DIB);
- }
-
- // Make sure the lists are lowercase, to speedup the check
- if (NoGDICaptureForProduct != null)
- {
- // Fix error in configuration
- if (NoGDICaptureForProduct.Count >= 2)
- {
- if ("intellij".Equals(NoGDICaptureForProduct[0]) && "idea".Equals(NoGDICaptureForProduct[1]))
- {
- NoGDICaptureForProduct.RemoveRange(0, 2);
- NoGDICaptureForProduct.Add("Intellij Idea");
- IsDirty = true;
- }
- }
- for (int i = 0; i < NoGDICaptureForProduct.Count; i++)
- {
- NoGDICaptureForProduct[i] = NoGDICaptureForProduct[i].ToLower();
- }
- }
- if (NoDWMCaptureForProduct != null)
- {
- // Fix error in configuration
- if (NoDWMCaptureForProduct.Count >= 3)
- {
- if ("citrix".Equals(NoDWMCaptureForProduct[0]) && "ica".Equals(NoDWMCaptureForProduct[1]) && "client".Equals(NoDWMCaptureForProduct[2]))
- {
- NoDWMCaptureForProduct.RemoveRange(0, 3);
- NoDWMCaptureForProduct.Add("Citrix ICA Client");
- IsDirty = true;
- }
- }
- for (int i = 0; i < NoDWMCaptureForProduct.Count; i++)
- {
- NoDWMCaptureForProduct[i] = NoDWMCaptureForProduct[i].ToLower();
- }
- }
-
- if (AutoCropDifference < 0)
- {
- AutoCropDifference = 0;
- }
- if (AutoCropDifference > 255)
- {
- AutoCropDifference = 255;
- }
- if (OutputFileReduceColorsTo < 2)
- {
- OutputFileReduceColorsTo = 2;
- }
- if (OutputFileReduceColorsTo > 256)
- {
- OutputFileReduceColorsTo = 256;
- }
-
- if (WebRequestTimeout <= 10)
- {
- WebRequestTimeout = 100;
- }
- if (WebRequestReadWriteTimeout < 1)
- {
- WebRequestReadWriteTimeout = 100;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Configuration/EditorConfiguration.cs b/Greenshot.ImageEditor/Configuration/EditorConfiguration.cs
deleted file mode 100644
index 4b7f512d8..000000000
--- a/Greenshot.ImageEditor/Configuration/EditorConfiguration.cs
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using Greenshot.Core;
-using Greenshot.Drawing.Fields;
-using Greenshot.IniFile;
-using Greenshot.Plugin;
-using GreenshotPlugin.UnmanagedHelpers;
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-
-namespace Greenshot.Configuration
-{
- ///
- /// Description of CoreConfiguration.
- ///
- [IniSection("Editor", Description = "Greenshot editor configuration")]
- public class EditorConfiguration : IniSection
- {
- [IniProperty("RecentColors", Separator = "|", Description = "Last used colors")]
- public List RecentColors;
-
- [IniProperty("DefaultDrawingMode", Separator = "|", Description = "Default drawing mode:None,Rect,Ellipse,Line,Arrow,Path,Text,SpeechBubble,StepLabel,Highlight,Obfuscate,Crop", DefaultValue = "Rect", FixedValue = true)]
- public DrawingModes DefaultDrawingMode;
- [IniProperty("RememberLastDrawingMode", Description = "Remember last drawing mode used and select it next time", DefaultValue = "False")]
- public bool RememberLastDrawingMode;
- [IniProperty("LastDrawingMode", Separator = "|", Description = "Last drawing mode used", DefaultValue = "Rect")]
- public DrawingModes LastDrawingMode;
-
- [IniProperty("LastFieldValue", Separator = "|", Description = "Field values, make sure the last used settings are re-used")]
- public Dictionary LastUsedFieldValues;
-
- [IniProperty("MatchSizeToCapture", Description = "Match the editor window size to the capture", DefaultValue = "True")]
- public bool MatchSizeToCapture;
- [IniProperty("MaximizeWhenLargeImage", Description = "Maximize the editor window when image is larger than the working area", DefaultValue = "False")]
- public bool MaximizeWhenLargeImage;
- [IniProperty("WindowPlacementFlags", Description = "Placement flags", DefaultValue = "0")]
- public WindowPlacementFlags WindowPlacementFlags;
- [IniProperty("WindowShowCommand", Description = "Show command", DefaultValue = "Normal")]
- public ShowWindowCommand ShowWindowCommand;
- [IniProperty("WindowMinPosition", Description = "Position of minimized window", DefaultValue = "-1,-1")]
- public Point WindowMinPosition;
- [IniProperty("WindowMaxPosition", Description = "Position of maximized window", DefaultValue = "-1,-1")]
- public Point WindowMaxPosition;
- [IniProperty("WindowNormalPosition", Description = "Position of normal window", DefaultValue = "100,100,400,400")]
- public Rectangle WindowNormalPosition;
- [IniProperty("ReuseEditor", Description = "Reuse already open editor", DefaultValue = "false")]
- public bool ReuseEditor;
- [IniProperty("FreehandSensitivity", Description = "The smaller this number, the less smoothing is used. Decrease for detailed drawing, e.g. when using a pen. Increase for smoother lines. e.g. when you want to draw a smooth line.", DefaultValue = "3")]
- public int FreehandSensitivity;
- [IniProperty("SuppressSaveDialogAtClose", Description = "Suppressed the 'do you want to save' dialog when closing the editor.", DefaultValue = "False")]
- public bool SuppressSaveDialogAtClose;
-
- [IniProperty("DropShadowEffectSettings", Description = "Settings for the drop shadow effect.")]
- public DropShadowEffect DropShadowEffectSettings;
-
- [IniProperty("TornEdgeEffectSettings", Description = "Settings for the torn edge effect.")]
- public TornEdgeEffect TornEdgeEffectSettings;
-
- public override void AfterLoad()
- {
- base.AfterLoad();
- if (RecentColors == null)
- {
- RecentColors = new List();
- }
- }
-
- /// Type of the class for which to create the field
- /// FieldType of the field to construct
- /// FieldType of the field to construct
- /// a new Field of the given fieldType, with the scope of it's value being restricted to the Type scope
- public Field CreateField(Type requestingType, FieldType fieldType, object preferredDefaultValue)
- {
- string requestingTypeName = requestingType.Name;
- string requestedField = requestingTypeName + "." + fieldType.Name;
- object fieldValue = preferredDefaultValue;
-
- // Check if the configuration exists
- if (LastUsedFieldValues == null)
- {
- LastUsedFieldValues = new Dictionary();
- }
-
- // Check if settings for the requesting type exist, if not create!
- if (LastUsedFieldValues.ContainsKey(requestedField))
- {
- // Check if a value is set (not null)!
- if (LastUsedFieldValues[requestedField] != null)
- {
- fieldValue = LastUsedFieldValues[requestedField];
- }
- else
- {
- // Overwrite null value
- LastUsedFieldValues[requestedField] = fieldValue;
- }
- }
- else
- {
- LastUsedFieldValues.Add(requestedField, fieldValue);
- }
- Field returnField = new Field(fieldType, requestingType);
- returnField.Value = fieldValue;
- return returnField;
- }
-
- public void UpdateLastFieldValue(Field field)
- {
- string requestedField = field.Scope + "." + field.FieldType.Name;
- // Check if the configuration exists
- if (LastUsedFieldValues == null)
- {
- LastUsedFieldValues = new Dictionary();
- }
- // check if settings for the requesting type exist, if not create!
- if (LastUsedFieldValues.ContainsKey(requestedField))
- {
- LastUsedFieldValues[requestedField] = field.myValue;
- }
- else
- {
- LastUsedFieldValues.Add(requestedField, field.myValue);
- }
- }
-
- public WindowPlacement GetEditorPlacement()
- {
- WindowPlacement placement = WindowPlacement.Default;
- placement.NormalPosition = new RECT(WindowNormalPosition);
- placement.MaxPosition = new POINT(WindowMaxPosition);
- placement.MinPosition = new POINT(WindowMinPosition);
- placement.ShowCmd = ShowWindowCommand;
- placement.Flags = WindowPlacementFlags;
- return placement;
- }
-
- public void SetEditorPlacement(WindowPlacement placement)
- {
- WindowNormalPosition = placement.NormalPosition.ToRectangle();
- WindowMaxPosition = placement.MaxPosition.ToPoint();
- WindowMinPosition = placement.MinPosition.ToPoint();
- ShowWindowCommand = placement.ShowCmd;
- WindowPlacementFlags = placement.Flags;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/BackgroundForm.cs b/Greenshot.ImageEditor/Controls/BackgroundForm.cs
deleted file mode 100644
index e4bbf9bfa..000000000
--- a/Greenshot.ImageEditor/Controls/BackgroundForm.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using GreenshotPlugin.Core;
-using System;
-using System.Drawing;
-using System.Threading;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- ///
- /// Description of PleaseWaitForm.
- ///
- internal partial class BackgroundForm : Form
- {
- private volatile bool _shouldClose;
-
- private void BackgroundShowDialog()
- {
- ShowDialog();
- }
-
- public static BackgroundForm ShowAndWait(string title, string text)
- {
- BackgroundForm backgroundForm = new BackgroundForm(title, text);
- // Show form in background thread
- Thread backgroundTask = new Thread(backgroundForm.BackgroundShowDialog);
- backgroundForm.Name = "Background form";
- backgroundTask.IsBackground = true;
- backgroundTask.SetApartmentState(ApartmentState.STA);
- backgroundTask.Start();
- return backgroundForm;
- }
-
- public BackgroundForm(string title, string text)
- {
- //
- // The InitializeComponent() call is required for Windows Forms designer support.
- //
- InitializeComponent();
- Icon = GreenshotResources.getGreenshotIcon();
- _shouldClose = false;
- Text = title;
- label_pleasewait.Text = text;
- FormClosing += PreventFormClose;
- timer_checkforclose.Start();
- }
-
- // Can be used instead of ShowDialog
- public new void Show()
- {
- base.Show();
- bool positioned = false;
- foreach (Screen screen in Screen.AllScreens)
- {
- if (screen.Bounds.Contains(Cursor.Position))
- {
- positioned = true;
- Location = new Point(screen.Bounds.X + (screen.Bounds.Width / 2) - (Width / 2), screen.Bounds.Y + (screen.Bounds.Height / 2) - (Height / 2));
- break;
- }
- }
- if (!positioned)
- {
- Location = new Point(Cursor.Position.X - Width / 2, Cursor.Position.Y - Height / 2);
- }
- }
-
- private void PreventFormClose(object sender, FormClosingEventArgs e)
- {
- if (!_shouldClose)
- {
- e.Cancel = true;
- }
- }
-
- private void Timer_checkforcloseTick(object sender, EventArgs e)
- {
- if (_shouldClose)
- {
- timer_checkforclose.Stop();
- BeginInvoke(new EventHandler(delegate { Close(); }));
- }
- }
-
- public void CloseDialog()
- {
- _shouldClose = true;
- Application.DoEvents();
- }
-
- private void BackgroundFormFormClosing(object sender, FormClosingEventArgs e)
- {
- timer_checkforclose.Stop();
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/BackgroundForm.designer.cs b/Greenshot.ImageEditor/Controls/BackgroundForm.designer.cs
deleted file mode 100644
index 1d1c30d28..000000000
--- a/Greenshot.ImageEditor/Controls/BackgroundForm.designer.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 .
- */
-
-namespace GreenshotPlugin.Controls
-{
- partial class BackgroundForm
- {
- ///
- /// Designer variable used to keep track of non-visual components.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Disposes resources used by the form.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing) {
- if (components != null) {
- components.Dispose();
- }
- }
- base.Dispose(disposing);
- }
-
- ///
- /// This method is required for Windows Forms designer support.
- /// Do not change the method contents inside the source code editor. The Forms designer might
- /// not be able to load this method if it was changed manually.
- ///
- private void InitializeComponent()
- {
- this.components = new System.ComponentModel.Container();
- this.label_pleasewait = new System.Windows.Forms.Label();
- this.timer_checkforclose = new System.Windows.Forms.Timer(this.components);
- this.SuspendLayout();
- //
- // label_pleasewait
- //
- this.label_pleasewait.AutoSize = true;
- this.label_pleasewait.Dock = System.Windows.Forms.DockStyle.Fill;
- this.label_pleasewait.Location = new System.Drawing.Point(0, 0);
- this.label_pleasewait.Name = "label_pleasewait";
- this.label_pleasewait.Padding = new System.Windows.Forms.Padding(10);
- this.label_pleasewait.Size = new System.Drawing.Size(90, 33);
- this.label_pleasewait.TabIndex = 0;
- this.label_pleasewait.Text = "Please wait...";
- this.label_pleasewait.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.label_pleasewait.UseWaitCursor = true;
- //
- // timer_checkforclose
- //
- this.timer_checkforclose.Interval = 200;
- this.timer_checkforclose.Tick += new System.EventHandler(this.Timer_checkforcloseTick);
- //
- // BackgroundForm
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.AutoSize = true;
- this.ClientSize = new System.Drawing.Size(169, 52);
- this.ControlBox = true;
- this.Controls.Add(this.label_pleasewait);
- this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
- this.MaximizeBox = false;
- this.MinimizeBox = false;
- this.Name = "BackgroundForm";
- this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
- this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
- this.Text = "Greenshot";
- this.TopMost = true;
- this.UseWaitCursor = true;
- this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.BackgroundFormFormClosing);
- this.ResumeLayout(false);
- this.PerformLayout();
- }
- private System.Windows.Forms.Timer timer_checkforclose;
- private System.Windows.Forms.Label label_pleasewait;
- }
-}
diff --git a/Greenshot.ImageEditor/Controls/BindableToolStripButton.cs b/Greenshot.ImageEditor/Controls/BindableToolStripButton.cs
deleted file mode 100644
index 7b45869a8..000000000
--- a/Greenshot.ImageEditor/Controls/BindableToolStripButton.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using GreenshotPlugin.Controls;
-using System;
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace Greenshot.Controls
-{
- ///
- /// Description of BindableToolStripButton.
- ///
- internal class BindableToolStripButton : ToolStripButton, INotifyPropertyChanged, IGreenshotLanguageBindable
- {
- public event PropertyChangedEventHandler PropertyChanged;
-
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
-
- public BindableToolStripButton()
- {
- CheckedChanged += BindableToolStripButton_CheckedChanged;
- }
-
- private void BindableToolStripButton_CheckedChanged(object sender, EventArgs e)
- {
- if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Checked"));
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/BindableToolStripComboBox.cs b/Greenshot.ImageEditor/Controls/BindableToolStripComboBox.cs
deleted file mode 100644
index 63e52cf51..000000000
--- a/Greenshot.ImageEditor/Controls/BindableToolStripComboBox.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using GreenshotPlugin.Controls;
-using System;
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace Greenshot.Controls
-{
- ///
- /// A simple ToolStripComboBox implementing INotifyPropertyChanged for data binding
- ///
- internal class BindableToolStripComboBox : ToolStripComboBox, INotifyPropertyChanged, IGreenshotLanguageBindable
- {
- public event PropertyChangedEventHandler PropertyChanged;
-
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
-
- public BindableToolStripComboBox()
- {
- SelectedIndexChanged += BindableToolStripComboBox_SelectedIndexChanged;
- }
-
- private void BindableToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e)
- {
- if (PropertyChanged != null)
- {
- PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/BindableToolStripDropDownButton.cs b/Greenshot.ImageEditor/Controls/BindableToolStripDropDownButton.cs
deleted file mode 100644
index 1848ac25f..000000000
--- a/Greenshot.ImageEditor/Controls/BindableToolStripDropDownButton.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using GreenshotPlugin.Controls;
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace Greenshot.Controls
-{
- ///
- /// A simple ToolStripDropDownButton implementing INotifyPropertyChanged for data binding.
- /// Also, when a DropDownItem is selected, the DropDownButton adopts its Tag and Image.
- /// The selected tag can be accessed via SelectedTag property.
- ///
- internal class BindableToolStripDropDownButton : ToolStripDropDownButton, INotifyPropertyChanged, IGreenshotLanguageBindable
- {
- public event PropertyChangedEventHandler PropertyChanged;
-
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
-
- public object SelectedTag
- {
- get { if (Tag == null && DropDownItems.Count > 0) Tag = DropDownItems[0].Tag; return Tag; }
- set { AdoptFromTag(value); }
- }
-
- protected override void OnDropDownItemClicked(ToolStripItemClickedEventArgs e)
- {
- ToolStripItem clickedItem = e.ClickedItem;
- if (Tag == null || !Tag.Equals(clickedItem.Tag))
- {
- Tag = clickedItem.Tag;
- Image = clickedItem.Image;
- if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SelectedTag"));
- }
- base.OnDropDownItemClicked(e);
- }
-
- private void AdoptFromTag(object tag)
- {
- if (Tag == null || !Tag.Equals(tag))
- {
- Tag = tag;
- foreach (ToolStripItem item in DropDownItems)
- {
- if (item.Tag != null && item.Tag.Equals(tag))
- {
- Image = item.Image;
- break;
- }
- }
- Tag = tag;
- if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SelectedTag"));
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/ColorButton.cs b/Greenshot.ImageEditor/Controls/ColorButton.cs
deleted file mode 100644
index 5edd69dc7..000000000
--- a/Greenshot.ImageEditor/Controls/ColorButton.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using GreenshotPlugin.Controls;
-using System;
-using System.ComponentModel;
-using System.Drawing;
-using System.Drawing.Drawing2D;
-using System.Windows.Forms;
-
-namespace Greenshot.Controls
-{
- ///
- /// Description of ColorButton.
- ///
- internal class ColorButton : Button, IGreenshotLanguageBindable
- {
- public event PropertyChangedEventHandler PropertyChanged;
- private Color selectedColor = Color.White;
-
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
-
- public ColorButton()
- {
- Click += ColorButtonClick;
- }
-
- public Color SelectedColor
- {
- get
- {
- return selectedColor;
- }
- set
- {
- selectedColor = value;
-
- Brush brush;
- if (value != Color.Transparent)
- {
- brush = new SolidBrush(value);
- }
- else
- {
- brush = new HatchBrush(HatchStyle.Percent50, Color.White, Color.Gray);
- }
-
- if (Image != null)
- {
- using (Graphics graphics = Graphics.FromImage(Image))
- {
- graphics.FillRectangle(brush, new Rectangle(4, 17, 16, 3));
- }
- }
-
- // cleanup GDI Object
- brush.Dispose();
- Invalidate();
- }
- }
-
- private void ColorButtonClick(object sender, EventArgs e)
- {
- ColorDialog colorDialog = ColorDialog.GetInstance();
- colorDialog.Color = SelectedColor;
- // Using the parent to make sure the dialog doesn't show on another window
- colorDialog.ShowDialog(Parent.Parent);
- if (colorDialog.DialogResult != DialogResult.Cancel)
- {
- if (!colorDialog.Color.Equals(SelectedColor))
- {
- SelectedColor = colorDialog.Color;
- if (PropertyChanged != null)
- {
- PropertyChanged(this, new PropertyChangedEventArgs("SelectedColor"));
- }
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/CustomToolStripProfessionalRenderer.cs b/Greenshot.ImageEditor/Controls/CustomToolStripProfessionalRenderer.cs
deleted file mode 100644
index 43111a455..000000000
--- a/Greenshot.ImageEditor/Controls/CustomToolStripProfessionalRenderer.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace Greenshot.Controls
-{
- ///
- /// Prevent having a gradient background in the toolstrip, and the overflow button
- /// See: http://stackoverflow.com/a/16926979
- ///
- internal class CustomProfessionalColorTable : ProfessionalColorTable
- {
- public override Color ToolStripGradientBegin
- {
- get { return SystemColors.Control; }
- }
- public override Color ToolStripGradientMiddle
- {
- get { return SystemColors.Control; }
- }
- public override Color ToolStripGradientEnd
- {
- get { return SystemColors.Control; }
- }
- public override Color OverflowButtonGradientBegin
- {
- get { return SystemColors.Control; }
- }
- public override Color OverflowButtonGradientMiddle
- {
- get { return SystemColors.Control; }
- }
- public override Color OverflowButtonGradientEnd
- {
- get { return SystemColors.Control; }
- }
- }
-
- ///
- /// ToolStripProfessionalRenderer without having a visual artifact
- /// See: http://stackoverflow.com/a/16926979 and http://stackoverflow.com/a/13418840
- ///
- internal class CustomToolStripProfessionalRenderer : ToolStripProfessionalRenderer
- {
- public CustomToolStripProfessionalRenderer() : base(new CustomProfessionalColorTable())
- {
- RoundedEdges = false;
- }
-
- ///
- /// By overriding the OnRenderToolStripBorder we can make the ToolStrip without border
- ///
- ///
- protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
- {
- // Don't draw a border
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/FontFamilyComboBox.cs b/Greenshot.ImageEditor/Controls/FontFamilyComboBox.cs
deleted file mode 100644
index 7bcf4bef6..000000000
--- a/Greenshot.ImageEditor/Controls/FontFamilyComboBox.cs
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-using System.ComponentModel;
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace Greenshot.Controls
-{
- ///
- /// ToolStripComboBox containing installed font families,
- /// implementing INotifyPropertyChanged for data binding
- ///
- internal class FontFamilyComboBox : ToolStripComboBox, INotifyPropertyChanged
- {
- public event PropertyChangedEventHandler PropertyChanged;
-
- public FontFamily FontFamily
- {
- get
- {
- return (FontFamily)SelectedItem;
- }
- set
- {
- if (!SelectedItem.Equals(value))
- {
- SelectedItem = value;
- }
- }
- }
-
- public FontFamilyComboBox() : base()
- {
- if (ComboBox != null)
- {
- ComboBox.DataSource = FontFamily.Families;
- ComboBox.DisplayMember = "Name";
- SelectedIndexChanged += BindableToolStripComboBox_SelectedIndexChanged;
- ComboBox.DrawMode = DrawMode.OwnerDrawFixed;
- ComboBox.DrawItem += ComboBox_DrawItem;
- }
- }
-
- private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
- {
- // DrawBackground handles drawing the background (i.e,. hot-tracked v. not)
- // It uses the system colors (Bluish, and and white, by default)
- // same as calling e.Graphics.FillRectangle ( SystemBrushes.Highlight, e.Bounds );
- e.DrawBackground();
-
- if (e.Index > -1)
- {
- FontFamily fontFamily = Items[e.Index] as FontFamily;
- FontStyle fontStyle = FontStyle.Regular;
- if (fontFamily != null && !fontFamily.IsStyleAvailable(FontStyle.Regular))
- {
- if (fontFamily.IsStyleAvailable(FontStyle.Bold))
- {
- fontStyle = FontStyle.Bold;
- }
- else if (fontFamily.IsStyleAvailable(FontStyle.Italic))
- {
- fontStyle = FontStyle.Italic;
- }
- else if (fontFamily.IsStyleAvailable(FontStyle.Strikeout))
- {
- fontStyle = FontStyle.Strikeout;
- }
- else if (fontFamily.IsStyleAvailable(FontStyle.Underline))
- {
- fontStyle = FontStyle.Underline;
- }
- }
- try
- {
- if (fontFamily != null)
- {
- DrawText(e.Graphics, fontFamily, fontStyle, e.Bounds, fontFamily.Name);
- }
- }
- catch
- {
- if (fontFamily != null)
- {
- // If the drawing failed, BUG-1770 seems to have a weird case that causes: Font 'Lucida Sans Typewriter' does not support style 'Regular'
- DrawText(e.Graphics, FontFamily.GenericSansSerif, FontStyle.Regular, e.Bounds, fontFamily.Name);
- }
- }
- }
- // Uncomment this if you actually like the way the focus rectangle looks
- //e.DrawFocusRectangle ();
- }
-
- ///
- /// Helper method to draw the string
- ///
- ///
- ///
- ///
- ///
- ///
- private void DrawText(Graphics graphics, FontFamily fontFamily, FontStyle fontStyle, Rectangle bounds, string text)
- {
- using (Font font = new Font(fontFamily, Font.Size + 5, fontStyle, GraphicsUnit.Pixel))
- {
- // Make sure the text is visible by centering it in the line
- using (StringFormat stringFormat = new StringFormat())
- {
- stringFormat.LineAlignment = StringAlignment.Center;
- graphics.DrawString(text, font, Brushes.Black, bounds, stringFormat);
- }
- }
- }
-
- private void BindableToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e)
- {
- if (PropertyChanged != null)
- {
- PropertyChanged(this, new PropertyChangedEventArgs("Text"));
- PropertyChanged(this, new PropertyChangedEventArgs("FontFamily"));
- PropertyChanged(this, new PropertyChangedEventArgs("SelectedIndex"));
- PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/FormWithoutActivation.cs b/Greenshot.ImageEditor/Controls/FormWithoutActivation.cs
deleted file mode 100644
index 71950d53d..000000000
--- a/Greenshot.ImageEditor/Controls/FormWithoutActivation.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- ///
- /// FormWithoutActivation is exactly like a normal form, but doesn't activate (steal focus)
- ///
- internal class FormWithoutActivation : Form
- {
- protected override bool ShowWithoutActivation
- {
- get { return true; }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotButton.cs b/Greenshot.ImageEditor/Controls/GreenshotButton.cs
deleted file mode 100644
index 28f8af8ec..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotButton.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- internal class GreenshotButton : Button, IGreenshotLanguageBindable
- {
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotCheckBox.cs b/Greenshot.ImageEditor/Controls/GreenshotCheckBox.cs
deleted file mode 100644
index cd70b69c7..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotCheckBox.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- ///
- /// Description of GreenshotCheckbox.
- ///
- internal class GreenshotCheckBox : CheckBox, IGreenshotLanguageBindable, IGreenshotConfigBindable
- {
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
-
- [Category("Greenshot"), DefaultValue("Core"), Description("Specifies the Ini-Section to map this control with.")]
- public string SectionName { get; set; } = "Core";
-
- [Category("Greenshot"), DefaultValue(null), Description("Specifies the property name to map the configuration.")]
- public string PropertyName
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotColumnSorter.cs b/Greenshot.ImageEditor/Controls/GreenshotColumnSorter.cs
deleted file mode 100644
index 8c4bb17b2..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotColumnSorter.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.Collections;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- ///
- /// This class is an implementation of the 'IComparer' interface.
- ///
- internal class GreenshotColumnSorter : IComparer
- {
- ///
- /// Specifies the column to be sorted
- ///
- private int _columnToSort;
- ///
- /// Specifies the order in which to sort (i.e. 'Ascending').
- ///
- private SortOrder _orderOfSort;
- ///
- /// Case insensitive comparer object
- ///
- private readonly CaseInsensitiveComparer _objectCompare;
-
- ///
- /// Class constructor. Initializes various elements
- ///
- public GreenshotColumnSorter()
- {
- // Initialize the column to '0'
- _columnToSort = 0;
-
- // Initialize the sort order to 'none'
- _orderOfSort = SortOrder.None;
-
- // Initialize the CaseInsensitiveComparer object
- _objectCompare = new CaseInsensitiveComparer();
- }
-
- ///
- /// This method is inherited from the IComparer interface. It compares the two objects passed using a case insensitive comparison.
- ///
- /// First object to be compared
- /// Second object to be compared
- /// The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'
- public int Compare(object x, object y)
- {
- if (x == null && y == null)
- {
- return 0;
- }
- if (x == null)
- {
- return -1;
- }
- if (y == null)
- {
- return 1;
- }
- // Cast the objects to be compared to ListViewItem objects
- var listviewX = (ListViewItem)x;
- var listviewY = (ListViewItem)y;
-
- // Compare the two items
- var compareResult = _objectCompare.Compare(listviewX.SubItems[_columnToSort].Text, listviewY.SubItems[_columnToSort].Text);
-
- // Calculate correct return value based on object comparison
- if (_orderOfSort == SortOrder.Ascending)
- {
- // Ascending sort is selected, return normal result of compare operation
- return compareResult;
- }
- if (_orderOfSort == SortOrder.Descending)
- {
- // Descending sort is selected, return negative result of compare operation
- return (-compareResult);
- }
-
- // Return '0' to indicate they are equal
- return 0;
- }
-
- ///
- /// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0').
- ///
- public int SortColumn
- {
- set
- {
- _columnToSort = value;
- }
- get
- {
- return _columnToSort;
- }
- }
-
- ///
- /// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending').
- ///
- public SortOrder Order
- {
- set
- {
- _orderOfSort = value;
- }
- get
- {
- return _orderOfSort;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotComboBox.cs b/Greenshot.ImageEditor/Controls/GreenshotComboBox.cs
deleted file mode 100644
index 40b43dbb0..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotComboBox.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- internal class GreenshotComboBox : ComboBox, IGreenshotConfigBindable
- {
- private Type _enumType = null;
- private Enum _selectedEnum = null;
-
- [Category("Greenshot"), DefaultValue("Core"), Description("Specifies the Ini-Section to map this control with.")]
- public string SectionName { get; set; } = "Core";
-
- [Category("Greenshot"), DefaultValue(null), Description("Specifies the property name to map the configuration.")]
- public string PropertyName
- {
- get;
- set;
- }
-
- public GreenshotComboBox()
- {
- SelectedIndexChanged += delegate
- {
- StoreSelectedEnum();
- };
- }
-
- public void SetValue(Enum currentValue)
- {
- if (currentValue != null)
- {
- _selectedEnum = currentValue;
- SelectedItem = currentValue;
- }
- }
-
- ///
- /// This is a method to popululate the ComboBox
- /// with the items from the enumeration
- ///
- /// TEnum to populate with
- public void Populate(Type enumType)
- {
- // Store the enum-type, so we can work with it
- _enumType = enumType;
-
- var availableValues = Enum.GetValues(enumType);
- Items.Clear();
- foreach (var enumValue in availableValues)
- {
- Items.Add(enumValue);
- }
- }
-
- ///
- /// Store the selected value internally
- ///
- private void StoreSelectedEnum()
- {
- string enumTypeName = _enumType.Name;
- string selectedValue = SelectedItem as string;
- var availableValues = Enum.GetValues(_enumType);
- object returnValue = null;
-
- try
- {
- returnValue = Enum.Parse(_enumType, selectedValue);
- }
- catch (Exception)
- {
- }
-
- _selectedEnum = (Enum)returnValue;
- }
-
- ///
- /// Get the selected enum value from the combobox, uses generics
- ///
- /// The enum value of the combobox
- public Enum GetSelectedEnum()
- {
- return _selectedEnum;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotForm.cs b/Greenshot.ImageEditor/Controls/GreenshotForm.cs
deleted file mode 100644
index f22652b31..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotForm.cs
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using Greenshot.IniFile;
-using GreenshotPlugin.Core;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.ComponentModel.Design;
-using System.Reflection;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- ///
- /// This form is used for automatically binding the elements of the form to the language
- ///
- public class GreenshotForm : Form, IGreenshotLanguageBindable
- {
- protected static CoreConfiguration coreConfiguration;
- private static readonly IDictionary reflectionCache = new Dictionary();
- private IComponentChangeService m_changeService;
- private bool _storeFieldsManually;
- private IDictionary _designTimeControls;
- private IDictionary _designTimeToolStripItems;
-
- static GreenshotForm()
- {
- if (!IsInDesignMode)
- {
- coreConfiguration = IniConfig.GetIniSection();
- }
- }
-
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
-
- ///
- /// Used to check the designmode during a constructor
- ///
- ///
- protected static bool IsInDesignMode
- {
- get
- {
- return (Application.ExecutablePath.IndexOf("devenv.exe", StringComparison.OrdinalIgnoreCase) > -1) || (Application.ExecutablePath.IndexOf("sharpdevelop.exe", StringComparison.OrdinalIgnoreCase) > -1 || (Application.ExecutablePath.IndexOf("wdexpress.exe", StringComparison.OrdinalIgnoreCase) > -1));
- }
- }
-
- protected bool ManualStoreFields
- {
- get
- {
- return _storeFieldsManually;
- }
- set
- {
- _storeFieldsManually = value;
- }
- }
-
- ///
- /// When this is set, the form will be brought to the foreground as soon as it is shown.
- ///
- protected bool ToFront
- {
- get;
- set;
- }
-
- ///
- /// Code to initialize the language etc during design time
- ///
- protected void InitializeForDesigner()
- {
- if (DesignMode)
- {
- _designTimeControls = new Dictionary();
- _designTimeToolStripItems = new Dictionary();
- }
- }
-
- protected override void OnLoad(EventArgs e)
- {
- // Every GreenshotForm should have it's default icon
- // And it might not ne needed for a Tool Window, but still for the task manager / switcher it's important
- Icon = GreenshotResources.getGreenshotIcon();
- if (!DesignMode)
- {
- FillFields();
- base.OnLoad(e);
- }
- else
- {
- LOG.Info("OnLoad called from designer.");
- InitializeForDesigner();
- base.OnLoad(e);
- }
- }
-
- ///
- /// Make sure the form is visible, if this is wanted
- ///
- /// EventArgs
- protected override void OnShown(EventArgs e)
- {
- base.OnShown(e);
- if (ToFront)
- {
- WindowDetails.ToForeground(Handle);
- }
- }
-
- ///
- /// check if the form was closed with an OK, if so store the values in the GreenshotControls
- ///
- ///
- protected override void OnClosed(EventArgs e)
- {
- if (!DesignMode && !_storeFieldsManually)
- {
- if (DialogResult == DialogResult.OK)
- {
- LOG.Info("Form was closed with OK: storing field values.");
- StoreFields();
- }
- }
- base.OnClosed(e);
- }
-
- ///
- /// This override allows the control to register event handlers for IComponentChangeService events
- /// at the time the control is sited, which happens only in design mode.
- ///
- public override ISite Site
- {
- get
- {
- return base.Site;
- }
- set
- {
- // Clear any component change event handlers.
- ClearChangeNotifications();
-
- // Set the new Site value.
- base.Site = value;
-
- m_changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService));
-
- // Register event handlers for component change events.
- RegisterChangeNotifications();
- }
- }
-
- private void ClearChangeNotifications()
- {
- // The m_changeService value is null when not in design mode,
- // as the IComponentChangeService is only available at design time.
- m_changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService));
-
- // Clear our the component change events to prepare for re-siting.
- if (m_changeService != null)
- {
- m_changeService.ComponentAdded -= OnComponentAdded;
- }
- }
-
- private void RegisterChangeNotifications()
- {
- // Register the event handlers for the IComponentChangeService events
- if (m_changeService != null)
- {
- m_changeService.ComponentAdded += OnComponentAdded;
- }
- }
-
- private void OnComponentAdded(object sender, ComponentEventArgs ce)
- {
- if (ce.Component != null && ((IComponent)ce.Component).Site != null)
- {
- Control control = ce.Component as Control;
- if (control != null)
- {
- if (!_designTimeControls.ContainsKey(control.Name))
- {
- _designTimeControls.Add(control.Name, control);
- }
- else
- {
- _designTimeControls[control.Name] = control;
- }
- }
- else if (ce.Component is ToolStripItem)
- {
- ToolStripItem item = ce.Component as ToolStripItem;
- if (!_designTimeControls.ContainsKey(item.Name))
- {
- _designTimeToolStripItems.Add(item.Name, item);
- }
- else
- {
- _designTimeToolStripItems[item.Name] = item;
- }
- }
- }
- }
-
- // Clean up any resources being used.
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- ClearChangeNotifications();
- }
- base.Dispose(disposing);
- }
-
- ///
- /// Helper method to cache the fieldinfo values, so we don't need to reflect all the time!
- ///
- ///
- ///
- private static FieldInfo[] GetCachedFields(Type typeToGetFieldsFor)
- {
- FieldInfo[] fields = null;
- if (!reflectionCache.TryGetValue(typeToGetFieldsFor, out fields))
- {
- fields = typeToGetFieldsFor.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
- reflectionCache.Add(typeToGetFieldsFor, fields);
- }
- return fields;
- }
-
- ///
- /// Fill all GreenshotControls with the values from the configuration
- ///
- protected void FillFields()
- {
- foreach (FieldInfo field in GetCachedFields(GetType()))
- {
- Object controlObject = field.GetValue(this);
- if (controlObject == null)
- {
- continue;
- }
- IGreenshotConfigBindable configBindable = controlObject as IGreenshotConfigBindable;
- if (configBindable == null)
- {
- continue;
- }
- if (!string.IsNullOrEmpty(configBindable.SectionName) && !string.IsNullOrEmpty(configBindable.PropertyName))
- {
- IniSection section = IniConfig.GetIniSection(configBindable.SectionName);
- if (section != null)
- {
- IniValue iniValue = null;
- if (!section.Values.TryGetValue(configBindable.PropertyName, out iniValue))
- {
- LOG.DebugFormat("Wrong property '{0}' configured for field '{1}'", configBindable.PropertyName, field.Name);
- continue;
- }
-
- CheckBox checkBox = controlObject as CheckBox;
- if (checkBox != null)
- {
- checkBox.Checked = (bool)iniValue.Value;
- checkBox.Enabled = !iniValue.IsFixed;
- continue;
- }
- RadioButton radÃoButton = controlObject as RadioButton;
- if (radÃoButton != null)
- {
- radÃoButton.Checked = (bool)iniValue.Value;
- radÃoButton.Enabled = !iniValue.IsFixed;
- continue;
- }
- GreenshotComboBox comboxBox = controlObject as GreenshotComboBox;
- if (comboxBox != null)
- {
- comboxBox.Populate(iniValue.ValueType);
- comboxBox.SetValue((Enum)iniValue.Value);
- comboxBox.Enabled = !iniValue.IsFixed;
- }
- }
- }
- }
- OnFieldsFilled();
- }
-
- protected virtual void OnFieldsFilled()
- {
- }
-
- ///
- /// Store all GreenshotControl values to the configuration
- ///
- protected void StoreFields()
- {
- bool iniDirty = false;
- foreach (FieldInfo field in GetCachedFields(GetType()))
- {
- Object controlObject = field.GetValue(this);
- if (controlObject == null)
- {
- continue;
- }
- IGreenshotConfigBindable configBindable = controlObject as IGreenshotConfigBindable;
- if (configBindable == null)
- {
- continue;
- }
-
- if (!string.IsNullOrEmpty(configBindable.SectionName) && !string.IsNullOrEmpty(configBindable.PropertyName))
- {
- IniSection section = IniConfig.GetIniSection(configBindable.SectionName);
- if (section != null)
- {
- IniValue iniValue = null;
- if (!section.Values.TryGetValue(configBindable.PropertyName, out iniValue))
- {
- continue;
- }
- CheckBox checkBox = controlObject as CheckBox;
- if (checkBox != null)
- {
- iniValue.Value = checkBox.Checked;
- iniDirty = true;
- continue;
- }
- RadioButton radioButton = controlObject as RadioButton;
- if (radioButton != null)
- {
- iniValue.Value = radioButton.Checked;
- iniDirty = true;
- continue;
- }
- GreenshotComboBox comboxBox = controlObject as GreenshotComboBox;
- if (comboxBox != null)
- {
- iniValue.Value = comboxBox.GetSelectedEnum();
- iniDirty = true;
- continue;
- }
- }
- }
- }
- if (iniDirty)
- {
- //IniConfig.Save();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotGroupBox.cs b/Greenshot.ImageEditor/Controls/GreenshotGroupBox.cs
deleted file mode 100644
index eff5753dd..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotGroupBox.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- internal class GreenshotGroupBox : GroupBox, IGreenshotLanguageBindable
- {
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotLabel.cs b/Greenshot.ImageEditor/Controls/GreenshotLabel.cs
deleted file mode 100644
index 5743154f0..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotLabel.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- internal class GreenshotLabel : Label, IGreenshotLanguageBindable
- {
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotRadioButton.cs b/Greenshot.ImageEditor/Controls/GreenshotRadioButton.cs
deleted file mode 100644
index 34e780b04..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotRadioButton.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- ///
- /// Description of GreenshotCheckbox.
- ///
- internal class GreenshotRadioButton : RadioButton, IGreenshotLanguageBindable, IGreenshotConfigBindable
- {
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
-
- private string sectionName = "Core";
- [Category("Greenshot"), DefaultValue("Core"), Description("Specifies the Ini-Section to map this control with.")]
- public string SectionName
- {
- get
- {
- return sectionName;
- }
- set
- {
- sectionName = value;
- }
- }
-
- [Category("Greenshot"), DefaultValue(null), Description("Specifies the property name to map the configuration.")]
- public string PropertyName
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotTabPage.cs b/Greenshot.ImageEditor/Controls/GreenshotTabPage.cs
deleted file mode 100644
index d9878fc60..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotTabPage.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- internal class GreenshotTabPage : TabPage, IGreenshotLanguageBindable
- {
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotTextBox.cs b/Greenshot.ImageEditor/Controls/GreenshotTextBox.cs
deleted file mode 100644
index c95a1a025..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotTextBox.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- internal class GreenshotTextBox : TextBox, IGreenshotConfigBindable
- {
- [Category("Greenshot"), DefaultValue("Core"), Description("Specifies the Ini-Section to map this control with.")]
- public string SectionName { get; set; } = "Core";
-
- [Category("Greenshot"), DefaultValue(null), Description("Specifies the property name to map the configuration.")]
- public string PropertyName
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotToolDropDownButton.cs b/Greenshot.ImageEditor/Controls/GreenshotToolDropDownButton.cs
deleted file mode 100644
index a1dec74e0..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotToolDropDownButton.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- internal class GreenshotToolStripDropDownButton : ToolStripDropDownButton, IGreenshotLanguageBindable
- {
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotToolStripButton.cs b/Greenshot.ImageEditor/Controls/GreenshotToolStripButton.cs
deleted file mode 100644
index fea02e5f4..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotToolStripButton.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- internal class GreenshotToolStripButton : ToolStripButton, IGreenshotLanguageBindable
- {
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotToolStripLabel.cs b/Greenshot.ImageEditor/Controls/GreenshotToolStripLabel.cs
deleted file mode 100644
index 7835c0b22..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotToolStripLabel.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- internal class GreenshotToolStripLabel : ToolStripLabel, IGreenshotLanguageBindable
- {
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/GreenshotToolStripMenuItem.cs b/Greenshot.ImageEditor/Controls/GreenshotToolStripMenuItem.cs
deleted file mode 100644
index 81b037881..000000000
--- a/Greenshot.ImageEditor/Controls/GreenshotToolStripMenuItem.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- internal class GreenshotToolStripMenuItem : ToolStripMenuItem, IGreenshotLanguageBindable
- {
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/IGreenshotConfigBindable.cs b/Greenshot.ImageEditor/Controls/IGreenshotConfigBindable.cs
deleted file mode 100644
index 7121849ff..000000000
--- a/Greenshot.ImageEditor/Controls/IGreenshotConfigBindable.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 .
- */
-
-namespace GreenshotPlugin.Controls
-{
- internal interface IGreenshotConfigBindable
- {
- ///
- /// The class where the property-value is stored
- ///
- string SectionName
- {
- get;
- set;
- }
-
- ///
- /// Path to the property value which will be mapped with this control
- ///
- string PropertyName
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/IGreenshotLanguageBindable.cs b/Greenshot.ImageEditor/Controls/IGreenshotLanguageBindable.cs
deleted file mode 100644
index a7531aa92..000000000
--- a/Greenshot.ImageEditor/Controls/IGreenshotLanguageBindable.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 .
- */
-
-namespace GreenshotPlugin.Controls
-{
- ///
- /// This interface describes the designer fields that need to be implemented for Greenshot controls
- ///
- internal interface IGreenshotLanguageBindable
- {
- ///
- /// Language key to use to fill the Text value with
- ///
- string LanguageKey
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/MenuStripEx.cs b/Greenshot.ImageEditor/Controls/MenuStripEx.cs
deleted file mode 100644
index f890b05df..000000000
--- a/Greenshot.ImageEditor/Controls/MenuStripEx.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-using System.Windows.Forms;
-
-namespace Greenshot.Controls
-{
- ///
- /// This is an extension of the default MenuStrip and allows us to click it even when the form doesn't have focus.
- /// See: http://blogs.msdn.com/b/rickbrew/archive/2006/01/09/511003.aspx
- ///
- internal class MenuStripEx : MenuStrip
- {
- private const int WM_MOUSEACTIVATE = 0x21;
-
- private enum NativeConstants : uint
- {
- MA_ACTIVATE = 1,
- MA_ACTIVATEANDEAT = 2,
- }
-
- private bool _clickThrough;
- ///
- /// Gets or sets whether the ToolStripEx honors item clicks when its containing form does not have input focus.
- ///
- ///
- /// Default value is false, which is the same behavior provided by the base ToolStrip class.
- ///
- public bool ClickThrough
- {
- get
- {
- return _clickThrough;
- }
-
- set
- {
- _clickThrough = value;
- }
- }
-
- protected override void WndProc(ref Message m)
- {
- base.WndProc(ref m);
- if (_clickThrough && m.Msg == WM_MOUSEACTIVATE && m.Result == (IntPtr)NativeConstants.MA_ACTIVATEANDEAT)
- {
- m.Result = (IntPtr)NativeConstants.MA_ACTIVATE;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/NonJumpingPanel.cs b/Greenshot.ImageEditor/Controls/NonJumpingPanel.cs
deleted file mode 100644
index f0c336a57..000000000
--- a/Greenshot.ImageEditor/Controls/NonJumpingPanel.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- ///
- /// See: http://nickstips.wordpress.com/2010/03/03/c-panel-resets-scroll-position-after-focus-is-lost-and-regained/
- ///
- internal class NonJumpingPanel : Panel
- {
- protected override Point ScrollToControl(Control activeControl)
- {
- // Returning the current location prevents the panel from
- // scrolling to the active control when the panel loses and regains focus
- return DisplayRectangle.Location;
- }
-
- ///
- /// Add horizontal scrolling to the panel, when using the wheel and the shift key is pressed
- ///
- /// MouseEventArgs
- protected override void OnMouseWheel(MouseEventArgs e)
- {
- if (VScroll && (ModifierKeys & Keys.Shift) == Keys.Shift)
- {
- VScroll = false;
- base.OnMouseWheel(e);
- VScroll = true;
- }
- else
- {
- base.OnMouseWheel(e);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/Pipette.cs b/Greenshot.ImageEditor/Controls/Pipette.cs
deleted file mode 100644
index 5e530eb55..000000000
--- a/Greenshot.ImageEditor/Controls/Pipette.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using Greenshot.Forms;
-using GreenshotPlugin.UnmanagedHelpers;
-using System;
-using System.ComponentModel;
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace Greenshot.Controls
-{
- ///
- /// This code was supplied by Hi-Coder as a patch for Greenshot
- /// Needed some modifications to be stable.
- ///
- internal class Pipette : Label, IMessageFilter, IDisposable
- {
- private MovableShowColorForm movableShowColorForm;
- private bool dragging;
- private Cursor _cursor;
- private readonly Bitmap _image;
- private const int VK_ESC = 27;
-
- public event EventHandler PipetteUsed;
-
- public Pipette()
- {
- BorderStyle = BorderStyle.FixedSingle;
- dragging = false;
- _image = (Bitmap)new ComponentResourceManager(typeof(ColorDialog)).GetObject("pipette.Image");
- Image = _image;
- _cursor = CreateCursor((Bitmap)_image, 1, 14);
- movableShowColorForm = new MovableShowColorForm();
- Application.AddMessageFilter(this);
- }
-
- ///
- /// Create a cursor from the supplied bitmap & hotspot coordinates
- ///
- /// Bitmap to create an icon from
- /// Hotspot X coordinate
- /// Hotspot Y coordinate
- /// Cursor
- private static Cursor CreateCursor(Bitmap bitmap, int hotspotX, int hotspotY)
- {
- using (SafeIconHandle iconHandle = new SafeIconHandle(bitmap.GetHicon()))
- {
- IntPtr icon;
- IconInfo iconInfo = new IconInfo();
- User32.GetIconInfo(iconHandle, out iconInfo);
- iconInfo.xHotspot = hotspotX;
- iconInfo.yHotspot = hotspotY;
- iconInfo.fIcon = false;
- icon = User32.CreateIconIndirect(ref iconInfo);
- return new Cursor(icon);
- }
- }
-
- ///
- /// The bulk of the clean-up code is implemented in Dispose(bool)
- ///
- public new void Dispose()
- {
- Dispose(true);
- }
-
- ///
- /// This Dispose is called from the Dispose and the Destructor.
- ///
- /// When disposing==true all non-managed resources should be freed too!
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (_cursor != null)
- {
- _cursor.Dispose();
- }
- if (movableShowColorForm != null)
- {
- movableShowColorForm.Dispose();
- }
- }
- movableShowColorForm = null;
- _cursor = null;
- base.Dispose(disposing);
- }
-
- ///
- /// Handle the mouse down on the Pipette "label", we take the capture and move the zoomer to the current location
- ///
- /// MouseEventArgs
- protected override void OnMouseDown(MouseEventArgs e)
- {
- if (e.Button == MouseButtons.Left)
- {
- User32.SetCapture(Handle);
- movableShowColorForm.MoveTo(PointToScreen(new Point(e.X, e.Y)));
- }
- base.OnMouseDown(e);
- }
-
- ///
- /// Handle the mouse up on the Pipette "label", we release the capture and fire the PipetteUsed event
- ///
- /// MouseEventArgs
- protected override void OnMouseUp(MouseEventArgs e)
- {
- if (e.Button == MouseButtons.Left)
- {
- //Release Capture should consume MouseUp when canceled with the escape key
- User32.ReleaseCapture();
- if (PipetteUsed != null)
- {
- PipetteUsed(this, new PipetteUsedArgs(movableShowColorForm.color));
- }
- }
- base.OnMouseUp(e);
- }
-
- ///
- /// Handle the mouse Move event, we move the ColorUnderCursor to the current location.
- ///
- /// MouseEventArgs
- protected override void OnMouseMove(MouseEventArgs e)
- {
- if (dragging)
- {
- //display the form on the right side of the cursor by default;
- Point zp = PointToScreen(new Point(e.X, e.Y));
- movableShowColorForm.MoveTo(zp);
- }
- base.OnMouseMove(e);
- }
-
- ///
- /// Handle the MouseCaptureChanged event
- ///
- ///
- protected override void OnMouseCaptureChanged(EventArgs e)
- {
- if (Capture)
- {
- dragging = true;
- Image = null;
- Cursor c = _cursor;
- Cursor = c;
- movableShowColorForm.Visible = true;
- }
- else
- {
- dragging = false;
- Image = _image;
- Cursor = Cursors.Arrow;
- movableShowColorForm.Visible = false;
- }
- Update();
- base.OnMouseCaptureChanged(e);
- }
-
- #region IMessageFilter Members
-
- public bool PreFilterMessage(ref Message m)
- {
- if (dragging)
- {
- if (m.Msg == (int)WindowsMessages.WM_CHAR)
- {
- if ((int)m.WParam == VK_ESC)
- {
- User32.ReleaseCapture();
- }
- }
- }
- return false;
- }
-
- #endregion IMessageFilter Members
- }
-
- public class PipetteUsedArgs : EventArgs
- {
- public Color color;
-
- public PipetteUsedArgs(Color c)
- {
- color = c;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/PleaseWaitForm.cs b/Greenshot.ImageEditor/Controls/PleaseWaitForm.cs
deleted file mode 100644
index ac168d48f..000000000
--- a/Greenshot.ImageEditor/Controls/PleaseWaitForm.cs
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using GreenshotPlugin.Core;
-using System;
-using System.Threading;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- ///
- /// Description of PleaseWaitForm.
- ///
- internal partial class PleaseWaitForm : Form
- {
- private Thread waitFor;
- private string title;
-
- public PleaseWaitForm()
- {
- //
- // The InitializeComponent() call is required for Windows Forms designer support.
- //
- InitializeComponent();
- Icon = GreenshotResources.getGreenshotIcon();
- }
-
- ///
- /// Prevent the close-window button showing
- ///
- private const int CP_NOCLOSE_BUTTON = 0x200;
- protected override CreateParams CreateParams
- {
- get
- {
- CreateParams createParams = base.CreateParams;
- createParams.ClassStyle = createParams.ClassStyle | CP_NOCLOSE_BUTTON;
- return createParams;
- }
- }
-
- ///
- /// Show the "please wait" form, execute the code from the delegate and wait until execution finishes.
- /// The supplied delegate will be wrapped with a try/catch so this method can return any exception that was thrown.
- ///
- /// The title of the form (and Thread)
- /// The text in the form
- /// delegate { with your code }
- public void ShowAndWait(string title, string text, ThreadStart waitDelegate)
- {
- this.title = title;
- Text = title;
- label_pleasewait.Text = text;
- cancelButton.Text = "Cancel";
-
- // Make sure the form is shown.
- Show();
-
- // Variable to store the exception, if one is generated, from inside the thread.
- Exception threadException = null;
- try
- {
- // Wrap the passed delegate in a try/catch which makes it possible to save the exception
- waitFor = new Thread(new ThreadStart(
- delegate
- {
- try
- {
- waitDelegate.Invoke();
- }
- catch (Exception ex)
- {
- LOG.Error("invoke error:", ex);
- threadException = ex;
- }
- })
- );
- waitFor.Name = title;
- waitFor.IsBackground = true;
- waitFor.SetApartmentState(ApartmentState.STA);
- waitFor.Start();
-
- // Wait until finished
- while (!waitFor.Join(TimeSpan.FromMilliseconds(100)))
- {
- Application.DoEvents();
- }
- LOG.DebugFormat("Finished {0}", title);
- }
- catch (Exception ex)
- {
- LOG.Error(ex);
- throw;
- }
- finally
- {
- Close();
- }
- // Check if an exception occured, if so throw it
- if (threadException != null)
- {
- throw threadException;
- }
- }
-
- ///
- /// Called if the cancel button is clicked, will use Thread.Abort()
- ///
- ///
- ///
- private void CancelButtonClick(object sender, EventArgs e)
- {
- LOG.DebugFormat("Cancel clicked on {0}", title);
- cancelButton.Enabled = false;
- waitFor.Abort();
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/PleaseWaitForm.designer.cs b/Greenshot.ImageEditor/Controls/PleaseWaitForm.designer.cs
deleted file mode 100644
index 7a922387b..000000000
--- a/Greenshot.ImageEditor/Controls/PleaseWaitForm.designer.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 .
- */
-namespace GreenshotPlugin.Controls
-{
- partial class PleaseWaitForm
- {
- ///
- /// Designer variable used to keep track of non-visual components.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Disposes resources used by the form.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (components != null)
- {
- components.Dispose();
- }
- }
- base.Dispose(disposing);
- }
-
- ///
- /// This method is required for Windows Forms designer support.
- /// Do not change the method contents inside the source code editor. The Forms designer might
- /// not be able to load this method if it was changed manually.
- ///
- private void InitializeComponent()
- {
- this.label_pleasewait = new System.Windows.Forms.Label();
- this.cancelButton = new System.Windows.Forms.Button();
- this.SuspendLayout();
- //
- // label_pleasewait
- //
- this.label_pleasewait.AutoSize = true;
- this.label_pleasewait.Dock = System.Windows.Forms.DockStyle.Fill;
- this.label_pleasewait.Location = new System.Drawing.Point(0, 0);
- this.label_pleasewait.Name = "label_pleasewait";
- this.label_pleasewait.Padding = new System.Windows.Forms.Padding(10);
- this.label_pleasewait.Size = new System.Drawing.Size(90, 33);
- this.label_pleasewait.TabIndex = 0;
- this.label_pleasewait.Text = "Please wait...";
- this.label_pleasewait.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.label_pleasewait.UseWaitCursor = true;
- //
- // cancelButton
- //
- this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
- this.cancelButton.Location = new System.Drawing.Point(38, 41);
- this.cancelButton.Name = "cancelButton";
- this.cancelButton.Size = new System.Drawing.Size(94, 23);
- this.cancelButton.TabIndex = 1;
- this.cancelButton.Text = "Cancel";
- this.cancelButton.UseVisualStyleBackColor = true;
- this.cancelButton.UseWaitCursor = true;
- this.cancelButton.Click += new System.EventHandler(this.CancelButtonClick);
- //
- // PleaseWaitForm
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.AutoSize = true;
- this.CancelButton = this.cancelButton;
- this.ClientSize = new System.Drawing.Size(169, 76);
- this.Controls.Add(this.cancelButton);
- this.Controls.Add(this.label_pleasewait);
- this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
- this.MaximizeBox = false;
- this.MinimizeBox = false;
- this.Name = "PleaseWaitForm";
- this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
- this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
- this.Text = "Greenshot";
- this.UseWaitCursor = true;
- this.ResumeLayout(false);
- this.PerformLayout();
- }
- private System.Windows.Forms.Button cancelButton;
- private System.Windows.Forms.Label label_pleasewait;
- }
-}
diff --git a/Greenshot.ImageEditor/Controls/QualityDialog.cs b/Greenshot.ImageEditor/Controls/QualityDialog.cs
deleted file mode 100644
index 218f878bb..000000000
--- a/Greenshot.ImageEditor/Controls/QualityDialog.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using Greenshot.IniFile;
-using Greenshot.Plugin;
-using GreenshotPlugin.Core;
-using System;
-
-namespace GreenshotPlugin.Controls
-{
- ///
- /// Description of JpegQualityDialog.
- ///
- internal partial class QualityDialog : GreenshotForm
- {
- private static readonly CoreConfiguration conf = IniConfig.GetIniSection();
- public SurfaceOutputSettings Settings
- {
- get;
- set;
- }
-
- public QualityDialog(SurfaceOutputSettings outputSettings)
- {
- Settings = outputSettings;
- //
- // The InitializeComponent() call is required for Windows Forms designer support.
- //
- InitializeComponent();
-
- checkBox_reduceColors.Checked = Settings.ReduceColors;
- trackBarJpegQuality.Enabled = OutputFormat.jpg.Equals(outputSettings.Format);
- trackBarJpegQuality.Value = Settings.JPGQuality;
- textBoxJpegQuality.Enabled = OutputFormat.jpg.Equals(outputSettings.Format);
- textBoxJpegQuality.Text = Settings.JPGQuality.ToString();
- ToFront = true;
- }
-
- private void Button_okClick(object sender, EventArgs e)
- {
- Settings.JPGQuality = trackBarJpegQuality.Value;
- Settings.ReduceColors = checkBox_reduceColors.Checked;
- if (checkbox_dontaskagain.Checked)
- {
- conf.OutputFileJpegQuality = Settings.JPGQuality;
- conf.OutputFilePromptQuality = false;
- conf.OutputFileReduceColors = Settings.ReduceColors;
- IniConfig.Save();
- }
- }
-
- private void TrackBarJpegQualityScroll(object sender, EventArgs e)
- {
- textBoxJpegQuality.Text = trackBarJpegQuality.Value.ToString();
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/QualityDialog.designer.cs b/Greenshot.ImageEditor/Controls/QualityDialog.designer.cs
deleted file mode 100644
index 0893caacb..000000000
--- a/Greenshot.ImageEditor/Controls/QualityDialog.designer.cs
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 .
- */
-namespace GreenshotPlugin.Controls
-{
- partial class QualityDialog
- {
- ///
- /// Designer variable used to keep track of non-visual components.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Disposes resources used by the form.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (components != null)
- {
- components.Dispose();
- }
- }
- base.Dispose(disposing);
- }
-
- ///
- /// This method is required for Windows Forms designer support.
- /// Do not change the method contents inside the source code editor. The Forms designer might
- /// not be able to load this method if it was changed manually.
- ///
- private void InitializeComponent()
- {
- this.label_choosejpegquality = new GreenshotPlugin.Controls.GreenshotLabel();
- this.textBoxJpegQuality = new System.Windows.Forms.TextBox();
- this.trackBarJpegQuality = new System.Windows.Forms.TrackBar();
- this.checkbox_dontaskagain = new GreenshotPlugin.Controls.GreenshotCheckBox();
- this.button_ok = new GreenshotPlugin.Controls.GreenshotButton();
- this.checkBox_reduceColors = new System.Windows.Forms.CheckBox();
- ((System.ComponentModel.ISupportInitialize)(this.trackBarJpegQuality)).BeginInit();
- this.SuspendLayout();
- //
- // label_choosejpegquality
- //
- this.label_choosejpegquality.Location = new System.Drawing.Point(12, 47);
- this.label_choosejpegquality.Name = "label_choosejpegquality";
- this.label_choosejpegquality.Size = new System.Drawing.Size(268, 19);
- this.label_choosejpegquality.TabIndex = 15;
- this.label_choosejpegquality.LanguageKey = "jpegqualitydialog_choosejpegquality";
- //
- // textBoxJpegQuality
- //
- this.textBoxJpegQuality.Location = new System.Drawing.Point(245, 69);
- this.textBoxJpegQuality.Name = "textBoxJpegQuality";
- this.textBoxJpegQuality.ReadOnly = true;
- this.textBoxJpegQuality.Size = new System.Drawing.Size(35, 20);
- this.textBoxJpegQuality.TabIndex = 16;
- this.textBoxJpegQuality.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
- //
- // trackBarJpegQuality
- //
- this.trackBarJpegQuality.LargeChange = 10;
- this.trackBarJpegQuality.Location = new System.Drawing.Point(12, 69);
- this.trackBarJpegQuality.Maximum = 100;
- this.trackBarJpegQuality.Name = "trackBarJpegQuality";
- this.trackBarJpegQuality.Size = new System.Drawing.Size(233, 45);
- this.trackBarJpegQuality.TabIndex = 14;
- this.trackBarJpegQuality.TickFrequency = 10;
- this.trackBarJpegQuality.Scroll += new System.EventHandler(this.TrackBarJpegQualityScroll);
- //
- // checkbox_dontaskagain
- //
- this.checkbox_dontaskagain.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
- this.checkbox_dontaskagain.ImageAlign = System.Drawing.ContentAlignment.TopLeft;
- this.checkbox_dontaskagain.Location = new System.Drawing.Point(12, 106);
- this.checkbox_dontaskagain.Name = "checkbox_dontaskagain";
- this.checkbox_dontaskagain.LanguageKey = "qualitydialog_dontaskagain";
- this.checkbox_dontaskagain.Size = new System.Drawing.Size(268, 37);
- this.checkbox_dontaskagain.TabIndex = 17;
- this.checkbox_dontaskagain.TextAlign = System.Drawing.ContentAlignment.TopLeft;
- this.checkbox_dontaskagain.UseVisualStyleBackColor = true;
- //
- // button_ok
- //
- this.button_ok.DialogResult = System.Windows.Forms.DialogResult.Cancel;
- this.button_ok.Location = new System.Drawing.Point(205, 149);
- this.button_ok.Name = "button_ok";
- this.button_ok.Size = new System.Drawing.Size(75, 23);
- this.button_ok.TabIndex = 18;
- this.button_ok.LanguageKey = "OK";
- this.button_ok.UseVisualStyleBackColor = true;
- this.button_ok.Click += new System.EventHandler(this.Button_okClick);
- //
- // checkBox_reduceColors
- //
- this.checkBox_reduceColors.AutoSize = true;
- this.checkBox_reduceColors.Location = new System.Drawing.Point(12, 11);
- this.checkBox_reduceColors.Name = "checkBox_reduceColors";
- this.checkBox_reduceColors.Size = new System.Drawing.Size(95, 17);
- this.checkBox_reduceColors.TabIndex = 19;
- this.checkBox_reduceColors.Text = "settings_reducecolors";
- this.checkBox_reduceColors.UseVisualStyleBackColor = true;
- //
- // QualityDialog
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
- this.ClientSize = new System.Drawing.Size(299, 184);
- this.ControlBox = false;
- this.Controls.Add(this.checkBox_reduceColors);
- this.Controls.Add(this.button_ok);
- this.Controls.Add(this.checkbox_dontaskagain);
- this.Controls.Add(this.label_choosejpegquality);
- this.Controls.Add(this.textBoxJpegQuality);
- this.Controls.Add(this.trackBarJpegQuality);
- this.MaximizeBox = false;
- this.MinimizeBox = false;
- this.Name = "QualityDialog";
- this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
- this.LanguageKey = "qualitydialog_title";
- ((System.ComponentModel.ISupportInitialize)(this.trackBarJpegQuality)).EndInit();
- this.ResumeLayout(false);
- this.PerformLayout();
-
- }
- private GreenshotPlugin.Controls.GreenshotButton button_ok;
- private GreenshotPlugin.Controls.GreenshotCheckBox checkbox_dontaskagain;
- private System.Windows.Forms.TrackBar trackBarJpegQuality;
- private System.Windows.Forms.TextBox textBoxJpegQuality;
- private GreenshotPlugin.Controls.GreenshotLabel label_choosejpegquality;
- private System.Windows.Forms.CheckBox checkBox_reduceColors;
- }
-}
diff --git a/Greenshot.ImageEditor/Controls/SaveImageFileDialog.cs b/Greenshot.ImageEditor/Controls/SaveImageFileDialog.cs
deleted file mode 100644
index a20670b07..000000000
--- a/Greenshot.ImageEditor/Controls/SaveImageFileDialog.cs
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using Greenshot.IniFile;
-using Greenshot.Plugin;
-using GreenshotPlugin.Core;
-using System;
-using System.IO;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Controls
-{
- ///
- /// Custom dialog for saving images, wraps SaveFileDialog.
- /// For some reason SFD is sealed :(
- ///
- internal class SaveImageFileDialog : IDisposable
- {
- private static readonly CoreConfiguration conf = IniConfig.GetIniSection();
- protected SaveFileDialog SaveFileDialog;
- private FilterOption[] _filterOptions;
- private DirectoryInfo _eagerlyCreatedDirectory;
- private readonly ICaptureDetails _captureDetails = null;
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (SaveFileDialog != null)
- {
- SaveFileDialog.Dispose();
- SaveFileDialog = null;
- }
- }
- }
-
- public SaveImageFileDialog()
- {
- Init();
- }
-
- public SaveImageFileDialog(ICaptureDetails captureDetails)
- {
- _captureDetails = captureDetails;
- Init();
- }
-
- private void Init()
- {
- SaveFileDialog = new SaveFileDialog();
- ApplyFilterOptions();
- string initialDirectory = null;
- try
- {
- initialDirectory = Path.GetDirectoryName(conf.OutputFileAsFullpath);
- }
- catch
- {
- LOG.WarnFormat("OutputFileAsFullpath was set to {0}, ignoring due to problem in path.", conf.OutputFileAsFullpath);
- }
-
- if (!string.IsNullOrEmpty(initialDirectory) && Directory.Exists(initialDirectory))
- {
- SaveFileDialog.InitialDirectory = initialDirectory;
- }
- else if (Directory.Exists(conf.OutputFilePath))
- {
- SaveFileDialog.InitialDirectory = conf.OutputFilePath;
- }
- // The following property fixes a problem that the directory where we save is locked (bug #2899790)
- SaveFileDialog.RestoreDirectory = true;
- SaveFileDialog.OverwritePrompt = true;
- SaveFileDialog.CheckPathExists = false;
- SaveFileDialog.AddExtension = true;
- ApplySuggestedValues();
- }
-
- private void ApplyFilterOptions()
- {
- PrepareFilterOptions();
- string fdf = "";
- int preselect = 0;
- var outputFileFormatAsString = Enum.GetName(typeof(OutputFormat), conf.OutputFileFormat);
- for (int i = 0; i < _filterOptions.Length; i++)
- {
- FilterOption fo = _filterOptions[i];
- fdf += fo.Label + "|*." + fo.Extension + "|";
- if (outputFileFormatAsString == fo.Extension)
- preselect = i;
- }
- fdf = fdf.Substring(0, fdf.Length - 1);
- SaveFileDialog.Filter = fdf;
- SaveFileDialog.FilterIndex = preselect + 1;
- }
-
- private void PrepareFilterOptions()
- {
- OutputFormat[] supportedImageFormats = (OutputFormat[])Enum.GetValues(typeof(OutputFormat));
- _filterOptions = new FilterOption[supportedImageFormats.Length];
- for (int i = 0; i < _filterOptions.Length; i++)
- {
- string ifo = supportedImageFormats[i].ToString();
- if (ifo.ToLower().Equals("jpeg")) ifo = "Jpg"; // we dont want no jpeg files, so let the dialog check for jpg
- FilterOption fo = new FilterOption
- {
- Label = ifo.ToUpper(),
- Extension = ifo.ToLower()
- };
- _filterOptions.SetValue(fo, i);
- }
- }
-
- ///
- /// filename exactly as typed in the filename field
- ///
- public string FileName
- {
- get { return SaveFileDialog.FileName; }
- set { SaveFileDialog.FileName = value; }
- }
-
- ///
- /// initial directory of the dialog
- ///
- public string InitialDirectory
- {
- get { return SaveFileDialog.InitialDirectory; }
- set { SaveFileDialog.InitialDirectory = value; }
- }
-
- ///
- /// returns filename as typed in the filename field with extension.
- /// if filename field value ends with selected extension, the value is just returned.
- /// otherwise, the selected extension is appended to the filename.
- ///
- public string FileNameWithExtension
- {
- get
- {
- string fn = SaveFileDialog.FileName;
- // 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;
- // otherwise we just add the selected filter item's extension
- else return fn + "." + Extension;
- }
- set
- {
- FileName = Path.GetFileNameWithoutExtension(value);
- Extension = Path.GetExtension(value);
- }
- }
-
- ///
- /// gets or sets selected extension
- ///
- public string Extension
- {
- get
- {
- return _filterOptions[SaveFileDialog.FilterIndex - 1].Extension;
- }
- set
- {
- for (int i = 0; i < _filterOptions.Length; i++)
- {
- if (value.Equals(_filterOptions[i].Extension, StringComparison.CurrentCultureIgnoreCase))
- {
- SaveFileDialog.FilterIndex = i + 1;
- }
- }
- }
- }
-
- public DialogResult ShowDialog()
- {
- DialogResult ret = SaveFileDialog.ShowDialog();
- CleanUp();
- return ret;
- }
-
- ///
- /// sets InitialDirectory and FileName property of a SaveFileDialog smartly, considering default pattern and last used path
- ///
- private void ApplySuggestedValues()
- {
- // build the full path and set dialog properties
- FileName = FilenameHelper.GetFilenameWithoutExtensionFromPattern(conf.OutputFileFilenamePattern, _captureDetails);
- }
-
- private class FilterOption
- {
- public string Label;
- public string Extension;
- }
-
- private void CleanUp()
- {
- // fix for bug #3379053
- try
- {
- if (_eagerlyCreatedDirectory != null && _eagerlyCreatedDirectory.GetFiles().Length == 0 && _eagerlyCreatedDirectory.GetDirectories().Length == 0)
- {
- _eagerlyCreatedDirectory.Delete();
- _eagerlyCreatedDirectory = null;
- }
- }
- catch (Exception e)
- {
- LOG.WarnFormat("Couldn't cleanup directory due to: {0}", e.Message);
- _eagerlyCreatedDirectory = null;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/ToolStripColorButton.cs b/Greenshot.ImageEditor/Controls/ToolStripColorButton.cs
deleted file mode 100644
index 7e18230d7..000000000
--- a/Greenshot.ImageEditor/Controls/ToolStripColorButton.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using GreenshotPlugin.Controls;
-using System;
-using System.ComponentModel;
-using System.Drawing;
-using System.Drawing.Drawing2D;
-using System.Windows.Forms;
-
-namespace Greenshot.Controls
-{
- internal class ToolStripColorButton : ToolStripButton, INotifyPropertyChanged, IGreenshotLanguageBindable
- {
- public event PropertyChangedEventHandler PropertyChanged;
-
- [Category("Greenshot"), DefaultValue(null), Description("Specifies key of the language file to use when displaying the text.")]
- public string LanguageKey
- {
- get;
- set;
- }
-
- private Color selectedColor = Color.Transparent;
-
- public ToolStripColorButton()
- {
- Click += ColorButtonClick;
- }
-
- public Color SelectedColor
- {
- get
- {
- return selectedColor;
- }
- set
- {
- selectedColor = value;
-
- Brush brush;
- if (value != Color.Transparent)
- {
- brush = new SolidBrush(value);
- }
- else
- {
- brush = new HatchBrush(HatchStyle.Percent50, Color.White, Color.Gray);
- }
-
- if (Image != null)
- {
- using (Graphics graphics = Graphics.FromImage(Image))
- {
- graphics.FillRectangle(brush, new Rectangle(0, 13, 16, 3));
- }
- }
-
- // cleanup GDI Object
- brush.Dispose();
- Invalidate();
- }
- }
-
- private void ColorButtonClick(object sender, EventArgs e)
- {
- ColorDialog colorDialog = ColorDialog.GetInstance();
- colorDialog.Color = SelectedColor;
- // Using the parent to make sure the dialog doesn't show on another window
- colorDialog.ShowDialog(Parent.Parent);
- if (colorDialog.DialogResult != DialogResult.Cancel)
- {
- if (!colorDialog.Color.Equals(SelectedColor))
- {
- SelectedColor = colorDialog.Color;
- if (PropertyChanged != null)
- {
- PropertyChanged(this, new PropertyChangedEventArgs("SelectedColor"));
- }
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/ToolStripEx.cs b/Greenshot.ImageEditor/Controls/ToolStripEx.cs
deleted file mode 100644
index ffd6f39fa..000000000
--- a/Greenshot.ImageEditor/Controls/ToolStripEx.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-using System.Windows.Forms;
-
-namespace Greenshot.Controls
-{
- ///
- /// This is an extension of the default ToolStrip and allows us to click it even when the form doesn't have focus.
- /// See: http://blogs.msdn.com/b/rickbrew/archive/2006/01/09/511003.aspx
- ///
- internal class ToolStripEx : ToolStrip
- {
- private const int WM_MOUSEACTIVATE = 0x21;
-
- private enum NativeConstants : uint
- {
- MA_ACTIVATE = 1,
- MA_ACTIVATEANDEAT = 2,
- }
-
- private bool _clickThrough = false;
- ///
- /// Gets or sets whether the ToolStripEx honors item clicks when its containing form does not have input focus.
- ///
- ///
- /// Default value is false, which is the same behavior provided by the base ToolStrip class.
- ///
-
- public bool ClickThrough
- {
- get
- {
- return _clickThrough;
- }
-
- set
- {
- _clickThrough = value;
- }
- }
-
- protected override void WndProc(ref Message m)
- {
- base.WndProc(ref m);
- if (_clickThrough && m.Msg == WM_MOUSEACTIVATE && m.Result == (IntPtr)NativeConstants.MA_ACTIVATEANDEAT)
- {
- m.Result = (IntPtr)NativeConstants.MA_ACTIVATE;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Controls/ToolStripNumericUpDown.cs b/Greenshot.ImageEditor/Controls/ToolStripNumericUpDown.cs
deleted file mode 100644
index 2954f3f4d..000000000
--- a/Greenshot.ImageEditor/Controls/ToolStripNumericUpDown.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-using System.ComponentModel;
-using System.Windows.Forms;
-using System.Windows.Forms.Design;
-
-namespace Greenshot.Controls
-{
- [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
- internal class ToolStripNumericUpDown : ToolStripControlHost, INotifyPropertyChanged
- {
- public event PropertyChangedEventHandler PropertyChanged;
-
- public ToolStripNumericUpDown() : base(new NumericUpDown())
- {
- }
-
- public NumericUpDown NumericUpDown
- {
- get { return Control as NumericUpDown; }
- }
-
- public decimal Value
- {
- get { return NumericUpDown.Value; }
- set { NumericUpDown.Value = value; }
- }
- public decimal Minimum
- {
- get { return NumericUpDown.Minimum; }
- set { NumericUpDown.Minimum = value; }
- }
-
- public decimal Maximum
- {
- get { return NumericUpDown.Maximum; }
- set { NumericUpDown.Maximum = value; }
- }
-
- public decimal Increment
- {
- get { return NumericUpDown.Increment; }
- set { NumericUpDown.Increment = value; }
- }
-
- public int DecimalPlaces
- {
- get { return NumericUpDown.DecimalPlaces; }
- set { NumericUpDown.DecimalPlaces = value; }
- }
-
- protected override void OnSubscribeControlEvents(Control control)
- {
- base.OnSubscribeControlEvents(control);
- NumericUpDown.ValueChanged += _valueChanged;
- }
-
- protected override void OnUnsubscribeControlEvents(Control control)
- {
- base.OnUnsubscribeControlEvents(control);
- NumericUpDown.ValueChanged -= _valueChanged;
- }
-
- private void _valueChanged(object sender, EventArgs e)
- {
- if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Value"));
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/BinaryStructHelper.cs b/Greenshot.ImageEditor/Core/BinaryStructHelper.cs
deleted file mode 100644
index 5668ce285..000000000
--- a/Greenshot.ImageEditor/Core/BinaryStructHelper.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace GreenshotPlugin.Core
-{
- ///
- /// A helper class which does the mashalling for structs
- ///
- public static class BinaryStructHelper
- {
- ///
- /// Get a struct from a byte array
- ///
- /// typeof struct
- /// byte[]
- /// struct
- public static T FromByteArray(byte[] bytes) where T : struct
- {
- IntPtr ptr = IntPtr.Zero;
- try
- {
- int size = Marshal.SizeOf(typeof(T));
- ptr = Marshal.AllocHGlobal(size);
- Marshal.Copy(bytes, 0, ptr, size);
- return FromIntPtr(ptr);
- }
- finally
- {
- if (ptr != IntPtr.Zero)
- {
- Marshal.FreeHGlobal(ptr);
- }
- }
- }
-
- ///
- /// Get a struct from a byte array
- ///
- /// typeof struct
- /// byte[]
- /// struct
- public static T FromIntPtr(IntPtr intPtr) where T : struct
- {
- object obj = Marshal.PtrToStructure(intPtr, typeof(T));
- return (T)obj;
- }
-
- ///
- /// copy a struct to a byte array
- ///
- /// typeof struct
- /// struct
- /// byte[]
- public static byte[] ToByteArray(T obj) where T : struct
- {
- IntPtr ptr = IntPtr.Zero;
- try
- {
- int size = Marshal.SizeOf(typeof(T));
- ptr = Marshal.AllocHGlobal(size);
- Marshal.StructureToPtr(obj, ptr, true);
- return FromPtrToByteArray(ptr);
- }
- finally
- {
- if (ptr != IntPtr.Zero)
- {
- Marshal.FreeHGlobal(ptr);
- }
- }
- }
-
- ///
- /// copy a struct from a pointer to a byte array
- ///
- /// typeof struct
- /// IntPtr to struct
- /// byte[]
- public static byte[] FromPtrToByteArray(IntPtr ptr) where T : struct
- {
- int size = Marshal.SizeOf(typeof(T));
- byte[] bytes = new byte[size];
- Marshal.Copy(ptr, bytes, 0, size);
- return bytes;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/Cache.cs b/Greenshot.ImageEditor/Core/Cache.cs
deleted file mode 100644
index 413ed9a4f..000000000
--- a/Greenshot.ImageEditor/Core/Cache.cs
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.Timers;
-
-namespace GreenshotPlugin.Core
-{
- ///
- /// Cache class
- ///
- /// Type of key
- /// Type of value
- public class Cache
- {
- private readonly IDictionary internalCache = new Dictionary();
- private readonly object lockObject = new object();
- private readonly int secondsToExpire = 10;
- private readonly CacheObjectExpired expiredCallback = null;
- public delegate void CacheObjectExpired(TK key, TV cacheValue);
-
- ///
- /// Initialize the cache
- ///
- public Cache()
- {
- }
-
- ///
- /// Initialize the cache
- ///
- ///
- public Cache(CacheObjectExpired expiredCallback) : this()
- {
- this.expiredCallback = expiredCallback;
- }
-
- ///
- /// Initialize the cache with a expire setting
- ///
- ///
- public Cache(int secondsToExpire) : this()
- {
- this.secondsToExpire = secondsToExpire;
- }
-
- ///
- /// Initialize the cache with a expire setting
- ///
- ///
- ///
- public Cache(int secondsToExpire, CacheObjectExpired expiredCallback) : this(expiredCallback)
- {
- this.secondsToExpire = secondsToExpire;
- }
-
- ///
- /// Enumerable for the values in the cache
- ///
- public IEnumerable Elements
- {
- get
- {
- List elements = new List();
-
- lock (lockObject)
- {
- foreach (TV element in internalCache.Values)
- {
- elements.Add(element);
- }
- }
- foreach (TV element in elements)
- {
- yield return element;
- }
- }
- }
-
- ///
- /// Get the value by key from the cache
- ///
- ///
- ///
- public TV this[TK key]
- {
- get
- {
- TV result = default(TV);
- lock (lockObject)
- {
- if (internalCache.ContainsKey(key))
- {
- result = internalCache[key];
- }
- }
- return result;
- }
- }
-
- ///
- /// Contains
- ///
- ///
- /// true if the cache contains the key
- public bool Contains(TK key)
- {
- lock (lockObject)
- {
- return internalCache.ContainsKey(key);
- }
- }
-
- ///
- /// Add a value to the cache
- ///
- ///
- ///
- public void Add(TK key, TV value)
- {
- Add(key, value, null);
- }
-
- ///
- /// Add a value to the cache
- ///
- ///
- ///
- /// optional value for the seconds to expire
- public void Add(TK key, TV value, int? secondsToExpire)
- {
- lock (lockObject)
- {
- var cachedItem = new CachedItem(key, value, secondsToExpire.HasValue ? secondsToExpire.Value : this.secondsToExpire);
- cachedItem.Expired += delegate (TK cacheKey, TV cacheValue)
- {
- if (internalCache.ContainsKey(cacheKey))
- {
- LOG.DebugFormat("Expiring object with Key: {0}", cacheKey);
- if (expiredCallback != null)
- {
- expiredCallback(cacheKey, cacheValue);
- }
- Remove(cacheKey);
- }
- else
- {
- LOG.DebugFormat("Expired old object with Key: {0}", cacheKey);
- }
- };
-
- if (internalCache.ContainsKey(key))
- {
- internalCache[key] = value;
- LOG.DebugFormat("Updated item with Key: {0}", key);
- }
- else
- {
- internalCache.Add(key, cachedItem);
- LOG.DebugFormat("Added item with Key: {0}", key);
- }
- }
- }
-
- ///
- /// Remove item from cache
- ///
- ///
- public void Remove(TK key)
- {
- lock (lockObject)
- {
- if (!internalCache.ContainsKey(key))
- {
- throw new ApplicationException(String.Format("An object with key ‘{0}’ does not exists in cache", key));
- }
- internalCache.Remove(key);
- LOG.DebugFormat("Removed item with Key: {0}", key);
- }
- }
-
- ///
- /// A cache item
- ///
- private class CachedItem
- {
- public event CacheObjectExpired Expired;
- private readonly int secondsToExpire;
- private readonly Timer _timerEvent;
-
- public CachedItem(TK key, TV item, int secondsToExpire)
- {
- if (key == null)
- {
- throw new ArgumentNullException("key is not valid");
- }
- Key = key;
- Item = item;
- this.secondsToExpire = secondsToExpire;
- if (secondsToExpire > 0)
- {
- _timerEvent = new Timer(secondsToExpire * 1000) { AutoReset = false };
- _timerEvent.Elapsed += timerEvent_Elapsed;
- _timerEvent.Start();
- }
- }
-
- private void ExpireNow()
- {
- _timerEvent.Stop();
- if (secondsToExpire > 0 && Expired != null)
- {
- Expired(Key, Item);
- }
- }
-
- private void timerEvent_Elapsed(object sender, ElapsedEventArgs e)
- {
- ExpireNow();
- }
-
- public TK Key { get; private set; }
- public TV Item { get; private set; }
-
- public static implicit operator TV(CachedItem a)
- {
- return a.Item;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/CaptureHandler.cs b/Greenshot.ImageEditor/Core/CaptureHandler.cs
deleted file mode 100644
index e490f6a21..000000000
--- a/Greenshot.ImageEditor/Core/CaptureHandler.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.Drawing;
-
-namespace GreenshotPlugin.Core
-{
- ///
- /// This is the method signature which is used to capture a rectangle from the screen.
- ///
- ///
- /// Captured Bitmap
- public delegate Bitmap CaptureScreenRectangleHandler(Rectangle captureBounds);
-
- ///
- /// This is a hack to experiment with different screen capture routines
- ///
- public static class CaptureHandler
- {
- ///
- /// By changing this value, null is default
- ///
- public static CaptureScreenRectangleHandler CaptureScreenRectangle
- {
- get;
- set;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/ClipboardHelper.cs b/Greenshot.ImageEditor/Core/ClipboardHelper.cs
deleted file mode 100644
index dfe33f6b1..000000000
--- a/Greenshot.ImageEditor/Core/ClipboardHelper.cs
+++ /dev/null
@@ -1,1006 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using Greenshot.IniFile;
-using Greenshot.Plugin;
-using GreenshotPlugin.UnmanagedHelpers;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Core
-{
- ///
- /// Description of ClipboardHelper.
- ///
- public static class ClipboardHelper
- {
- private static readonly Object clipboardLockObject = new Object();
- private static readonly CoreConfiguration config = IniConfig.GetIniSection();
- private static readonly string FORMAT_FILECONTENTS = "FileContents";
- private static readonly string FORMAT_PNG = "PNG";
- private static readonly string FORMAT_PNG_OFFICEART = "PNG+Office Art";
- private static readonly string FORMAT_17 = "Format17";
- private static readonly string FORMAT_JPG = "JPG";
- private static readonly string FORMAT_JFIF = "JFIF";
- private static readonly string FORMAT_JFIF_OFFICEART = "JFIF+Office Art";
- private static readonly string FORMAT_GIF = "GIF";
- private static readonly string FORMAT_BITMAP = "System.Drawing.Bitmap";
- //private static readonly string FORMAT_HTML = "HTML Format";
-
- private static IntPtr nextClipboardViewer = IntPtr.Zero;
- // Template for the HTML Text on the clipboard
- // see: http://msdn.microsoft.com/en-us/library/ms649015%28v=vs.85%29.aspx
- // or: http://msdn.microsoft.com/en-us/library/Aa767917.aspx
- private const string HTML_CLIPBOARD_STRING = @"Version:0.9
-StartHTML:<<<<<<<1
-EndHTML:<<<<<<<2
-StartFragment:<<<<<<<3
-EndFragment:<<<<<<<4
-StartSelection:<<<<<<<3
-EndSelection:<<<<<<<4
-
-
-
-Greenshot capture
-
-
-
-
-
-
-";
- private const string HTML_CLIPBOARD_BASE64_STRING = @"Version:0.9
-StartHTML:<<<<<<<1
-EndHTML:<<<<<<<2
-StartFragment:<<<<<<<3
-EndFragment:<<<<<<<4
-StartSelection:<<<<<<<3
-EndSelection:<<<<<<<4
-
-
-
-Greenshot capture
-
-
-
-
-
-
-";
-
- ///
- /// Get the current "ClipboardOwner" but only if it isn't us!
- ///
- /// current clipboard owner
- private static string GetClipboardOwner()
- {
- string owner = null;
- try
- {
- IntPtr hWnd = User32.GetClipboardOwner();
- if (hWnd != IntPtr.Zero)
- {
- int pid;
- User32.GetWindowThreadProcessId(hWnd, out pid);
- using (Process me = Process.GetCurrentProcess())
- using (Process ownerProcess = Process.GetProcessById(pid))
- {
- // Exclude myself
- if (ownerProcess != null && me.Id != ownerProcess.Id)
- {
- // Get Process Name
- owner = ownerProcess.ProcessName;
- // Try to get the starting Process Filename, this might fail.
- try
- {
- owner = ownerProcess.Modules[0].FileName;
- }
- catch (Exception)
- {
- }
- }
- }
- }
- }
- catch (Exception e)
- {
- LOG.Warn("Non critical error: Couldn't get clipboard owner.", e);
- }
- return owner;
- }
-
- ///
- /// The SetDataObject will lock/try/catch clipboard operations making it save and not show exceptions.
- /// The bool "copy" is used to decided if the information stays on the clipboard after exit.
- ///
- ///
- ///
- private static void SetDataObject(IDataObject ido, bool copy)
- {
- lock (clipboardLockObject)
- {
- int retryCount = 5;
- while (retryCount >= 0)
- {
- try
- {
- Clipboard.SetDataObject(ido, copy);
- break;
- }
- catch (Exception ee)
- {
- if (retryCount == 0)
- {
- string messageText = null;
- string clipboardOwner = GetClipboardOwner();
- if (clipboardOwner != null)
- {
- messageText = string.Format("Greenshot wasn't able to write to the clipboard as the process {0} blocked the access.", clipboardOwner);
- }
- else
- {
- messageText = "An unexpected error occured while writing to the clipboard.";
- }
- LOG.Error(messageText, ee);
- }
- else
- {
- Thread.Sleep(100);
- }
- }
- finally
- {
- --retryCount;
- }
- }
- }
- }
-
- ///
- /// The GetDataObject will lock/try/catch clipboard operations making it save and not show exceptions.
- ///
- public static IDataObject GetDataObject()
- {
- lock (clipboardLockObject)
- {
- int retryCount = 2;
- while (retryCount >= 0)
- {
- try
- {
- return Clipboard.GetDataObject();
- }
- catch (Exception ee)
- {
- if (retryCount == 0)
- {
- string messageText = null;
- string clipboardOwner = GetClipboardOwner();
- if (clipboardOwner != null)
- {
- messageText = string.Format("Greenshot wasn't able to write to the clipboard as the process {0} blocked the access.", clipboardOwner);
- }
- else
- {
- messageText = "An unexpected error occured while writing to the clipboard.";
- }
- LOG.Error(messageText, ee);
- }
- else
- {
- Thread.Sleep(100);
- }
- }
- finally
- {
- --retryCount;
- }
- }
- }
- return null;
- }
-
- ///
- /// Wrapper for Clipboard.ContainsText, Created for Bug #3432313
- ///
- /// boolean if there is text on the clipboard
- public static bool ContainsText()
- {
- IDataObject clipboardData = GetDataObject();
- return ContainsText(clipboardData);
- }
-
- ///
- /// Test if the IDataObject contains Text
- ///
- ///
- ///
- public static bool ContainsText(IDataObject dataObject)
- {
- if (dataObject != null)
- {
- if (dataObject.GetDataPresent(DataFormats.Text) || dataObject.GetDataPresent(DataFormats.UnicodeText))
- {
- return true;
- }
- }
- return false;
- }
-
- ///
- /// Wrapper for Clipboard.ContainsImage, specialized for Greenshot, Created for Bug #3432313
- ///
- /// boolean if there is an image on the clipboard
- public static bool ContainsImage()
- {
- IDataObject clipboardData = GetDataObject();
- return ContainsImage(clipboardData);
- }
-
- ///
- /// Check if the IDataObject has an image
- ///
- ///
- /// true if an image is there
- public static bool ContainsImage(IDataObject dataObject)
- {
- if (dataObject != null)
- {
- if (dataObject.GetDataPresent(DataFormats.Bitmap)
- || dataObject.GetDataPresent(DataFormats.Dib)
- || dataObject.GetDataPresent(DataFormats.Tiff)
- || dataObject.GetDataPresent(DataFormats.EnhancedMetafile)
- || dataObject.GetDataPresent(FORMAT_PNG)
- || dataObject.GetDataPresent(FORMAT_17)
- || dataObject.GetDataPresent(FORMAT_JPG)
- || dataObject.GetDataPresent(FORMAT_GIF))
- {
- return true;
- }
- List imageFiles = GetImageFilenames(dataObject);
- if (imageFiles != null && imageFiles.Count > 0)
- {
- return true;
- }
- if (dataObject.GetDataPresent(FORMAT_FILECONTENTS))
- {
- try
- {
- MemoryStream imageStream = dataObject.GetData(FORMAT_FILECONTENTS) as MemoryStream;
- if (isValidStream(imageStream))
- {
- using (Image tmpImage = Image.FromStream(imageStream))
- {
- // If we get here, there is an image
- return true;
- }
- }
- }
- catch (Exception)
- {
- }
- }
- }
- return false;
- }
-
- ///
- /// Simple helper to check the stream
- ///
- ///
- ///
- private static bool isValidStream(MemoryStream memoryStream)
- {
- return memoryStream != null && memoryStream.Length > 0;
- }
-
- ///
- /// Wrapper for Clipboard.GetImage, Created for Bug #3432313
- ///
- /// Image if there is an image on the clipboard
- public static Image GetImage()
- {
- IDataObject clipboardData = GetDataObject();
- // Return the first image
- foreach (Image clipboardImage in GetImages(clipboardData))
- {
- return clipboardImage;
- }
- return null;
- }
-
- ///
- /// Get all images (multiple if filenames are available) from the dataObject
- /// Returned images must be disposed by the calling code!
- ///
- ///
- /// IEnumerable
- public static IEnumerable GetImages(IDataObject dataObject)
- {
- // Get single image, this takes the "best" match
- Image singleImage = GetImage(dataObject);
- if (singleImage != null)
- {
- LOG.InfoFormat("Got image from clipboard with size {0} and format {1}", singleImage.Size, singleImage.PixelFormat);
- yield return singleImage;
- }
- else
- {
- // check if files are supplied
- List imageFiles = GetImageFilenames(dataObject);
- if (imageFiles != null)
- {
- foreach (string imageFile in imageFiles)
- {
- Image returnImage = null;
- try
- {
- returnImage = ImageHelper.LoadImage(imageFile);
- }
- catch (Exception streamImageEx)
- {
- LOG.Error("Problem retrieving Image from clipboard.", streamImageEx);
- }
- if (returnImage != null)
- {
- LOG.InfoFormat("Got image from clipboard with size {0} and format {1}", returnImage.Size, returnImage.PixelFormat);
- yield return returnImage;
- }
- }
- }
- }
- }
-
- ///
- /// Get an Image from the IDataObject, don't check for FileDrop
- ///
- ///
- /// Image or null
- private static Image GetImage(IDataObject dataObject)
- {
- Image returnImage = null;
- if (dataObject != null)
- {
- IList formats = GetFormats(dataObject);
- string[] retrieveFormats;
-
- // Found a weird bug, where PNG's from Outlook 2010 are clipped
- // So I build some special logik 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_JFIF, DataFormats.Tiff, FORMAT_GIF };
- }
- else
- {
- retrieveFormats = new[] { FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_17, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JFIF, DataFormats.Tiff, DataFormats.Dib, FORMAT_BITMAP, FORMAT_FILECONTENTS, FORMAT_GIF };
- }
- foreach (string currentFormat in retrieveFormats)
- {
- if (formats.Contains(currentFormat))
- {
- LOG.InfoFormat("Found {0}, trying to retrieve.", currentFormat);
- returnImage = GetImageForFormat(currentFormat, dataObject);
- }
- else
- {
- LOG.DebugFormat("Couldn't find format {0}.", currentFormat);
- }
- if (returnImage != null)
- {
- ImageHelper.Orientate(returnImage);
- return returnImage;
- }
- }
- }
- return null;
- }
-
- ///
- /// Helper method to try to get an image in the specified format from the dataObject
- /// the DIB readed should solve the issue reported here: https://sourceforge.net/projects/greenshot/forums/forum/676083/topic/6354353/index/page/1
- /// It also supports Format17/DibV5, by using the following information: http://stackoverflow.com/a/14335591
- ///
- /// string with the format
- /// IDataObject
- /// Image or null
- private static Image GetImageForFormat(string format, IDataObject dataObject)
- {
- object clipboardObject = GetFromDataObject(dataObject, format);
- MemoryStream imageStream = clipboardObject as MemoryStream;
- if (!isValidStream(imageStream))
- {
- // add "HTML Format" support here...
- return clipboardObject as Image;
- }
- else
- {
- if (config.EnableSpecialDIBClipboardReader)
- {
- if (format == FORMAT_17 || format == DataFormats.Dib)
- {
- LOG.Info("Found DIB stream, trying to process it.");
- try
- {
- byte[] dibBuffer = new byte[imageStream.Length];
- imageStream.Read(dibBuffer, 0, dibBuffer.Length);
- BITMAPINFOHEADER infoHeader = BinaryStructHelper.FromByteArray(dibBuffer);
- if (!infoHeader.IsDibV5)
- {
- LOG.InfoFormat("Using special DIB (fileHeader);
-
- using (MemoryStream bitmapStream = new MemoryStream())
- {
- bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize);
- bitmapStream.Write(dibBuffer, 0, dibBuffer.Length);
- bitmapStream.Seek(0, SeekOrigin.Begin);
- using (Image tmpImage = Image.FromStream(bitmapStream))
- {
- if (tmpImage != null)
- {
- return ImageHelper.Clone(tmpImage);
- }
- }
- }
- }
- else
- {
- 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);
- 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)
- {
- 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
- {
- imageStream.Seek(0, SeekOrigin.Begin);
- using (Image tmpImage = Image.FromStream(imageStream, true, true))
- {
- if (tmpImage != null)
- {
- LOG.InfoFormat("Got image with clipboard format {0} from the clipboard.", format);
- return ImageHelper.Clone(tmpImage);
- }
- }
- }
- catch (Exception streamImageEx)
- {
- LOG.Error(string.Format("Problem retrieving {0} from clipboard.", format), streamImageEx);
- }
- }
- return null;
- }
-
- ///
- /// Wrapper for Clipboard.GetText created for Bug #3432313
- ///
- /// string if there is text on the clipboard
- public static string GetText()
- {
- return GetText(GetDataObject());
- }
-
- ///
- /// Get Text from the DataObject
- ///
- /// string if there is text on the clipboard
- public static string GetText(IDataObject dataObject)
- {
- if (ContainsText(dataObject))
- {
- return (String)dataObject.GetData(DataFormats.Text);
- }
- return null;
- }
-
- ///
- /// Set text to the clipboard
- ///
- ///
- public static void SetClipboardData(string text)
- {
- IDataObject ido = new DataObject();
- ido.SetData(DataFormats.Text, true, text);
- SetDataObject(ido, true);
- }
-
- private static string getHTMLString(ISurface surface, string filename)
- {
- string utf8EncodedHTMLString = Encoding.GetEncoding(0).GetString(Encoding.UTF8.GetBytes(HTML_CLIPBOARD_STRING));
- utf8EncodedHTMLString = utf8EncodedHTMLString.Replace("${width}", surface.Image.Width.ToString());
- utf8EncodedHTMLString = utf8EncodedHTMLString.Replace("${height}", surface.Image.Height.ToString());
- utf8EncodedHTMLString = utf8EncodedHTMLString.Replace("${file}", filename.Replace("\\", "/"));
- StringBuilder sb = new StringBuilder();
- sb.Append(utf8EncodedHTMLString);
- sb.Replace("<<<<<<<1", (utf8EncodedHTMLString.IndexOf("") + "".Length).ToString("D8"));
- sb.Replace("<<<<<<<2", (utf8EncodedHTMLString.IndexOf("")).ToString("D8"));
- sb.Replace("<<<<<<<3", (utf8EncodedHTMLString.IndexOf("") + "".Length).ToString("D8"));
- sb.Replace("<<<<<<<4", (utf8EncodedHTMLString.IndexOf("")).ToString("D8"));
- return sb.ToString();
- }
-
- private static string getHTMLDataURLString(ISurface surface, MemoryStream pngStream)
- {
- string utf8EncodedHTMLString = Encoding.GetEncoding(0).GetString(Encoding.UTF8.GetBytes(HTML_CLIPBOARD_BASE64_STRING));
- utf8EncodedHTMLString = utf8EncodedHTMLString.Replace("${width}", surface.Image.Width.ToString());
- utf8EncodedHTMLString = utf8EncodedHTMLString.Replace("${height}", surface.Image.Height.ToString());
- utf8EncodedHTMLString = utf8EncodedHTMLString.Replace("${format}", "png");
- utf8EncodedHTMLString = utf8EncodedHTMLString.Replace("${data}", Convert.ToBase64String(pngStream.GetBuffer(), 0, (int)pngStream.Length));
- StringBuilder sb = new StringBuilder();
- sb.Append(utf8EncodedHTMLString);
- sb.Replace("<<<<<<<1", (utf8EncodedHTMLString.IndexOf("") + "".Length).ToString("D8"));
- sb.Replace("<<<<<<<2", (utf8EncodedHTMLString.IndexOf("")).ToString("D8"));
- sb.Replace("<<<<<<<3", (utf8EncodedHTMLString.IndexOf("") + "".Length).ToString("D8"));
- sb.Replace("<<<<<<<4", (utf8EncodedHTMLString.IndexOf("")).ToString("D8"));
- return sb.ToString();
- }
-
- ///
- /// Set an Image to the clipboard
- /// This method will place images to the clipboard depending on the ClipboardFormats setting.
- /// e.g. Bitmap which works with pretty much everything and type Dib for e.g. OpenOffice
- /// because OpenOffice has a bug http://qa.openoffice.org/issues/show_bug.cgi?id=85661
- /// The Dib (Device Indenpendend Bitmap) in 32bpp actually won't work with Powerpoint 2003!
- /// When pasting a Dib in PP 2003 the Bitmap is somehow shifted left!
- /// For this problem the user should not use the direct paste (=Dib), but select Bitmap
- ///
- private const int BITMAPFILEHEADER_LENGTH = 14;
-
- public static void SetClipboardData(ISurface surface)
- {
- DataObject dataObject = new DataObject();
-
- // This will work for Office and most other applications
- //ido.SetData(DataFormats.Bitmap, true, image);
-
- MemoryStream dibStream = null;
- MemoryStream dibV5Stream = null;
- MemoryStream pngStream = null;
- Image imageToSave = null;
- bool disposeImage = false;
- try
- {
- SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false);
- // Create the image which is going to be saved so we don't create it multiple times
- disposeImage = ImageOutput.CreateImageFromSurface(surface, outputSettings, out imageToSave);
- try
- {
- // Create PNG stream
- if (config.ClipboardFormats.Contains(ClipboardFormat.PNG))
- {
- pngStream = new MemoryStream();
- // PNG works for e.g. Powerpoint
- SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false);
- ImageOutput.SaveToStream(imageToSave, null, pngStream, pngOutputSettings);
- pngStream.Seek(0, SeekOrigin.Begin);
- // Set the PNG stream
- dataObject.SetData(FORMAT_PNG, false, pngStream);
- }
- }
- catch (Exception pngEX)
- {
- LOG.Error("Error creating PNG for the Clipboard.", pngEX);
- }
-
- try
- {
- if (config.ClipboardFormats.Contains(ClipboardFormat.DIB))
- {
- using (MemoryStream tmpBmpStream = new MemoryStream())
- {
- // Save image as BMP
- SurfaceOutputSettings bmpOutputSettings = new SurfaceOutputSettings(OutputFormat.bmp, 100, false);
- ImageOutput.SaveToStream(imageToSave, null, tmpBmpStream, bmpOutputSettings);
-
- dibStream = new MemoryStream();
- // Copy the source, but skip the "BITMAPFILEHEADER" which has a size of 14
- dibStream.Write(tmpBmpStream.GetBuffer(), BITMAPFILEHEADER_LENGTH, (int)tmpBmpStream.Length - BITMAPFILEHEADER_LENGTH);
- }
-
- // Set the DIB to the clipboard DataObject
- dataObject.SetData(DataFormats.Dib, true, dibStream);
- }
- }
- catch (Exception dibEx)
- {
- LOG.Error("Error creating DIB for the Clipboard.", dibEx);
- }
-
- // CF_DibV5
- try
- {
- if (config.ClipboardFormats.Contains(ClipboardFormat.DIBV5))
- {
- // Create the stream for the clipboard
- dibV5Stream = new MemoryStream();
-
- // Create the BITMAPINFOHEADER
- BITMAPINFOHEADER header = new BITMAPINFOHEADER(imageToSave.Width, imageToSave.Height, 32);
- // Make sure we have BI_BITFIELDS, this seems to be normal for Format17?
- header.biCompression = BI_COMPRESSION.BI_BITFIELDS;
- // Create a byte[] to write
- byte[] headerBytes = BinaryStructHelper.ToByteArray(header);
- // Write the BITMAPINFOHEADER to the stream
- dibV5Stream.Write(headerBytes, 0, headerBytes.Length);
-
- // As we have specified BI_COMPRESSION.BI_BITFIELDS, the BitfieldColorMask needs to be added
- BitfieldColorMask colorMask = new BitfieldColorMask();
- // Make sure the values are set
- colorMask.InitValues();
- // Create the byte[] from the struct
- byte[] colorMaskBytes = BinaryStructHelper.ToByteArray(colorMask);
- Array.Reverse(colorMaskBytes);
- // Write to the stream
- dibV5Stream.Write(colorMaskBytes, 0, colorMaskBytes.Length);
-
- // Create the raw bytes for the pixels only
- byte[] bitmapBytes = BitmapToByteArray((Bitmap)imageToSave);
- // Write to the stream
- dibV5Stream.Write(bitmapBytes, 0, bitmapBytes.Length);
-
- // Set the DIBv5 to the clipboard DataObject
- dataObject.SetData(FORMAT_17, true, dibV5Stream);
- }
- }
- catch (Exception dibEx)
- {
- LOG.Error("Error creating DIB for the Clipboard.", dibEx);
- }
-
- // Set the HTML
- if (config.ClipboardFormats.Contains(ClipboardFormat.HTML))
- {
- string tmpFile = ImageOutput.SaveToTmpFile(surface, new SurfaceOutputSettings(OutputFormat.png, 100, false), null);
- string html = getHTMLString(surface, tmpFile);
- dataObject.SetText(html, TextDataFormat.Html);
- }
- else if (config.ClipboardFormats.Contains(ClipboardFormat.HTMLDATAURL))
- {
- string html;
- using (MemoryStream tmpPNGStream = new MemoryStream())
- {
- SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false);
- // Do not allow to reduce the colors, some applications dislike 256 color images
- // reported with bug #3594681
- pngOutputSettings.DisableReduceColors = true;
- // Check if we can use the previously used image
- if (imageToSave.PixelFormat != PixelFormat.Format8bppIndexed)
- {
- ImageOutput.SaveToStream(imageToSave, surface, tmpPNGStream, pngOutputSettings);
- }
- else
- {
- ImageOutput.SaveToStream(surface, tmpPNGStream, pngOutputSettings);
- }
- html = getHTMLDataURLString(surface, tmpPNGStream);
- }
- dataObject.SetText(html, TextDataFormat.Html);
- }
- }
- finally
- {
- // we need to use the SetDataOject before the streams are closed otherwise the buffer will be gone!
- // Check if Bitmap is wanted
- if (config.ClipboardFormats.Contains(ClipboardFormat.BITMAP))
- {
- dataObject.SetImage(imageToSave);
- // Place the DataObject to the clipboard
- SetDataObject(dataObject, true);
- }
- else
- {
- // Place the DataObject to the clipboard
- SetDataObject(dataObject, true);
- }
-
- if (pngStream != null)
- {
- pngStream.Dispose();
- pngStream = null;
- }
-
- if (dibStream != null)
- {
- dibStream.Dispose();
- dibStream = null;
- }
- if (dibV5Stream != null)
- {
- dibV5Stream.Dispose();
- dibV5Stream = null;
- }
- // cleanup if needed
- if (disposeImage && imageToSave != null)
- {
- imageToSave.Dispose();
- }
- }
- }
-
- ///
- /// Helper method so get the bitmap bytes
- /// See: http://stackoverflow.com/a/6570155
- ///
- /// Bitmap
- /// byte[]
- private static byte[] BitmapToByteArray(Bitmap bitmap)
- {
- // Lock the bitmap's bits.
- Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
- BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);
-
- int absStride = Math.Abs(bmpData.Stride);
- int bytes = absStride * bitmap.Height;
- long ptr = bmpData.Scan0.ToInt32();
- // Declare an array to hold the bytes of the bitmap.
- byte[] rgbValues = new byte[bytes];
-
- for (int i = 0; i < bitmap.Height; i++)
- {
- IntPtr pointer = new IntPtr(ptr + (bmpData.Stride * i));
- Marshal.Copy(pointer, rgbValues, absStride * (bitmap.Height - i - 1), absStride);
- }
-
- // Unlock the bits.
- bitmap.UnlockBits(bmpData);
-
- return rgbValues;
- }
-
- ///
- /// Set Object with type Type to the clipboard
- ///
- /// Type
- /// object
- public static void SetClipboardData(Type type, Object obj)
- {
- DataFormats.Format format = DataFormats.GetFormat(type.FullName);
-
- //now copy to clipboard
- IDataObject dataObj = new DataObject();
- dataObj.SetData(format.Name, false, obj);
- // Use false to make the object dissapear when the application stops.
- SetDataObject(dataObj, true);
- }
-
- ///
- /// Retrieve a list of all formats currently on the clipboard
- ///
- /// List with the current formats
- public static List GetFormats()
- {
- return GetFormats(GetDataObject());
- }
-
- ///
- /// Retrieve a list of all formats currently in the IDataObject
- ///
- /// List with the current formats
- public static List GetFormats(IDataObject dataObj)
- {
- string[] formats = null;
-
- if (dataObj != null)
- {
- formats = dataObj.GetFormats();
- }
- if (formats != null)
- {
- LOG.DebugFormat("Got clipboard formats: {0}", String.Join(",", formats));
- return new List(formats);
- }
- return new List();
- }
-
- ///
- /// Check if there is currently something in the dataObject which has the supplied format
- ///
- /// IDataObject
- /// string with format
- /// true if one the format is found
- public static bool ContainsFormat(string format)
- {
- return ContainsFormat(GetDataObject(), new[] { format });
- }
-
- ///
- /// Check if there is currently something on the clipboard which has the supplied format
- ///
- /// string with format
- /// true if one the format is found
- public static bool ContainsFormat(IDataObject dataObject, string format)
- {
- return ContainsFormat(dataObject, new[] { format });
- }
-
- ///
- /// Check if there is currently something on the clipboard which has one of the supplied formats
- ///
- /// string[] with formats
- /// true if one of the formats was found
- public static bool ContainsFormat(string[] formats)
- {
- return ContainsFormat(GetDataObject(), formats);
- }
-
- ///
- /// Check if there is currently something on the clipboard which has one of the supplied formats
- ///
- /// IDataObject
- /// string[] with formats
- /// true if one of the formats was found
- public static bool ContainsFormat(IDataObject dataObject, string[] formats)
- {
- bool formatFound = false;
- List currentFormats = GetFormats(dataObject);
- if (currentFormats == null || currentFormats.Count == 0 || formats == null || formats.Length == 0)
- {
- return false;
- }
- foreach (string format in formats)
- {
- if (currentFormats.Contains(format))
- {
- formatFound = true;
- break;
- }
- }
- return formatFound;
- }
-
- ///
- /// Get Object of type Type from the clipboard
- ///
- /// Type to get
- /// object from clipboard
- public static Object GetClipboardData(Type type)
- {
- string format = type.FullName;
- return GetClipboardData(format);
- }
-
- ///
- /// Get Object for format from IDataObject
- ///
- /// IDataObject
- /// Type to get
- /// object from IDataObject
- public static Object GetFromDataObject(IDataObject dataObj, Type type)
- {
- if (type != null)
- {
- return GetFromDataObject(dataObj, type.FullName);
- }
- return null;
- }
-
- ///
- /// Get ImageFilenames from the IDataObject
- ///
- /// IDataObject
- ///
- public static List GetImageFilenames(IDataObject dataObject)
- {
- List filenames = new List();
- string[] dropFileNames = (string[])dataObject.GetData(DataFormats.FileDrop);
- try
- {
- if (dropFileNames != null && dropFileNames.Length > 0)
- {
- foreach (string filename in dropFileNames)
- {
- string ext = Path.GetExtension(filename).ToLower();
- if ((ext == ".jpg") || (ext == ".jpeg") || (ext == ".tiff") || (ext == ".gif") || (ext == ".png") || (ext == ".bmp") || (ext == ".ico") || (ext == ".wmf"))
- {
- filenames.Add(filename);
- }
- }
- }
- }
- catch (Exception ex)
- {
- LOG.Warn("Ignoring an issue with getting the dropFilenames from the clipboard: ", ex);
- }
- return filenames;
- }
-
- ///
- /// Get Object for format from IDataObject
- ///
- /// IDataObject
- /// format to get
- /// object from IDataObject
- public static Object GetFromDataObject(IDataObject dataObj, string format)
- {
- if (dataObj != null)
- {
- try
- {
- return dataObj.GetData(format);
- }
- catch (Exception e)
- {
- LOG.Error("Error in GetClipboardData.", e);
- }
- }
- return null;
- }
-
- ///
- /// Get Object for format from the clipboard
- ///
- /// format to get
- /// object from clipboard
- public static Object GetClipboardData(string format)
- {
- return GetFromDataObject(GetDataObject(), format);
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/Effects.cs b/Greenshot.ImageEditor/Core/Effects.cs
deleted file mode 100644
index b5e59ef43..000000000
--- a/Greenshot.ImageEditor/Core/Effects.cs
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using GreenshotPlugin;
-using GreenshotPlugin.Core;
-using System;
-using System.ComponentModel;
-using System.Drawing;
-using System.Drawing.Drawing2D;
-using System.Drawing.Imaging;
-using System.Globalization;
-using System.Text;
-
-namespace Greenshot.Core
-{
- ///
- /// Interface to describe an effect
- ///
- public interface IEffect
- {
- ///
- /// Apply this IEffect to the supplied sourceImage.
- /// In the process of applying the supplied matrix will be modified to represent the changes.
- ///
- /// Image to apply the effect to
- /// Matrix with the modifications like rotate, translate etc. this can be used to calculate the new location of elements on a canvas
- /// new image with applied effect
- Image Apply(Image sourceImage, Matrix matrix);
-
- ///
- /// Reset all values to their defaults
- ///
- void Reset();
- }
-
- ///
- /// DropShadowEffect
- ///
- [TypeConverter(typeof(EffectConverter))]
- public class DropShadowEffect : IEffect
- {
- public DropShadowEffect()
- {
- Reset();
- }
-
- public float Darkness
- {
- get;
- set;
- }
- public int ShadowSize
- {
- get;
- set;
- }
- public Point ShadowOffset
- {
- get;
- set;
- }
-
- public virtual void Reset()
- {
- Darkness = 0.6f;
- ShadowSize = 7;
- ShadowOffset = new Point(-1, -1);
- }
-
- public virtual Image Apply(Image sourceImage, Matrix matrix)
- {
- return ImageHelper.CreateShadow(sourceImage, Darkness, ShadowSize, ShadowOffset, matrix, PixelFormat.Format32bppArgb);
- }
- }
-
- ///
- /// TornEdgeEffect extends on DropShadowEffect
- ///
- [TypeConverter(typeof(EffectConverter))]
- public class TornEdgeEffect : DropShadowEffect
- {
- public TornEdgeEffect()
- {
- Reset();
- }
-
- public int ToothHeight
- {
- get;
- set;
- }
- public int HorizontalToothRange
- {
- get;
- set;
- }
- public int VerticalToothRange
- {
- get;
- set;
- }
- public bool[] Edges
- {
- get;
- set;
- }
- public bool GenerateShadow
- {
- get;
- set;
- }
-
- public override void Reset()
- {
- base.Reset();
- ShadowSize = 7;
- ToothHeight = 12;
- HorizontalToothRange = 20;
- VerticalToothRange = 20;
- Edges = new[] { true, true, true, true };
- GenerateShadow = true;
- }
-
- public override Image Apply(Image sourceImage, Matrix matrix)
- {
- Image tmpTornImage = ImageHelper.CreateTornEdge(sourceImage, ToothHeight, HorizontalToothRange, VerticalToothRange, Edges);
- if (GenerateShadow)
- {
- using (tmpTornImage)
- {
- return ImageHelper.CreateShadow(tmpTornImage, Darkness, ShadowSize, ShadowOffset, matrix, PixelFormat.Format32bppArgb);
- }
- }
- return tmpTornImage;
- }
- }
-
- ///
- /// GrayscaleEffect
- ///
- public class GrayscaleEffect : IEffect
- {
- public Image Apply(Image sourceImage, Matrix matrix)
- {
- return ImageHelper.CreateGrayscale(sourceImage);
- }
-
- public void Reset()
- {
- // No settings to reset
- }
- }
-
- ///
- /// MonochromeEffect
- ///
- public class MonochromeEffect : IEffect
- {
- private readonly byte _threshold;
-
- /// Threshold for monochrome filter (0 - 255), lower value means less black
- public MonochromeEffect(byte threshold)
- {
- _threshold = threshold;
- }
-
- public void Reset()
- {
- // Modify the threshold to have a default, which is reset here
- }
-
- public Image Apply(Image sourceImage, Matrix matrix)
- {
- return ImageHelper.CreateMonochrome(sourceImage, _threshold);
- }
- }
-
- ///
- /// AdjustEffect
- ///
- public class AdjustEffect : IEffect
- {
- public AdjustEffect()
- {
- Reset();
- }
-
- public float Contrast
- {
- get;
- set;
- }
- public float Brightness
- {
- get;
- set;
- }
- public float Gamma
- {
- get;
- set;
- }
-
- public void Reset()
- {
- Contrast = 1f;
- Brightness = 1f;
- Gamma = 1f;
- }
-
- public Image Apply(Image sourceImage, Matrix matrix)
- {
- return ImageHelper.Adjust(sourceImage, Brightness, Contrast, Gamma);
- }
- }
-
- ///
- /// ReduceColorsEffect
- ///
- public class ReduceColorsEffect : IEffect
- {
- public ReduceColorsEffect()
- {
- Reset();
- }
-
- public int Colors
- {
- get;
- set;
- }
-
- public void Reset()
- {
- Colors = 256;
- }
-
- public Image Apply(Image sourceImage, Matrix matrix)
- {
- using (WuQuantizer quantizer = new WuQuantizer((Bitmap)sourceImage))
- {
- int colorCount = quantizer.GetColorCount();
- if (colorCount > Colors)
- {
- try
- {
- return quantizer.GetQuantizedImage(Colors);
- }
- catch (Exception e)
- {
- LOG.Warn("Error occurred while Quantizing the image, ignoring and using original. Error: ", e);
- }
- }
- }
- return null;
- }
- }
-
- ///
- /// InvertEffect
- ///
- public class InvertEffect : IEffect
- {
- public Image Apply(Image sourceImage, Matrix matrix)
- {
- return ImageHelper.CreateNegative(sourceImage);
- }
-
- public void Reset()
- {
- // No settings to reset
- }
- }
-
- ///
- /// BorderEffect
- ///
- public class BorderEffect : IEffect
- {
- public BorderEffect()
- {
- Reset();
- }
-
- public Color Color
- {
- get;
- set;
- }
- public int Width
- {
- get;
- set;
- }
-
- public void Reset()
- {
- Width = 2;
- Color = Color.Black;
- }
-
- public Image Apply(Image sourceImage, Matrix matrix)
- {
- return ImageHelper.CreateBorder(sourceImage, Width, Color, sourceImage.PixelFormat, matrix);
- }
- }
-
- ///
- /// RotateEffect
- ///
- public class RotateEffect : IEffect
- {
- public RotateEffect(int angle)
- {
- Angle = angle;
- }
-
- public int Angle
- {
- get;
- set;
- }
-
- public void Reset()
- {
- // Angle doesn't have a default value
- }
-
- public Image Apply(Image sourceImage, Matrix matrix)
- {
- RotateFlipType flipType;
- if (Angle == 90)
- {
- matrix.Rotate(90, MatrixOrder.Append);
- matrix.Translate(sourceImage.Height, 0, MatrixOrder.Append);
- flipType = RotateFlipType.Rotate90FlipNone;
- }
- else if (Angle == -90 || Angle == 270)
- {
- flipType = RotateFlipType.Rotate270FlipNone;
- matrix.Rotate(-90, MatrixOrder.Append);
- matrix.Translate(0, sourceImage.Width, MatrixOrder.Append);
- }
- else
- {
- throw new NotSupportedException("Currently only an angle of 90 or -90 (270) is supported.");
- }
- return ImageHelper.RotateFlip(sourceImage, flipType);
- }
- }
-
- ///
- /// ResizeEffect
- ///
- public class ResizeEffect : IEffect
- {
- public ResizeEffect(int width, int height, bool maintainAspectRatio)
- {
- Width = width;
- Height = height;
- MaintainAspectRatio = maintainAspectRatio;
- }
-
- public int Width
- {
- get;
- set;
- }
- public int Height
- {
- get;
- set;
- }
- public bool MaintainAspectRatio
- {
- get;
- set;
- }
-
- public void Reset()
- {
- // values don't have a default value
- }
-
- public Image Apply(Image sourceImage, Matrix matrix)
- {
- return ImageHelper.ResizeImage(sourceImage, MaintainAspectRatio, Width, Height, matrix);
- }
- }
-
- ///
- /// ResizeCanvasEffect
- ///
- public class ResizeCanvasEffect : IEffect
- {
- public ResizeCanvasEffect(int left, int right, int top, int bottom)
- {
- Left = left;
- Right = right;
- Top = top;
- Bottom = bottom;
- BackgroundColor = Color.Empty; // Uses the default background color depending on the format
- }
-
- public int Left
- {
- get;
- set;
- }
- public int Right
- {
- get;
- set;
- }
- public int Top
- {
- get;
- set;
- }
- public int Bottom
- {
- get;
- set;
- }
- public Color BackgroundColor
- {
- get;
- set;
- }
-
- public void Reset()
- {
- // values don't have a default value
- }
-
- public Image Apply(Image sourceImage, Matrix matrix)
- {
- return ImageHelper.ResizeCanvas(sourceImage, BackgroundColor, Left, Right, Top, Bottom, matrix);
- }
- }
-
- public class EffectConverter : TypeConverter
- {
- // Fix to prevent BUG-1753
- private readonly NumberFormatInfo numberFormatInfo = new NumberFormatInfo();
-
- public EffectConverter()
- {
- numberFormatInfo.NumberDecimalSeparator = ".";
- numberFormatInfo.NumberGroupSeparator = ",";
- }
-
- public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
- {
- if (sourceType == typeof(string))
- {
- return true;
- }
- return base.CanConvertFrom(context, sourceType);
- }
-
- public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
- {
- if (destinationType == typeof(string))
- {
- return true;
- }
- if (destinationType == typeof(DropShadowEffect))
- {
- return true;
- }
- if (destinationType == typeof(TornEdgeEffect))
- {
- return true;
- }
- return base.CanConvertTo(context, destinationType);
- }
-
- public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
- {
- // to string
- if (destinationType == typeof(string))
- {
- StringBuilder sb = new StringBuilder();
- if (value.GetType() == typeof(DropShadowEffect))
- {
- DropShadowEffect effect = value as DropShadowEffect;
- RetrieveDropShadowEffectValues(effect, sb);
- return sb.ToString();
- }
- if (value.GetType() == typeof(TornEdgeEffect))
- {
- TornEdgeEffect effect = value as TornEdgeEffect;
- RetrieveDropShadowEffectValues(effect, sb);
- sb.Append("|");
- RetrieveTornEdgeEffectValues(effect, sb);
- return sb.ToString();
- }
- }
- // from string
- if (value is string)
- {
- string settings = value as string;
- if (destinationType == typeof(DropShadowEffect))
- {
- DropShadowEffect effect = new DropShadowEffect();
- ApplyDropShadowEffectValues(settings, effect);
- return effect;
- }
- if (destinationType == typeof(TornEdgeEffect))
- {
- TornEdgeEffect effect = new TornEdgeEffect();
- ApplyDropShadowEffectValues(settings, effect);
- ApplyTornEdgeEffectValues(settings, effect);
- return effect;
- }
- }
- return base.ConvertTo(context, culture, value, destinationType);
- }
-
- public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
- {
- if (value != null && value is string)
- {
- string settings = value as string;
- if (settings.Contains("ToothHeight"))
- {
- return ConvertTo(context, culture, value, typeof(TornEdgeEffect));
- }
- return ConvertTo(context, culture, value, typeof(DropShadowEffect));
- }
- return base.ConvertFrom(context, culture, value);
- }
-
- private void ApplyDropShadowEffectValues(string valuesString, DropShadowEffect effect)
- {
- string[] values = valuesString.Split('|');
- foreach (string nameValuePair in values)
- {
- string[] pair = nameValuePair.Split(':');
- switch (pair[0])
- {
- case "Darkness":
- float darkness;
- // Fix to prevent BUG-1753
- if (pair[1] != null && float.TryParse(pair[1], NumberStyles.Float, numberFormatInfo, out darkness))
- {
- if (darkness <= 1.0)
- {
- effect.Darkness = darkness;
- }
- }
- break;
- case "ShadowSize":
- int shadowSize;
- if (int.TryParse(pair[1], out shadowSize))
- {
- effect.ShadowSize = shadowSize;
- }
- break;
- case "ShadowOffset":
- Point shadowOffset = new Point();
- int shadowOffsetX;
- int shadowOffsetY;
- string[] coordinates = pair[1].Split(',');
- if (int.TryParse(coordinates[0], out shadowOffsetX))
- {
- shadowOffset.X = shadowOffsetX;
- }
- if (int.TryParse(coordinates[1], out shadowOffsetY))
- {
- shadowOffset.Y = shadowOffsetY;
- }
- effect.ShadowOffset = shadowOffset;
- break;
- }
- }
- }
-
- private void ApplyTornEdgeEffectValues(string valuesString, TornEdgeEffect effect)
- {
- string[] values = valuesString.Split('|');
- foreach (string nameValuePair in values)
- {
- string[] pair = nameValuePair.Split(':');
- switch (pair[0])
- {
- case "GenerateShadow":
- bool generateShadow;
- if (bool.TryParse(pair[1], out generateShadow))
- {
- effect.GenerateShadow = generateShadow;
- }
- break;
- case "ToothHeight":
- int toothHeight;
- if (int.TryParse(pair[1], out toothHeight))
- {
- effect.ToothHeight = toothHeight;
- }
- break;
- case "HorizontalToothRange":
- int horizontalToothRange;
- if (int.TryParse(pair[1], out horizontalToothRange))
- {
- effect.HorizontalToothRange = horizontalToothRange;
- }
- break;
- case "VerticalToothRange":
- int verticalToothRange;
- if (int.TryParse(pair[1], out verticalToothRange))
- {
- effect.VerticalToothRange = verticalToothRange;
- }
- break;
- case "Edges":
- string[] edges = pair[1].Split(',');
- bool edge;
- if (bool.TryParse(edges[0], out edge))
- {
- effect.Edges[0] = edge;
- }
- if (bool.TryParse(edges[1], out edge))
- {
- effect.Edges[1] = edge;
- }
- if (bool.TryParse(edges[2], out edge))
- {
- effect.Edges[2] = edge;
- }
- if (bool.TryParse(edges[3], out edge))
- {
- effect.Edges[3] = edge;
- }
- break;
- }
- }
- }
-
- private void RetrieveDropShadowEffectValues(DropShadowEffect effect, StringBuilder sb)
- {
- // Fix to prevent BUG-1753 is to use the numberFormatInfo
- sb.AppendFormat("Darkness:{0}|ShadowSize:{1}|ShadowOffset:{2},{3}", effect.Darkness.ToString("F2", numberFormatInfo), effect.ShadowSize, effect.ShadowOffset.X, effect.ShadowOffset.Y);
- }
-
- private void RetrieveTornEdgeEffectValues(TornEdgeEffect effect, StringBuilder sb)
- {
- sb.AppendFormat("GenerateShadow:{0}|ToothHeight:{1}|HorizontalToothRange:{2}|VerticalToothRange:{3}|Edges:{4},{5},{6},{7}", effect.GenerateShadow, effect.ToothHeight, effect.HorizontalToothRange, effect.VerticalToothRange, effect.Edges[0], effect.Edges[1], effect.Edges[2], effect.Edges[3]);
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/EnumExtensions.cs b/Greenshot.ImageEditor/Core/EnumExtensions.cs
deleted file mode 100644
index 6b76fec98..000000000
--- a/Greenshot.ImageEditor/Core/EnumExtensions.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-
-namespace GreenshotPlugin.Core
-{
- public static class EnumerationExtensions
- {
- public static bool Has(this Enum type, T value)
- {
- Type underlyingType = Enum.GetUnderlyingType(value.GetType());
- try
- {
- if (underlyingType == typeof(int))
- {
- return (((int)(object)type & (int)(object)value) == (int)(object)value);
- }
- else if (underlyingType == typeof(uint))
- {
- return (((uint)(object)type & (uint)(object)value) == (uint)(object)value);
- }
- }
- catch
- {
- }
- return false;
- }
-
- public static bool Is(this Enum type, T value)
- {
- Type underlyingType = Enum.GetUnderlyingType(value.GetType());
- try
- {
- if (underlyingType == typeof(int))
- {
- return (int)(object)type == (int)(object)value;
- }
- else if (underlyingType == typeof(uint))
- {
- return (uint)(object)type == (uint)(object)value;
- }
- }
- catch
- {
- }
- return false;
- }
-
- ///
- /// Add a flag to an enum
- ///
- ///
- ///
- ///
- public static T Add(this Enum type, T value)
- {
- Type underlyingType = Enum.GetUnderlyingType(value.GetType());
- try
- {
- if (underlyingType == typeof(int))
- {
- return (T)(object)(((int)(object)type | (int)(object)value));
- }
- else if (underlyingType == typeof(uint))
- {
- return (T)(object)(((uint)(object)type | (uint)(object)value));
- }
- }
- catch (Exception ex)
- {
- throw new ArgumentException(string.Format("Could not append value '{0}' to enumerated type '{1}'.", value, typeof(T).Name), ex);
- }
- throw new ArgumentException(string.Format("Could not append value '{0}' to enumerated type '{1}'.", value, typeof(T).Name));
- }
-
- ///
- /// Remove a flag from an enum type
- ///
- ///
- ///
- ///
- public static T Remove(this Enum type, T value)
- {
- Type underlyingType = Enum.GetUnderlyingType(value.GetType());
- try
- {
- if (underlyingType == typeof(int))
- {
- return (T)(object)(((int)(object)type & ~(int)(object)value));
- }
- else if (underlyingType == typeof(uint))
- {
- return (T)(object)(((uint)(object)type & ~(uint)(object)value));
- }
- }
- catch (Exception ex)
- {
- throw new ArgumentException(string.Format("Could not remove value '{0}' from enumerated type '{1}'.", value, typeof(T).Name), ex);
- }
- throw new ArgumentException(string.Format("Could not remove value '{0}' from enumerated type '{1}'.", value, typeof(T).Name));
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/EventDelay.cs b/Greenshot.ImageEditor/Core/EventDelay.cs
deleted file mode 100644
index d6787077d..000000000
--- a/Greenshot.ImageEditor/Core/EventDelay.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-
-namespace GreenshotPlugin.Core
-{
- public class EventDelay
- {
- private long lastCheck;
- private readonly long waitTime;
-
- public EventDelay(long ticks)
- {
- waitTime = ticks;
- }
-
- public bool Check()
- {
- lock (this)
- {
- long now = DateTime.Now.Ticks;
- bool isPassed = now - lastCheck > waitTime;
- lastCheck = now;
- return isPassed;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/FastBitmap.cs b/Greenshot.ImageEditor/Core/FastBitmap.cs
deleted file mode 100644
index 53d713c83..000000000
--- a/Greenshot.ImageEditor/Core/FastBitmap.cs
+++ /dev/null
@@ -1,1167 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-
-namespace GreenshotPlugin.Core
-{
- ///
- /// The interface for the FastBitmap
- ///
- public interface IFastBitmap : IDisposable
- {
- ///
- /// Get the color at x,y
- /// The returned Color object depends on the underlying pixel format
- ///
- /// int x
- /// int y
- /// Color
- Color GetColorAt(int x, int y);
-
- ///
- /// Set the color at the specified location
- ///
- /// int x
- /// int y
- /// Color
- void SetColorAt(int x, int y, Color color);
-
- ///
- /// Get the color at x,y
- /// The returned byte[] color depends on the underlying pixel format
- ///
- /// int x
- /// int y
- /// Set the color at the specified location
- ///
- /// int x
- /// int y
- /// byte[] color
- void SetColorAt(int x, int y, byte[] color);
-
- ///
- /// Lock the bitmap
- ///
- void Lock();
-
- ///
- /// Unlock the bitmap
- ///
- void Unlock();
-
- ///
- /// Unlock the bitmap and get the underlying bitmap in one call
- ///
- ///
- Bitmap UnlockAndReturnBitmap();
-
- ///
- /// Size of the underlying image
- ///
- Size Size
- {
- get;
- }
-
- ///
- /// Height of the image area that this fastbitmap covers
- ///
- int Height
- {
- get;
- }
-
- ///
- /// Width of the image area that this fastbitmap covers
- ///
- int Width
- {
- get;
- }
-
- ///
- /// Top of the image area that this fastbitmap covers
- ///
- int Top
- {
- get;
- }
-
- ///
- /// Left of the image area that this fastbitmap covers
- ///
- int Left
- {
- get;
- }
-
- ///
- /// Right of the image area that this fastbitmap covers
- ///
- int Right
- {
- get;
- }
-
- ///
- /// Bottom of the image area that this fastbitmap covers
- ///
- int Bottom
- {
- get;
- }
-
- ///
- /// Does the underlying image need to be disposed
- ///
- bool NeedsDispose
- {
- get;
- set;
- }
-
- ///
- /// Returns if this FastBitmap has an alpha channel
- ///
- bool hasAlphaChannel
- {
- get;
- }
-
- ///
- /// Draw the stored bitmap to the destionation bitmap at the supplied point
- ///
- /// Graphics
- /// Point with location
- void DrawTo(Graphics graphics, Point destination);
-
- ///
- /// Draw the stored Bitmap on the Destination bitmap with the specified rectangle
- /// Be aware that the stored bitmap will be resized to the specified rectangle!!
- ///
- /// Graphics
- /// Rectangle with destination
- void DrawTo(Graphics graphics, Rectangle destinationRect);
-
- ///
- /// Return true if the coordinates are inside the FastBitmap
- ///
- ///
- ///
- ///
- bool Contains(int x, int y);
-
- ///
- /// Set the bitmap resolution
- ///
- ///
- ///
- void SetResolution(float horizontal, float vertical);
- }
-
- ///
- /// This interface can be used for when offsetting is needed
- ///
- public interface IFastBitmapWithOffset : IFastBitmap
- {
- ///
- /// Return true if the coordinates are inside the FastBitmap
- ///
- ///
- ///
- ///
- new bool Contains(int x, int y);
-
- ///
- /// Set the color at the specified location, using offsetting so the original coordinates can be used
- ///
- /// int x
- /// int y
- /// Color color
- new void SetColorAt(int x, int y, Color color);
-
- ///
- /// Set the color at the specified location, using offsetting so the original coordinates can be used
- ///
- /// int x
- /// int y
- /// byte[] color
- new void SetColorAt(int x, int y, byte[] color);
-
- ///
- /// Get the color at x,y
- /// The returned Color object depends on the underlying pixel format
- ///
- /// int x
- /// int y
- /// Color
- new Color GetColorAt(int x, int y);
-
- ///
- /// Get the color at x,y, using offsetting so the original coordinates can be used
- /// The returned byte[] color depends on the underlying pixel format
- ///
- /// int x
- /// int y
- /// This interface can be used for when clipping is needed
- ///
- public interface IFastBitmapWithClip : IFastBitmap
- {
- Rectangle Clip
- {
- get;
- set;
- }
-
- bool InvertClip
- {
- get;
- set;
- }
-
- ///
- /// Set the color at the specified location, this doesn't do anything if the location is excluded due to clipping
- ///
- /// int x
- /// int y
- /// Color color
- new void SetColorAt(int x, int y, Color color);
-
- ///
- /// Set the color at the specified location, this doesn't do anything if the location is excluded due to clipping
- ///
- /// int x
- /// int y
- /// byte[] color
- new void SetColorAt(int x, int y, byte[] color);
-
- ///
- /// Return true if the coordinates are inside the FastBitmap and not clipped
- ///
- ///
- ///
- ///
- new bool Contains(int x, int y);
- }
-
- ///
- /// This interface is implemented when there is a alpha-blending possibility
- ///
- public interface IFastBitmapWithBlend : IFastBitmap
- {
- Color BackgroundBlendColor
- {
- get;
- set;
- }
-
- Color GetBlendedColorAt(int x, int y);
- }
-
- ///
- /// The base class for the fast bitmap implementation
- ///
- public unsafe abstract class FastBitmap : IFastBitmap, IFastBitmapWithClip, IFastBitmapWithOffset
- {
- protected const int PIXELFORMAT_INDEX_A = 3;
- protected const int PIXELFORMAT_INDEX_R = 2;
- protected const int PIXELFORMAT_INDEX_G = 1;
- protected const int PIXELFORMAT_INDEX_B = 0;
-
- public const int COLOR_INDEX_R = 0;
- public const int COLOR_INDEX_G = 1;
- public const int COLOR_INDEX_B = 2;
- public const int COLOR_INDEX_A = 3;
-
- protected Rectangle area = Rectangle.Empty;
- ///
- /// If this is set to true, the bitmap will be disposed when disposing the IFastBitmap
- ///
- public bool NeedsDispose
- {
- get;
- set;
- }
-
- public Rectangle Clip
- {
- get;
- set;
- }
-
- public bool InvertClip
- {
- get;
- set;
- }
-
- ///
- /// The bitmap for which the FastBitmap is creating access
- ///
- protected Bitmap bitmap;
-
- protected BitmapData bmData;
- protected int stride; /* bytes per pixel row */
- protected bool bitsLocked;
- protected byte* pointer;
-
- public static IFastBitmap Create(Bitmap source)
- {
- return Create(source, Rectangle.Empty);
- }
-
- public void SetResolution(float horizontal, float vertical)
- {
- bitmap.SetResolution(horizontal, vertical);
- }
-
- ///
- /// Factory for creating a FastBitmap depending on the pixelformat of the source
- /// The supplied rectangle specifies the area for which the FastBitmap does its thing
- ///
- /// Bitmap to access
- /// Rectangle which specifies the area to have access to, can be Rectangle.Empty for the whole image
- /// IFastBitmap
- public static IFastBitmap Create(Bitmap source, Rectangle area)
- {
- switch (source.PixelFormat)
- {
- case PixelFormat.Format8bppIndexed:
- return new FastChunkyBitmap(source, area);
- case PixelFormat.Format24bppRgb:
- return new Fast24RGBBitmap(source, area);
- case PixelFormat.Format32bppRgb:
- return new Fast32RGBBitmap(source, area);
- case PixelFormat.Format32bppArgb:
- case PixelFormat.Format32bppPArgb:
- return new Fast32ARGBBitmap(source, area);
- default:
- throw new NotSupportedException(string.Format("Not supported Pixelformat {0}", source.PixelFormat));
- }
- }
-
- ///
- /// Factory for creating a FastBitmap as a destination for the source
- ///
- /// Bitmap to clone
- /// IFastBitmap
- public static IFastBitmap CreateCloneOf(Image source)
- {
- return CreateCloneOf(source, source.PixelFormat, Rectangle.Empty);
- }
-
- ///
- /// Factory for creating a FastBitmap as a destination for the source
- ///
- /// Bitmap to clone
- /// new Pixelformat
- /// IFastBitmap
- public static IFastBitmap CreateCloneOf(Image source, PixelFormat pixelFormat)
- {
- return CreateCloneOf(source, pixelFormat, Rectangle.Empty);
- }
-
- ///
- /// Factory for creating a FastBitmap as a destination for the source
- ///
- /// Bitmap to clone
- /// Area of the bitmap to access, can be Rectangle.Empty for the whole
- /// IFastBitmap
- public static IFastBitmap CreateCloneOf(Image source, Rectangle area)
- {
- return CreateCloneOf(source, PixelFormat.DontCare, area);
- }
-
- ///
- /// Factory for creating a FastBitmap as a destination for the source
- ///
- /// Bitmap to clone
- /// Pixelformat of the cloned bitmap
- /// Area of the bitmap to access, can be Rectangle.Empty for the whole
- /// IFastBitmap
- public static IFastBitmap CreateCloneOf(Image source, PixelFormat pixelFormat, Rectangle area)
- {
- Bitmap destination = ImageHelper.CloneArea(source, area, pixelFormat);
- FastBitmap fastBitmap = Create(destination) as FastBitmap;
- fastBitmap.NeedsDispose = true;
- fastBitmap.Left = area.Left;
- fastBitmap.Top = area.Top;
- return fastBitmap;
- }
-
- ///
- /// Factory for creating a FastBitmap as a destination
- ///
- ///
- ///
- ///
- /// IFastBitmap
- public static IFastBitmap CreateEmpty(Size newSize, PixelFormat pixelFormat, Color backgroundColor)
- {
- Bitmap destination = ImageHelper.CreateEmpty(newSize.Width, newSize.Height, pixelFormat, backgroundColor, 96f, 96f);
- IFastBitmap fastBitmap = Create(destination);
- fastBitmap.NeedsDispose = true;
- return fastBitmap;
- }
-
- ///
- /// Constructor which stores the image and locks it when called
- ///
- ///
- protected FastBitmap(Bitmap bitmap, Rectangle area)
- {
- this.bitmap = bitmap;
- Rectangle bitmapArea = new Rectangle(Point.Empty, bitmap.Size);
- if (area != Rectangle.Empty)
- {
- area.Intersect(bitmapArea);
- this.area = area;
- }
- else
- {
- this.area = bitmapArea;
- }
- // As the lock takes care that only the specified area is made available we need to calculate the offset
- Left = area.Left;
- Top = area.Top;
- // Default cliping is done to the area without invert
- Clip = this.area;
- InvertClip = false;
- // Always lock, so we don't need to do this ourselves
- Lock();
- }
-
- ///
- /// Return the size of the image
- ///
- public Size Size
- {
- get
- {
- if (area == Rectangle.Empty)
- {
- return bitmap.Size;
- }
- return area.Size;
- }
- }
-
- ///
- /// Return the width of the image
- ///
- public int Width
- {
- get
- {
- if (area == Rectangle.Empty)
- {
- return bitmap.Width;
- }
- return area.Width;
- }
- }
-
- ///
- /// Return the height of the image
- ///
- public int Height
- {
- get
- {
- if (area == Rectangle.Empty)
- {
- return bitmap.Height;
- }
- return area.Height;
- }
- }
-
- private int left;
- ///
- /// Return the left of the fastbitmap, this is also used as an offset
- ///
- public int Left
- {
- get
- {
- return 0;
- }
- set
- {
- left = value;
- }
- }
-
- ///
- /// Return the left of the fastbitmap, this is also used as an offset
- ///
- int IFastBitmapWithOffset.Left
- {
- get
- {
- return left;
- }
- set
- {
- left = value;
- }
- }
-
- private int top;
- ///
- /// Return the top of the fastbitmap, this is also used as an offset
- ///
- public int Top
- {
- get
- {
- return 0;
- }
- set
- {
- top = value;
- }
- }
-
- ///
- /// Return the top of the fastbitmap, this is also used as an offset
- ///
- int IFastBitmapWithOffset.Top
- {
- get
- {
- return top;
- }
- set
- {
- top = value;
- }
- }
-
- ///
- /// Return the right of the fastbitmap
- ///
- public int Right
- {
- get
- {
- return Left + Width;
- }
- }
-
- ///
- /// Return the bottom of the fastbitmap
- ///
- public int Bottom
- {
- get
- {
- return Top + Height;
- }
- }
-
- ///
- /// Returns the underlying bitmap, unlocks it and prevents that it will be disposed
- ///
- public Bitmap UnlockAndReturnBitmap()
- {
- if (bitsLocked)
- {
- Unlock();
- }
- NeedsDispose = false;
- return bitmap;
- }
-
- public virtual bool hasAlphaChannel
- {
- get
- {
- return false;
- }
- }
-
- ///
- /// Destructor
- ///
- ~FastBitmap()
- {
- Dispose(false);
- }
-
- ///
- /// The public accessible Dispose
- /// Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
- ///
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- // 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!
- ///
- ///
- protected virtual void Dispose(bool disposing)
- {
- Unlock();
- if (disposing)
- {
- if (bitmap != null && NeedsDispose)
- {
- bitmap.Dispose();
- }
- }
- bitmap = null;
- bmData = null;
- pointer = null;
- }
-
- ///
- /// Lock the bitmap so we have direct access to the memory
- ///
- public void Lock()
- {
- if (Width > 0 && Height > 0 && !bitsLocked)
- {
- bmData = bitmap.LockBits(area, ImageLockMode.ReadWrite, bitmap.PixelFormat);
- bitsLocked = true;
-
- IntPtr Scan0 = bmData.Scan0;
- pointer = (byte*)(void*)Scan0;
- stride = bmData.Stride;
- }
- }
-
- ///
- /// Unlock the System Memory
- ///
- public void Unlock()
- {
- if (bitsLocked)
- {
- bitmap.UnlockBits(bmData);
- bitsLocked = false;
- }
- }
-
- ///
- /// Draw the stored bitmap to the destionation bitmap at the supplied point
- ///
- ///
- ///
- public void DrawTo(Graphics graphics, Point destination)
- {
- DrawTo(graphics, new Rectangle(destination, area.Size));
- }
-
- ///
- /// Draw the stored Bitmap on the Destination bitmap with the specified rectangle
- /// Be aware that the stored bitmap will be resized to the specified rectangle!!
- ///
- ///
- ///
- ///
- public void DrawTo(Graphics graphics, Rectangle destinationRect)
- {
- // Make sure this.bitmap is unlocked, if it was locked
- bool isLocked = bitsLocked;
- if (isLocked)
- {
- Unlock();
- }
-
- graphics.DrawImage(bitmap, destinationRect, area, GraphicsUnit.Pixel);
- }
-
- ///
- /// returns true if x & y are inside the FastBitmap
- ///
- ///
- ///
- /// true if x & y are inside the FastBitmap
- public bool Contains(int x, int y)
- {
- return area.Contains(x - Left, y - Top);
- }
-
- public abstract Color GetColorAt(int x, int y);
-
- public abstract void SetColorAt(int x, int y, Color color);
-
- public abstract void GetColorAt(int x, int y, byte[] color);
-
- public abstract void SetColorAt(int x, int y, byte[] color);
-
- #region IFastBitmapWithClip
-
- bool IFastBitmapWithClip.Contains(int x, int y)
- {
- bool contains = Clip.Contains(x, y);
- if (InvertClip)
- {
- return !contains;
- }
- else
- {
- return contains;
- }
- }
-
- void IFastBitmapWithClip.SetColorAt(int x, int y, byte[] color)
- {
- bool contains = Clip.Contains(x, y);
- if ((InvertClip && contains) || (!InvertClip && !contains))
- {
- return;
- }
- SetColorAt(x, y, color);
- }
-
- void IFastBitmapWithClip.SetColorAt(int x, int y, Color color)
- {
- bool contains = Clip.Contains(x, y);
- if ((InvertClip && contains) || (!InvertClip && !contains))
- {
- return;
- }
- SetColorAt(x, y, color);
- }
-
- #endregion IFastBitmapWithClip
-
- #region IFastBitmapWithOffset
-
- ///
- /// returns true if x & y are inside the FastBitmap
- ///
- ///
- ///
- /// true if x & y are inside the FastBitmap
- bool IFastBitmapWithOffset.Contains(int x, int y)
- {
- return area.Contains(x - Left, y - Top);
- }
-
- Color IFastBitmapWithOffset.GetColorAt(int x, int y)
- {
- x -= left;
- y -= top;
- return GetColorAt(x, y);
- }
-
- void IFastBitmapWithOffset.GetColorAt(int x, int y, byte[] color)
- {
- x -= left;
- y -= top;
- GetColorAt(x, y, color);
- }
-
- void IFastBitmapWithOffset.SetColorAt(int x, int y, byte[] color)
- {
- x -= left;
- y -= top;
- SetColorAt(x, y, color);
- }
-
- void IFastBitmapWithOffset.SetColorAt(int x, int y, Color color)
- {
- x -= left;
- y -= top;
- SetColorAt(x, y, color);
- }
-
- #endregion IFastBitmapWithOffset
- }
-
- ///
- /// This is the implementation of the FastBitmat for the 8BPP pixelformat
- ///
- public unsafe class FastChunkyBitmap : FastBitmap
- {
- // Used for indexed images
- private readonly Color[] colorEntries;
- private readonly Dictionary colorCache = new Dictionary();
-
- public FastChunkyBitmap(Bitmap source, Rectangle area) : base(source, area)
- {
- colorEntries = bitmap.Palette.Entries;
- }
-
- ///
- /// Get the color from the specified location
- ///
- ///
- ///
- /// Color
- public override Color GetColorAt(int x, int y)
- {
- int offset = x + (y * stride);
- byte colorIndex = pointer[offset];
- return colorEntries[colorIndex];
- }
-
- ///
- /// Get the color from the specified location into the specified array
- ///
- ///
- ///
- /// byte[4] as reference
- public override void GetColorAt(int x, int y, byte[] color)
- {
- throw new NotImplementedException("No performance gain!");
- }
-
- ///
- /// Set the color at the specified location from the specified array
- ///
- ///
- ///
- /// byte[4] as reference
- public override void SetColorAt(int x, int y, byte[] color)
- {
- throw new NotImplementedException("No performance gain!");
- }
-
- ///
- /// Get the color-index from the specified location
- ///
- ///
- ///
- /// byte with index
- public byte GetColorIndexAt(int x, int y)
- {
- int offset = x + (y * stride);
- return pointer[offset];
- }
-
- ///
- /// Set the color-index at the specified location
- ///
- ///
- ///
- ///
- public void SetColorIndexAt(int x, int y, byte colorIndex)
- {
- int offset = x + (y * stride);
- pointer[offset] = colorIndex;
- }
-
- ///
- /// Set the supplied color at the specified location.
- /// Throws an ArgumentException if the color is not in the palette
- ///
- ///
- ///
- /// Color to set
- public override void SetColorAt(int x, int y, Color color)
- {
- int offset = x + (y * stride);
- byte colorIndex;
- if (!colorCache.TryGetValue(color, out colorIndex))
- {
- bool foundColor = false;
- for (colorIndex = 0; colorIndex < colorEntries.Length; colorIndex++)
- {
- if (color == colorEntries[colorIndex])
- {
- colorCache.Add(color, colorIndex);
- foundColor = true;
- break;
- }
- }
- if (!foundColor)
- {
- throw new ArgumentException("No such color!");
- }
- }
- pointer[offset] = colorIndex;
- }
- }
-
- ///
- /// This is the implementation of the IFastBitmap for 24 bit images (no Alpha)
- ///
- public unsafe class Fast24RGBBitmap : FastBitmap
- {
- public Fast24RGBBitmap(Bitmap source, Rectangle area) : base(source, area)
- {
- }
-
- ///
- /// Retrieve the color at location x,y
- /// Before the first time this is called the Lock() should be called once!
- ///
- /// X coordinate
- /// Y Coordinate
- /// Color
- public override Color GetColorAt(int x, int y)
- {
- int offset = (x * 3) + (y * stride);
- return Color.FromArgb(255, pointer[PIXELFORMAT_INDEX_R + offset], pointer[PIXELFORMAT_INDEX_G + offset], pointer[PIXELFORMAT_INDEX_B + offset]);
- }
-
- ///
- /// Set the color at location x,y
- /// Before the first time this is called the Lock() should be called once!
- ///
- ///
- ///
- ///
- public override void SetColorAt(int x, int y, Color color)
- {
- int offset = (x * 3) + (y * stride);
- pointer[PIXELFORMAT_INDEX_R + offset] = color.R;
- pointer[PIXELFORMAT_INDEX_G + offset] = color.G;
- pointer[PIXELFORMAT_INDEX_B + offset] = color.B;
- }
-
- ///
- /// Get the color from the specified location into the specified array
- ///
- ///
- ///
- /// byte[4] as reference (r,g,b)
- public override void GetColorAt(int x, int y, byte[] color)
- {
- int offset = (x * 3) + (y * stride);
- color[PIXELFORMAT_INDEX_R] = pointer[PIXELFORMAT_INDEX_R + offset];
- color[PIXELFORMAT_INDEX_G] = pointer[PIXELFORMAT_INDEX_G + offset];
- color[PIXELFORMAT_INDEX_B] = pointer[PIXELFORMAT_INDEX_B + offset];
- }
-
- ///
- /// Set the color at the specified location from the specified array
- ///
- ///
- ///
- /// byte[4] as reference (r,g,b)
- public override void SetColorAt(int x, int y, byte[] color)
- {
- int offset = (x * 3) + (y * stride);
- pointer[PIXELFORMAT_INDEX_R + offset] = color[PIXELFORMAT_INDEX_R];
- pointer[PIXELFORMAT_INDEX_G + offset] = color[PIXELFORMAT_INDEX_G];
- pointer[PIXELFORMAT_INDEX_B + offset] = color[PIXELFORMAT_INDEX_B];
- }
- }
-
- ///
- /// This is the implementation of the IFastBitmap for 32 bit images (no Alpha)
- ///
- public unsafe class Fast32RGBBitmap : FastBitmap
- {
- public Fast32RGBBitmap(Bitmap source, Rectangle area) : base(source, area)
- {
- }
-
- ///
- /// Retrieve the color at location x,y
- /// Before the first time this is called the Lock() should be called once!
- ///
- /// X coordinate
- /// Y Coordinate
- /// Color
- public override Color GetColorAt(int x, int y)
- {
- int offset = (x * 4) + (y * stride);
- return Color.FromArgb(255, pointer[PIXELFORMAT_INDEX_R + offset], pointer[PIXELFORMAT_INDEX_G + offset], pointer[PIXELFORMAT_INDEX_B + offset]);
- }
-
- ///
- /// Set the color at location x,y
- /// Before the first time this is called the Lock() should be called once!
- ///
- ///
- ///
- ///
- public override void SetColorAt(int x, int y, Color color)
- {
- int offset = (x * 4) + (y * stride);
- pointer[PIXELFORMAT_INDEX_R + offset] = color.R;
- pointer[PIXELFORMAT_INDEX_G + offset] = color.G;
- pointer[PIXELFORMAT_INDEX_B + offset] = color.B;
- }
-
- ///
- /// Get the color from the specified location into the specified array
- ///
- ///
- ///
- /// byte[4] as reference (a,r,g,b)
- public override void GetColorAt(int x, int y, byte[] color)
- {
- int offset = (x * 4) + (y * stride);
- color[COLOR_INDEX_R] = pointer[PIXELFORMAT_INDEX_R + offset];
- color[COLOR_INDEX_G] = pointer[PIXELFORMAT_INDEX_G + offset];
- color[COLOR_INDEX_B] = pointer[PIXELFORMAT_INDEX_B + offset];
- }
-
- ///
- /// Set the color at the specified location from the specified array
- ///
- ///
- ///
- /// byte[4] as reference (r,g,b)
- public override void SetColorAt(int x, int y, byte[] color)
- {
- int offset = (x * 4) + (y * stride);
- pointer[PIXELFORMAT_INDEX_R + offset] = color[COLOR_INDEX_R]; // R
- pointer[PIXELFORMAT_INDEX_G + offset] = color[COLOR_INDEX_G];
- pointer[PIXELFORMAT_INDEX_B + offset] = color[COLOR_INDEX_B];
- }
- }
-
- ///
- /// This is the implementation of the IFastBitmap for 32 bit images with Alpha
- ///
- public unsafe class Fast32ARGBBitmap : FastBitmap, IFastBitmapWithBlend
- {
- public override bool hasAlphaChannel
- {
- get
- {
- return true;
- }
- }
-
- public Color BackgroundBlendColor
- {
- get;
- set;
- }
-
- public Fast32ARGBBitmap(Bitmap source, Rectangle area) : base(source, area)
- {
- BackgroundBlendColor = Color.White;
- }
-
- ///
- /// Retrieve the color at location x,y
- ///
- /// X coordinate
- /// Y Coordinate
- /// Color
- public override Color GetColorAt(int x, int y)
- {
- int offset = (x * 4) + (y * stride);
- return Color.FromArgb(pointer[PIXELFORMAT_INDEX_A + offset], pointer[PIXELFORMAT_INDEX_R + offset], pointer[PIXELFORMAT_INDEX_G + offset], pointer[PIXELFORMAT_INDEX_B + offset]);
- }
-
- ///
- /// Set the color at location x,y
- /// Before the first time this is called the Lock() should be called once!
- ///
- ///
- ///
- ///
- public override void SetColorAt(int x, int y, Color color)
- {
- int offset = (x * 4) + (y * stride);
- pointer[PIXELFORMAT_INDEX_A + offset] = color.A;
- pointer[PIXELFORMAT_INDEX_R + offset] = color.R;
- pointer[PIXELFORMAT_INDEX_G + offset] = color.G;
- pointer[PIXELFORMAT_INDEX_B + offset] = color.B;
- }
-
- ///
- /// Get the color from the specified location into the specified array
- ///
- ///
- ///
- /// byte[4] as reference (r,g,b,a)
- public override void GetColorAt(int x, int y, byte[] color)
- {
- int offset = (x * 4) + (y * stride);
- color[COLOR_INDEX_R] = pointer[PIXELFORMAT_INDEX_R + offset];
- color[COLOR_INDEX_G] = pointer[PIXELFORMAT_INDEX_G + offset];
- color[COLOR_INDEX_B] = pointer[PIXELFORMAT_INDEX_B + offset];
- color[COLOR_INDEX_A] = pointer[PIXELFORMAT_INDEX_A + offset];
- }
-
- ///
- /// Set the color at the specified location from the specified array
- ///
- ///
- ///
- /// byte[4] as reference (r,g,b,a)
- public override void SetColorAt(int x, int y, byte[] color)
- {
- int offset = (x * 4) + (y * stride);
- pointer[PIXELFORMAT_INDEX_R + offset] = color[COLOR_INDEX_R]; // R
- pointer[PIXELFORMAT_INDEX_G + offset] = color[COLOR_INDEX_G];
- pointer[PIXELFORMAT_INDEX_B + offset] = color[COLOR_INDEX_B];
- pointer[PIXELFORMAT_INDEX_A + offset] = color[COLOR_INDEX_A];
- }
-
- ///
- /// Retrieve the color, without alpha (is blended), at location x,y
- /// Before the first time this is called the Lock() should be called once!
- ///
- /// X coordinate
- /// Y Coordinate
- /// Color
- public Color GetBlendedColorAt(int x, int y)
- {
- int offset = (x * 4) + (y * stride);
- int a = pointer[PIXELFORMAT_INDEX_A + offset];
- int red = pointer[PIXELFORMAT_INDEX_R + offset];
- int green = pointer[PIXELFORMAT_INDEX_G + offset];
- int blue = pointer[PIXELFORMAT_INDEX_B + offset];
-
- if (a < 255)
- {
- // As the request is to get without alpha, we blend.
- int rem = 255 - a;
- red = (red * a + BackgroundBlendColor.R * rem) / 255;
- green = (green * a + BackgroundBlendColor.G * rem) / 255;
- blue = (blue * a + BackgroundBlendColor.B * rem) / 255;
- }
- return Color.FromArgb(255, red, green, blue);
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/FilenameHelper.cs b/Greenshot.ImageEditor/Core/FilenameHelper.cs
deleted file mode 100644
index 028c224dd..000000000
--- a/Greenshot.ImageEditor/Core/FilenameHelper.cs
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using Greenshot.IniFile;
-using Greenshot.Plugin;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using System.Text.RegularExpressions;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Core
-{
- public static class FilenameHelper
- {
- // Specify the regular expression for the filename formatting:
- // Starting with ${
- // than the varname, which ends with a : or }
- // If a parameters needs to be supplied, than a ":" should follow the name... everything from the : until the } is considered to be part of the parameters.
- // The parameter format is a single alpha followed by the value belonging to the parameter, e.g. :
- // ${capturetime:d"yyyy-MM-dd HH_mm_ss"}
- private static readonly Regex VAR_REGEXP = new Regex(@"\${(?[^:}]+)[:]?(?[^}]*)}", RegexOptions.Compiled);
- private static readonly Regex CMD_VAR_REGEXP = new Regex(@"%(?[^%]+)%", RegexOptions.Compiled);
-
- private static readonly Regex SPLIT_REGEXP = new Regex(";(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", RegexOptions.Compiled);
- private const int MAX_TITLE_LENGTH = 80;
- private static readonly CoreConfiguration conf = IniConfig.GetIniSection();
- private const string UNSAFE_REPLACEMENT = "_";
-
- ///
- /// Remove invalid characters from the fully qualified filename
- ///
- /// string with the full path to a file
- /// string with the full path to a file, without invalid characters
- public static string MakeFQFilenameSafe(string fullPath)
- {
- string path = MakePathSafe(Path.GetDirectoryName(fullPath));
- string filename = MakeFilenameSafe(Path.GetFileName(fullPath));
- // Make the fullpath again and return
- return Path.Combine(path, filename);
- }
-
- ///
- /// Remove invalid characters from the filename
- ///
- /// string with the full path to a file
- /// string with the full path to a file, without invalid characters
- public static string MakeFilenameSafe(string filename)
- {
- // Make the filename save!
- if (filename != null)
- {
- foreach (char disallowed in Path.GetInvalidFileNameChars())
- {
- filename = filename.Replace(disallowed.ToString(), UNSAFE_REPLACEMENT);
- }
- }
- return filename;
- }
-
- ///
- /// Remove invalid characters from the path
- ///
- /// string with the full path to a file
- /// string with the full path to a file, without invalid characters
- public static string MakePathSafe(string path)
- {
- // Make the path save!
- if (path != null)
- {
- foreach (char disallowed in Path.GetInvalidPathChars())
- {
- path = path.Replace(disallowed.ToString(), UNSAFE_REPLACEMENT);
- }
- }
- return path;
- }
-
- public static string GetFilenameWithoutExtensionFromPattern(string pattern)
- {
- return GetFilenameWithoutExtensionFromPattern(pattern, null);
- }
-
- public static string GetFilenameWithoutExtensionFromPattern(string pattern, ICaptureDetails captureDetails)
- {
- return FillPattern(pattern, captureDetails, true);
- }
-
- public static string GetFilenameFromPattern(string pattern, OutputFormat imageFormat)
- {
- return GetFilenameFromPattern(pattern, imageFormat, null);
- }
-
- public static string GetFilenameFromPattern(string pattern, OutputFormat imageFormat, ICaptureDetails captureDetails)
- {
- return FillPattern(pattern, captureDetails, true) + "." + imageFormat.ToString().ToLower();
- }
-
- ///
- /// Return a filename for the current image format (png,jpg etc) with the default file pattern
- /// that is specified in the configuration
- ///
- /// A string with the format
- /// The filename which should be used to save the image
- public static string GetFilename(OutputFormat format, ICaptureDetails captureDetails)
- {
- string pattern = conf.OutputFileFilenamePattern;
- if (pattern == null || string.IsNullOrEmpty(pattern.Trim()))
- {
- pattern = "greenshot ${capturetime}";
- }
- return GetFilenameFromPattern(pattern, format, captureDetails);
- }
-
- ///
- /// This method will be called by the regexp.replace as a MatchEvaluator delegate!
- /// Will delegate this to the MatchVarEvaluatorInternal and catch any exceptions
- /// What are we matching?
- /// The detail, can be null
- /// Variables from the process
- /// Variables from the user
- /// Variables from the machine
- /// string with the match replacement
- private static string MatchVarEvaluator(Match match, ICaptureDetails captureDetails, IDictionary processVars, IDictionary userVars, IDictionary machineVars, bool filenameSafeMode)
- {
- try
- {
- return MatchVarEvaluatorInternal(match, captureDetails, processVars, userVars, machineVars, filenameSafeMode);
- }
- catch (Exception e)
- {
- LOG.Error("Error in MatchVarEvaluatorInternal", e);
- }
- return "";
- }
-
- ///
- /// This method will be called by the regexp.replace as a MatchEvaluator delegate!
- ///
- /// What are we matching?
- /// The detail, can be null
- ///
- private static string MatchVarEvaluatorInternal(Match match, ICaptureDetails captureDetails, IDictionary processVars, IDictionary userVars, IDictionary machineVars, bool filenameSafeMode)
- {
- // some defaults
- int padWidth = 0;
- int startIndex = 0;
- int endIndex = 0;
- char padChar = ' ';
- string dateFormat = "yyyy-MM-dd HH-mm-ss";
- IDictionary replacements = new Dictionary();
- string replaceValue = "";
- string variable = match.Groups["variable"].Value;
- string parameters = match.Groups["parameters"].Value;
-
- if (parameters != null && parameters.Length > 0)
- {
- string[] parms = SPLIT_REGEXP.Split(parameters);
- foreach (string parameter in parms)
- {
- switch (parameter.Substring(0, 1))
- {
- // Padding p[,pad-character]
- case "p":
- string[] padParams = parameter.Substring(1).Split(new[] { ',' });
- try
- {
- padWidth = int.Parse(padParams[0]);
- }
- catch
- {
- };
- if (padParams.Length > 1)
- {
- padChar = padParams[1][0];
- }
- break;
- // replace
- // r,
- case "r":
- string[] replaceParameters = parameter.Substring(1).Split(new[] { ',' });
- if (replaceParameters != null && replaceParameters.Length == 2)
- {
- replacements.Add(replaceParameters[0], replaceParameters[1]);
- }
- break;
- // Dateformat d
- // Format can be anything that is used in C# date formatting
- case "d":
- dateFormat = parameter.Substring(1);
- if (dateFormat.StartsWith("\""))
- {
- dateFormat = dateFormat.Substring(1);
- }
- if (dateFormat.EndsWith("\""))
- {
- dateFormat = dateFormat.Substring(0, dateFormat.Length - 1);
- }
- break;
- // Substring:
- // s[,length]
- case "s":
- string range = parameter.Substring(1);
- string[] rangelist = range.Split(new[] { ',' });
- if (rangelist.Length > 0)
- {
- try
- {
- startIndex = int.Parse(rangelist[0]);
- }
- catch
- {
- // Ignore
- }
- }
- if (rangelist.Length > 1)
- {
- try
- {
- endIndex = int.Parse(rangelist[1]);
- }
- catch
- {
- // Ignore
- }
- }
- break;
- }
- }
- }
- if (processVars != null && processVars.Contains(variable))
- {
- replaceValue = (string)processVars[variable];
- if (filenameSafeMode)
- {
- replaceValue = MakePathSafe(replaceValue);
- }
- }
- else if (userVars != null && userVars.Contains(variable))
- {
- replaceValue = (string)userVars[variable];
- if (filenameSafeMode)
- {
- replaceValue = MakePathSafe(replaceValue);
- }
- }
- else if (machineVars != null && machineVars.Contains(variable))
- {
- replaceValue = (string)machineVars[variable];
- if (filenameSafeMode)
- {
- replaceValue = MakePathSafe(replaceValue);
- }
- }
- else if (captureDetails != null && captureDetails.MetaData != null && captureDetails.MetaData.ContainsKey(variable))
- {
- replaceValue = captureDetails.MetaData[variable];
- if (filenameSafeMode)
- {
- replaceValue = MakePathSafe(replaceValue);
- }
- }
- else
- {
- // Handle other variables
- // Default use "now" for the capture take´n
- DateTime capturetime = DateTime.Now;
- // Use default application name for title
- string title = Application.ProductName;
-
- // Check if we have capture details
- if (captureDetails != null)
- {
- capturetime = captureDetails.DateTime;
- if (captureDetails.Title != null)
- {
- title = captureDetails.Title;
- if (title.Length > MAX_TITLE_LENGTH)
- {
- title = title.Substring(0, MAX_TITLE_LENGTH);
- }
- }
- }
- switch (variable)
- {
- case "domain":
- replaceValue = Environment.UserDomainName;
- break;
- case "user":
- replaceValue = Environment.UserName;
- break;
- case "hostname":
- replaceValue = Environment.MachineName;
- break;
- case "YYYY":
- if (padWidth == 0)
- {
- padWidth = -4;
- padChar = '0';
- }
- replaceValue = capturetime.Year.ToString();
- break;
- case "MM":
- replaceValue = capturetime.Month.ToString();
- if (padWidth == 0)
- {
- padWidth = -2;
- padChar = '0';
- }
- break;
- case "DD":
- replaceValue = capturetime.Day.ToString();
- if (padWidth == 0)
- {
- padWidth = -2;
- padChar = '0';
- }
- break;
- case "hh":
- if (padWidth == 0)
- {
- padWidth = -2;
- padChar = '0';
- }
- replaceValue = capturetime.Hour.ToString();
- break;
- case "mm":
- if (padWidth == 0)
- {
- padWidth = -2;
- padChar = '0';
- }
- replaceValue = capturetime.Minute.ToString();
- break;
- case "ss":
- if (padWidth == 0)
- {
- padWidth = -2;
- padChar = '0';
- }
- replaceValue = capturetime.Second.ToString();
- break;
- case "now":
- replaceValue = DateTime.Now.ToString(dateFormat);
- if (filenameSafeMode)
- {
- replaceValue = MakeFilenameSafe(replaceValue);
- }
- break;
- case "capturetime":
- replaceValue = capturetime.ToString(dateFormat);
- if (filenameSafeMode)
- {
- replaceValue = MakeFilenameSafe(replaceValue);
- }
- break;
- case "NUM":
- conf.OutputFileIncrementingNumber++;
- IniConfig.Save();
- replaceValue = conf.OutputFileIncrementingNumber.ToString();
- if (padWidth == 0)
- {
- padWidth = -6;
- padChar = '0';
- }
-
- break;
- case "title":
- replaceValue = title;
- if (filenameSafeMode)
- {
- replaceValue = MakeFilenameSafe(replaceValue);
- }
- break;
- case "MyPictures":
- replaceValue = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
- break;
- case "MyMusic":
- replaceValue = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);
- break;
- case "MyDocuments":
- replaceValue = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
- break;
- case "Personal":
- replaceValue = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
- break;
- case "Desktop":
- replaceValue = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
- break;
- case "ApplicationData":
- replaceValue = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
- break;
- case "LocalApplicationData":
- replaceValue = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
- break;
- }
- }
- // do padding
- if (padWidth > 0)
- {
- replaceValue = replaceValue.PadRight(padWidth, padChar);
- }
- else if (padWidth < 0)
- {
- replaceValue = replaceValue.PadLeft(-padWidth, padChar);
- }
-
- // do substring
- if (startIndex != 0 || endIndex != 0)
- {
- if (startIndex < 0)
- {
- startIndex = replaceValue.Length + startIndex;
- }
- if (endIndex < 0)
- {
- endIndex = replaceValue.Length + endIndex;
- }
- if (endIndex != 0)
- {
- try
- {
- replaceValue = replaceValue.Substring(startIndex, endIndex);
- }
- catch
- {
- // Ignore
- }
- }
- else
- {
- try
- {
- replaceValue = replaceValue.Substring(startIndex);
- }
- catch
- {
- // Ignore
- }
- }
- }
-
- // new for feature #697
- if (replacements.Count > 0)
- {
- foreach (string oldValue in replacements.Keys)
- {
- replaceValue = replaceValue.Replace(oldValue, replacements[oldValue]);
- }
- }
- return replaceValue;
- }
-
- ///
- /// "Simply" fill the pattern with environment variables
- ///
- /// String with pattern %var%
- /// true to make sure everything is filenamesafe
- /// Filled string
- public static string FillCmdVariables(string pattern, bool filenameSafeMode)
- {
- IDictionary processVars = null;
- IDictionary userVars = null;
- IDictionary machineVars = null;
- try
- {
- processVars = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process);
- }
- catch (Exception e)
- {
- LOG.Error("Error retrieving EnvironmentVariableTarget.Process", e);
- }
-
- try
- {
- userVars = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.User);
- }
- catch (Exception e)
- {
- LOG.Error("Error retrieving EnvironmentVariableTarget.User", e);
- }
-
- try
- {
- machineVars = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Machine);
- }
- catch (Exception e)
- {
- LOG.Error("Error retrieving EnvironmentVariableTarget.Machine", e);
- }
-
- return CMD_VAR_REGEXP.Replace(pattern,
- delegate (Match m)
- {
- return MatchVarEvaluator(m, null, processVars, userVars, machineVars, filenameSafeMode);
- }
- );
- }
-
- ///
- /// "Simply" fill the pattern with environment variables
- ///
- /// String with pattern ${var}
- /// true to make sure everything is filenamesafe
- /// Filled string
- public static string FillVariables(string pattern, bool filenameSafeMode)
- {
- IDictionary processVars = null;
- IDictionary userVars = null;
- IDictionary machineVars = null;
- try
- {
- processVars = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process);
- }
- catch (Exception e)
- {
- LOG.Error("Error retrieving EnvironmentVariableTarget.Process", e);
- }
-
- try
- {
- userVars = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.User);
- }
- catch (Exception e)
- {
- LOG.Error("Error retrieving EnvironmentVariableTarget.User", e);
- }
-
- try
- {
- machineVars = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Machine);
- }
- catch (Exception e)
- {
- LOG.Error("Error retrieving EnvironmentVariableTarget.Machine", e);
- }
-
- return VAR_REGEXP.Replace(pattern,
- delegate (Match m)
- {
- return MatchVarEvaluator(m, null, processVars, userVars, machineVars, filenameSafeMode);
- }
- );
- }
-
- ///
- /// Fill the pattern wit the supplied details
- ///
- /// Pattern
- /// CaptureDetails, can be null
- /// Should the result be made "filename" safe?
- /// Filled pattern
- public static string FillPattern(string pattern, ICaptureDetails captureDetails, bool filenameSafeMode)
- {
- IDictionary processVars = null;
- IDictionary userVars = null;
- IDictionary machineVars = null;
- try
- {
- processVars = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process);
- }
- catch (Exception e)
- {
- LOG.Error("Error retrieving EnvironmentVariableTarget.Process", e);
- }
-
- try
- {
- userVars = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.User);
- }
- catch (Exception e)
- {
- LOG.Error("Error retrieving EnvironmentVariableTarget.User", e);
- }
-
- try
- {
- machineVars = Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Machine);
- }
- catch (Exception e)
- {
- LOG.Error("Error retrieving EnvironmentVariableTarget.Machine", e);
- }
-
- try
- {
- return VAR_REGEXP.Replace(pattern,
- delegate (Match m)
- {
- return MatchVarEvaluator(m, captureDetails, processVars, userVars, machineVars, filenameSafeMode);
- }
- );
- }
- catch (Exception e)
- {
- // adding additional data for bug tracking
- if (captureDetails != null)
- {
- e.Data.Add("title", captureDetails.Title);
- }
- e.Data.Add("pattern", pattern);
- throw;
- }
- }
-
- ///
- /// Checks whether a directory name is valid in the current file system
- ///
- /// directory name (not path!)
- /// true if directory name is valid
- public static bool IsDirectoryNameValid(string directoryName)
- {
- var forbiddenChars = Path.GetInvalidPathChars();
- foreach (var forbiddenChar in forbiddenChars)
- {
- if (directoryName == null || directoryName.Contains(forbiddenChar.ToString()))
- {
- return false;
- }
- }
- return true;
- }
-
- ///
- /// Checks whether a filename is valid in the current file system
- ///
- /// name of the file
- /// true if filename is valid
- public static bool IsFilenameValid(string filename)
- {
- var forbiddenChars = Path.GetInvalidFileNameChars();
- foreach (var forbiddenChar in forbiddenChars)
- {
- if (filename == null || filename.Contains(forbiddenChar.ToString()))
- {
- return false;
- }
- }
- return true;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/GreenshotResources.cs b/Greenshot.ImageEditor/Core/GreenshotResources.cs
deleted file mode 100644
index c6918ecaf..000000000
--- a/Greenshot.ImageEditor/Core/GreenshotResources.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System.ComponentModel;
-using System.Drawing;
-
-namespace GreenshotPlugin.Core
-{
- ///
- /// Centralized storage of the icons & bitmaps
- ///
- public static class GreenshotResources
- {
- private static readonly ComponentResourceManager greenshotResources = new ComponentResourceManager(typeof(GreenshotResources));
-
- public static Image getImage(string imageName)
- {
- return (Image)greenshotResources.GetObject(imageName);
- }
-
- public static Icon getIcon(string imageName)
- {
- return (Icon)greenshotResources.GetObject(imageName);
- }
-
- public static Icon getGreenshotIcon()
- {
- return getIcon("Greenshot.Icon");
- }
-
- public static Image getGreenshotImage()
- {
- return getImage("Greenshot.Image");
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/GreenshotResources.resx b/Greenshot.ImageEditor/Core/GreenshotResources.resx
deleted file mode 100644
index 5613cbe7e..000000000
--- a/Greenshot.ImageEditor/Core/GreenshotResources.resx
+++ /dev/null
@@ -1,471 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
-
-
- 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
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPSkpKSisCAAAAAAAAAQAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFTg9JgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAgAAAgABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIA
- AAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAA
- AKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIA
- AAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAA
- AKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIA
- AAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAA
- AKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCKAAAACAAAABA
- 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
- YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAwBQTFRFgICA////
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAODgHVgAAAAlwSFlzAAAOvgAA
- Dr4B6kKxwAAAABZJREFUGFdjYAABRhAAs4hlkq4DZDgACywAM12jTsYAAAAASUVORK5CYII=
-
-
-
-
- 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
- mXizAAAAAElFTkSuQmCC
-
-
-
-
- iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAXJJREFUOE+lk0FL
- AkEYhlvwv3jzoiDoQdCbdEnYf6CrqCgoHgRRAk/9EQVLdEGyFiQNMS+dvHnoEkgglGAmCL7NO6RMIZvU
- wsMO3zzzzGk0ACf/+hjQNO1ccKlXKsYx0OUZeflXoFmtVsUS2P4CHboi0FQDrXK5jM12i/VmYwsduiLQ
- UgNmqVTCuzj8tlrZQoeuCJhqoFMsFvG6XmO2WNhCh64IdNRAt1Ao4EXc/jSf20KHrgh01YCVy+Uwnkzw
- vFzaQoeuCFhqoJfJZBCLxY6Crgj01EA/lUrB4/HA7XYfhHs78vk8A301MIzH4/B6vRiNHjAY3H+DM+7p
- ug6fz4dsNsvAUA2Mo9Eo/H4/LOsOTqdTYprXEs64x0AwGEQ6nWZgrAYeDcNAIBBAu30r/6Reb0t2MwbC
- 4TCSySQDj/uAeEyngqnL5fpoNG4QCoUktVpHspsxEIlEkEgk+AKnaoAP8kwwczgcF4fg3g+u9gEu/son
- bfJW/NwRDyIAAAAASUVORK5CYII=
-
-
-
-
- iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAUNJREFUOE+lk79L
- QlEcxW9/gqCrm6vg4uYoOAgOrqLk4ioP0r2Glhp0SSjoF1FE0BIUDU3RdIOGoKBVGlpapaHTObeuCPe6
- 9ITD5fs9n3Pue8JbAWBS/VSQRvPwKR/j3JgaZXVqPv5TzPOXLhYoZDEcQidVWyhw3qzfn3tBAWH7PRjg
- uV7HV5JAM6USyX50u86btlrOCwoOCR7Q+Oz1cFcu473dhmbppdFwu8dq1e3EBgU0zB6NXQJvzSaui0U8
- VCq4LZWwn8vhLJ+HPDFiowUEzITADsGrQgFHmYzTSTYL7eSJiRZs0timRoTGhC956wXDXtrJEyM2eAIt
- t34Be8NgTPLELCuQYe8Z9tK8ZBf+ieuEnxj20rzB26SYF7zCGsGEoVeW6NTMoJFiXlDAkFllqMOwTs2+
- IOYFBf/9oFJ9ibr0B4f94vVG3bWDAAAAAElFTkSuQmCC
-
-
-
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/ImageHelper.cs b/Greenshot.ImageEditor/Core/ImageHelper.cs
deleted file mode 100644
index 3c322bed3..000000000
--- a/Greenshot.ImageEditor/Core/ImageHelper.cs
+++ /dev/null
@@ -1,1672 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using Greenshot.Core;
-using GreenshotPlugin.UnmanagedHelpers;
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Drawing2D;
-using System.Drawing.Imaging;
-using System.IO;
-
-namespace GreenshotPlugin.Core
-{
- internal enum ExifOrientations : byte
- {
- Unknown = 0,
- TopLeft = 1,
- TopRight = 2,
- BottomRight = 3,
- BottomLeft = 4,
- LeftTop = 5,
- RightTop = 6,
- RightBottom = 7,
- LeftBottom = 8,
- }
-
- ///
- /// Description of ImageHelper.
- ///
- public static class ImageHelper
- {
- private const int EXIF_ORIENTATION_ID = 0x0112;
-
- ///
- /// Make sure the image is orientated correctly
- ///
- ///
- public static void Orientate(Image image)
- {
- /*if (!conf.ProcessEXIFOrientation)
- {
- return;
- }*/
- try
- {
- // Get the index of the orientation property.
- int orientationIndex = Array.IndexOf(image.PropertyIdList, EXIF_ORIENTATION_ID);
- // If there is no such property, return Unknown.
- if (orientationIndex < 0)
- {
- return;
- }
- PropertyItem item = image.GetPropertyItem(EXIF_ORIENTATION_ID);
-
- ExifOrientations orientation = (ExifOrientations)item.Value[0];
- // Orient the image.
- switch (orientation)
- {
- case ExifOrientations.Unknown:
- case ExifOrientations.TopLeft:
- break;
- case ExifOrientations.TopRight:
- image.RotateFlip(RotateFlipType.RotateNoneFlipX);
- break;
- case ExifOrientations.BottomRight:
- image.RotateFlip(RotateFlipType.Rotate180FlipNone);
- break;
- case ExifOrientations.BottomLeft:
- image.RotateFlip(RotateFlipType.RotateNoneFlipY);
- break;
- case ExifOrientations.LeftTop:
- image.RotateFlip(RotateFlipType.Rotate90FlipX);
- break;
- case ExifOrientations.RightTop:
- image.RotateFlip(RotateFlipType.Rotate90FlipNone);
- break;
- case ExifOrientations.RightBottom:
- image.RotateFlip(RotateFlipType.Rotate90FlipY);
- break;
- case ExifOrientations.LeftBottom:
- image.RotateFlip(RotateFlipType.Rotate270FlipNone);
- break;
- }
- // Set the orientation to be normal, as we rotated the image.
- item.Value[0] = (byte)ExifOrientations.TopLeft;
- image.SetPropertyItem(item);
- }
- catch (Exception orientEx)
- {
- LOG.Warn("Problem orientating the image: ", orientEx);
- }
- }
-
- ///
- /// Create a thumbnail from an image
- ///
- ///
- ///
- ///
- ///
- public static Image CreateThumbnail(Image image, int thumbWidth, int thumbHeight)
- {
- return CreateThumbnail(image, thumbWidth, thumbHeight, -1, -1);
- }
-
- ///
- /// Create a Thumbnail
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public static Image CreateThumbnail(Image image, int thumbWidth, int thumbHeight, int maxWidth, int maxHeight)
- {
- int srcWidth = image.Width;
- int srcHeight = image.Height;
- if (thumbHeight < 0)
- {
- thumbHeight = (int)(thumbWidth * (srcHeight / (float)srcWidth));
- }
- if (thumbWidth < 0)
- {
- thumbWidth = (int)(thumbHeight * (srcWidth / (float)srcHeight));
- }
- if (maxWidth > 0 && thumbWidth > maxWidth)
- {
- thumbWidth = Math.Min(thumbWidth, maxWidth);
- thumbHeight = (int)(thumbWidth * (srcHeight / (float)srcWidth));
- }
- if (maxHeight > 0 && thumbHeight > maxHeight)
- {
- thumbHeight = Math.Min(thumbHeight, maxHeight);
- thumbWidth = (int)(thumbHeight * (srcWidth / (float)srcHeight));
- }
-
- Bitmap bmp = new Bitmap(thumbWidth, thumbHeight);
- using (Graphics graphics = Graphics.FromImage(bmp))
- {
- graphics.SmoothingMode = SmoothingMode.HighQuality;
- graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
- graphics.CompositingQuality = CompositingQuality.HighQuality;
- graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
- Rectangle rectDestination = new Rectangle(0, 0, thumbWidth, thumbHeight);
- graphics.DrawImage(image, rectDestination, 0, 0, srcWidth, srcHeight, GraphicsUnit.Pixel);
- }
- return bmp;
- }
-
- ///
- /// Crops the image to the specified rectangle
- ///
- /// Image to crop
- /// Rectangle with bitmap coordinates, will be "intersected" to the bitmap
- public static bool Crop(ref Image image, ref Rectangle cropRectangle)
- {
- Image returnImage = null;
- if (image != null && image is Bitmap && ((image.Width * image.Height) > 0))
- {
- cropRectangle.Intersect(new Rectangle(0, 0, image.Width, image.Height));
- if (cropRectangle.Width != 0 || cropRectangle.Height != 0)
- {
- returnImage = CloneArea(image, cropRectangle, PixelFormat.DontCare);
- image.Dispose();
- image = returnImage;
- return true;
- }
- }
- LOG.Warn("Can't crop a null/zero size image!");
- return false;
- }
-
- ///
- /// Private helper method for the FindAutoCropRectangle
- ///
- ///
- ///
- ///
- /// Rectangle
- private static Rectangle FindAutoCropRectangle(IFastBitmap fastBitmap, Point colorPoint, int cropDifference)
- {
- Rectangle cropRectangle = Rectangle.Empty;
- Color referenceColor = fastBitmap.GetColorAt(colorPoint.X, colorPoint.Y);
- Point min = new Point(int.MaxValue, int.MaxValue);
- Point max = new Point(int.MinValue, int.MinValue);
-
- if (cropDifference > 0)
- {
- for (int y = 0; y < fastBitmap.Height; y++)
- {
- for (int x = 0; x < fastBitmap.Width; x++)
- {
- Color currentColor = fastBitmap.GetColorAt(x, y);
- int diffR = Math.Abs(currentColor.R - referenceColor.R);
- int diffG = Math.Abs(currentColor.G - referenceColor.G);
- int diffB = Math.Abs(currentColor.B - referenceColor.B);
- if (((diffR + diffG + diffB) / 3) <= cropDifference)
- {
- continue;
- }
- if (x < min.X) min.X = x;
- if (y < min.Y) min.Y = y;
- if (x > max.X) max.X = x;
- if (y > max.Y) max.Y = y;
- }
- }
- }
- else
- {
- for (int y = 0; y < fastBitmap.Height; y++)
- {
- for (int x = 0; x < fastBitmap.Width; x++)
- {
- Color currentColor = fastBitmap.GetColorAt(x, y);
- if (!referenceColor.Equals(currentColor))
- {
- continue;
- }
- if (x < min.X) min.X = x;
- if (y < min.Y) min.Y = y;
- if (x > max.X) max.X = x;
- if (y > max.Y) max.Y = y;
- }
- }
- }
-
- if (!(Point.Empty.Equals(min) && max.Equals(new Point(fastBitmap.Width - 1, fastBitmap.Height - 1))))
- {
- if (!(min.X == int.MaxValue || min.Y == int.MaxValue || max.X == int.MinValue || min.X == int.MinValue))
- {
- cropRectangle = new Rectangle(min.X, min.Y, max.X - min.X + 1, max.Y - min.Y + 1);
- }
- }
- return cropRectangle;
- }
-
- ///
- /// Get a rectangle for the image which crops the image of all colors equal to that on 0,0
- ///
- ///
- ///
- /// Rectangle
- public static Rectangle FindAutoCropRectangle(Image image, int cropDifference)
- {
- Rectangle cropRectangle = Rectangle.Empty;
- Rectangle currentRectangle;
- List checkPoints = new List();
- // Top Left
- checkPoints.Add(new Point(0, 0));
- // Bottom Left
- checkPoints.Add(new Point(0, image.Height - 1));
- // Top Right
- checkPoints.Add(new Point(image.Width - 1, 0));
- // Bottom Right
- checkPoints.Add(new Point(image.Width - 1, image.Height - 1));
- using (IFastBitmap fastBitmap = FastBitmap.Create((Bitmap)image))
- {
- // find biggest area
- foreach (Point checkPoint in checkPoints)
- {
- currentRectangle = FindAutoCropRectangle(fastBitmap, checkPoint, cropDifference);
- if (currentRectangle.Width * currentRectangle.Height > cropRectangle.Width * cropRectangle.Height)
- {
- cropRectangle = currentRectangle;
- }
- }
- }
- return cropRectangle;
- }
-
- ///
- /// Load an image from file
- ///
- ///
- ///
- public static Image LoadImage(string filename)
- {
- if (string.IsNullOrEmpty(filename))
- {
- return null;
- }
- if (!File.Exists(filename))
- {
- return null;
- }
- Image fileImage = null;
- LOG.InfoFormat("Loading image from file {0}", filename);
- // Fixed lock problem Bug #3431881
- using (Stream imageFileStream = File.OpenRead(filename))
- {
- // And fixed problem that the bitmap stream is disposed... by Cloning the image
- // This also ensures the bitmap is correctly created
-
- if (filename.EndsWith(".ico"))
- {
- // Icon logic, try to get the Vista icon, else the biggest possible
- try
- {
- using (Image tmpImage = ExtractVistaIcon(imageFileStream))
- {
- if (tmpImage != null)
- {
- fileImage = Clone(tmpImage);
- }
- }
- }
- catch (Exception vistaIconException)
- {
- LOG.Warn("Can't read icon from " + filename, vistaIconException);
- }
- if (fileImage == null)
- {
- try
- {
- // No vista icon, try normal icon
- imageFileStream.Position = 0;
- // We create a copy of the bitmap, so everything else can be disposed
- using (Icon tmpIcon = new Icon(imageFileStream, new Size(1024, 1024)))
- {
- using (Image tmpImage = tmpIcon.ToBitmap())
- {
- fileImage = Clone(tmpImage);
- }
- }
- }
- catch (Exception iconException)
- {
- LOG.Warn("Can't read icon from " + filename, iconException);
- }
- }
- }
- if (fileImage == null)
- {
- // We create a copy of the bitmap, so everything else can be disposed
- imageFileStream.Position = 0;
- using (Image tmpImage = Image.FromStream(imageFileStream, true, true))
- {
- LOG.DebugFormat("Loaded {0} with Size {1}x{2} and PixelFormat {3}", filename, tmpImage.Width, tmpImage.Height, tmpImage.PixelFormat);
- fileImage = Clone(tmpImage);
- }
- }
- }
- 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);
- }
- // Make sure the orientation is set correctly so Greenshot can process the image correctly
- Orientate(fileImage);
- return fileImage;
- }
-
- ///
- /// Based on: http://www.codeproject.com/KB/cs/IconExtractor.aspx
- /// And a hint from: http://www.codeproject.com/KB/cs/IconLib.aspx
- ///
- /// Stream with the icon information
- /// Bitmap with the Vista Icon (256x256)
- private static Bitmap ExtractVistaIcon(Stream iconStream)
- {
- const int SizeICONDIR = 6;
- const int SizeICONDIRENTRY = 16;
- Bitmap bmpPngExtracted = null;
- try
- {
- byte[] srcBuf = new byte[iconStream.Length];
- iconStream.Read(srcBuf, 0, (int)iconStream.Length);
- int iCount = BitConverter.ToInt16(srcBuf, 4);
- for (int iIndex = 0; iIndex < iCount; iIndex++)
- {
- int iWidth = srcBuf[SizeICONDIR + SizeICONDIRENTRY * iIndex];
- int iHeight = srcBuf[SizeICONDIR + SizeICONDIRENTRY * iIndex + 1];
- int iBitCount = BitConverter.ToInt16(srcBuf, SizeICONDIR + SizeICONDIRENTRY * iIndex + 6);
- if (iWidth == 0 && iHeight == 0)
- {
- int iImageSize = BitConverter.ToInt32(srcBuf, SizeICONDIR + SizeICONDIRENTRY * iIndex + 8);
- int iImageOffset = BitConverter.ToInt32(srcBuf, SizeICONDIR + SizeICONDIRENTRY * iIndex + 12);
- using (MemoryStream destStream = new MemoryStream())
- {
- destStream.Write(srcBuf, iImageOffset, iImageSize);
- destStream.Seek(0, SeekOrigin.Begin);
- bmpPngExtracted = new Bitmap(destStream); // This is PNG! :)
- }
- break;
- }
- }
- }
- catch
- {
- return null;
- }
- return bmpPngExtracted;
- }
-
- ///
- /// See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms648069%28v=vs.85%29.aspx
- ///
- /// The icon to
- /// The file (EXE or DLL) to get the icon from
- /// Index of the icon
- /// true if the large icon is wanted
- /// Icon
- public static Icon ExtractAssociatedIcon(string location, int index, bool takeLarge)
- {
- IntPtr large;
- IntPtr small;
- Shell32.ExtractIconEx(location, index, out large, out 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;
- }
-
- ///
- /// Get the number of icon in the file
- ///
- /// Location of the EXE or DLL
- ///
- public static int CountAssociatedIcons(string location)
- {
- IntPtr large;
- IntPtr small;
- return Shell32.ExtractIconEx(location, -1, out large, out small, 0);
- }
-
- ///
- /// Apply the effect to the bitmap
- ///
- /// Bitmap
- /// IEffect
- ///
- /// Bitmap
- public static Image ApplyEffect(Image sourceImage, IEffect effect, Matrix matrix)
- {
- List effects = new List();
- effects.Add(effect);
- return ApplyEffects(sourceImage, effects, matrix);
- }
-
- ///
- /// Apply the effects in the supplied order to the bitmap
- ///
- /// Bitmap
- /// List
- ///
- /// Bitmap
- public static Image ApplyEffects(Image sourceImage, List effects, Matrix matrix)
- {
- Image currentImage = sourceImage;
- bool disposeImage = false;
- foreach (IEffect effect in effects)
- {
- Image tmpImage = effect.Apply(currentImage, matrix);
- if (tmpImage != null)
- {
- if (disposeImage)
- {
- currentImage.Dispose();
- }
- currentImage = tmpImage;
- tmpImage = null;
- // Make sure the "new" image is disposed
- disposeImage = true;
- }
- }
- return currentImage;
- }
-
- ///
- /// Helper method for the tornedge
- ///
- /// Path to draw to
- /// Points for the lines to draw
- private static void DrawLines(GraphicsPath path, List points)
- {
- path.AddLine(points[0], points[1]);
- for (int i = 0; i < points.Count - 1; i++)
- {
- path.AddLine(points[i], points[i + 1]);
- }
- }
-
- ///
- /// Make the picture look like it's torn
- ///
- /// Bitmap to make torn edge off
- /// How large (height) is each tooth
- /// How wide is a horizontal tooth
- /// How wide is a vertical tooth
- /// bool[] with information on if the edge needs torn or not. Order is clockwise: 0=top,1=right,2=bottom,3=left
- /// Changed bitmap
- 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, sourceImage.VerticalResolution);
- using (GraphicsPath path = new GraphicsPath())
- {
- Random random = new Random();
- int horizontalRegions = (int)Math.Round((float)sourceImage.Width / horizontalToothRange);
- int verticalRegions = (int)Math.Round((float)sourceImage.Height / verticalToothRange);
-
- Point topLeft = new Point(0, 0);
- Point topRight = new Point(sourceImage.Width, 0);
- Point bottomLeft = new Point(0, sourceImage.Height);
- Point bottomRight = new Point(sourceImage.Width, sourceImage.Height);
-
- List points = new List();
-
- if (edges[0])
- {
- // calculate starting point only if the left edge is torn
- if (!edges[3])
- {
- points.Add(topLeft);
- }
- else
- {
- points.Add(new Point(random.Next(1, toothHeight), random.Next(1, toothHeight)));
- }
- for (int i = 1; i < horizontalRegions - 1; i++)
- {
- points.Add(new Point(i * horizontalToothRange, random.Next(1, toothHeight)));
- }
- points.Add(new Point(sourceImage.Width - random.Next(1, toothHeight), random.Next(1, toothHeight)));
- }
- else
- {
- // set start & endpoint to be the default "whole-line"
- points.Add(topLeft);
- points.Add(topRight);
- }
- // Right
- if (edges[1])
- {
- for (int i = 1; i < verticalRegions - 1; i++)
- {
- points.Add(new Point(sourceImage.Width - random.Next(1, toothHeight), i * verticalToothRange));
- }
- points.Add(new Point(sourceImage.Width - random.Next(1, toothHeight), sourceImage.Height - random.Next(1, toothHeight)));
- }
- else
- {
- // correct previous ending point
- points[points.Count - 1] = topRight;
- // set endpoint to be the default "whole-line"
- points.Add(bottomRight);
- }
- // Bottom
- if (edges[2])
- {
- for (int i = 1; i < horizontalRegions - 1; i++)
- {
- points.Add(new Point(sourceImage.Width - i * horizontalToothRange, sourceImage.Height - random.Next(1, toothHeight)));
- }
- points.Add(new Point(random.Next(1, toothHeight), sourceImage.Height - random.Next(1, toothHeight)));
- }
- else
- {
- // correct previous ending point
- points[points.Count - 1] = bottomRight;
- // set endpoint to be the default "whole-line"
- points.Add(bottomLeft);
- }
- // Left
- if (edges[3])
- {
- // One fewer as the end point is the starting point
- for (int i = 1; i < verticalRegions - 1; i++)
- {
- points.Add(new Point(random.Next(1, toothHeight), points[points.Count - 1].Y - verticalToothRange));
- }
- }
- else
- {
- // correct previous ending point
- points[points.Count - 1] = bottomLeft;
- // set endpoint to be the default "whole-line"
- points.Add(topLeft);
- }
- // End point always is the starting point
- points[points.Count - 1] = points[0];
-
- DrawLines(path, points);
-
- path.CloseFigure();
-
- // Draw the created figure with the original image by using a TextureBrush so we have anti-aliasing
- using (Graphics graphics = Graphics.FromImage(returnImage))
- {
- graphics.SmoothingMode = SmoothingMode.HighQuality;
- graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
- graphics.CompositingQuality = CompositingQuality.HighQuality;
- graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
- using (Brush brush = new TextureBrush(sourceImage))
- {
- // Important note: If the target wouldn't be at 0,0 we need to translate-transform!!
- graphics.FillPath(brush, path);
- }
- }
- }
- return returnImage;
- }
-
- ///
- /// Apply BoxBlur to the destinationBitmap
- ///
- /// Bitmap to blur
- /// Must be ODD!
- public static void ApplyBoxBlur(Bitmap destinationBitmap, int range)
- {
- // We only need one fastbitmap as we use it as source and target (the reading is done for one line H/V, writing after "parsing" one line H/V)
- using (IFastBitmap fastBitmap = FastBitmap.Create(destinationBitmap))
- {
- ApplyBoxBlur(fastBitmap, range);
- }
- }
-
- ///
- /// Apply BoxBlur to the fastBitmap
- ///
- /// IFastBitmap to blur
- /// Must be ODD!
- public static void ApplyBoxBlur(IFastBitmap fastBitmap, int range)
- {
- // Range must be odd!
- if ((range & 1) == 0)
- {
- range++;
- }
- if (range <= 1)
- {
- return;
- }
- // Box blurs are frequently used to approximate a Gaussian blur.
- // By the central limit theorem, if applied 3 times on the same image, a box blur approximates the Gaussian kernel to within about 3%, yielding the same result as a quadratic convolution kernel.
- // This might be true, but the GDI+ BlurEffect doesn't look the same, a 2x blur is more simular and we only make 2x Box-Blur.
- // (Might also be a mistake in our blur, but for now it looks great)
- if (fastBitmap.hasAlphaChannel)
- {
- BoxBlurHorizontalAlpha(fastBitmap, range);
- BoxBlurVerticalAlpha(fastBitmap, range);
- BoxBlurHorizontalAlpha(fastBitmap, range);
- BoxBlurVerticalAlpha(fastBitmap, range);
- }
- else
- {
- BoxBlurHorizontal(fastBitmap, range);
- BoxBlurVertical(fastBitmap, range);
- BoxBlurHorizontal(fastBitmap, range);
- BoxBlurVertical(fastBitmap, range);
- }
- }
-
- ///
- /// BoxBlurHorizontal is a private helper method for the BoxBlur
- ///
- /// Target BitmapBuffer
- /// Range must be odd!
- private static void BoxBlurHorizontal(IFastBitmap targetFastBitmap, int range)
- {
- if (targetFastBitmap.hasAlphaChannel)
- {
- throw new NotSupportedException("BoxBlurHorizontal should NOT be called for bitmaps with alpha channel");
- }
- int halfRange = range / 2;
- Color[] newColors = new Color[targetFastBitmap.Width];
- byte[] tmpColor = new byte[3];
- for (int y = targetFastBitmap.Top; y < targetFastBitmap.Bottom; y++)
- {
- int hits = 0;
- int r = 0;
- int g = 0;
- int b = 0;
- for (int x = targetFastBitmap.Left - halfRange; x < targetFastBitmap.Right; x++)
- {
- int oldPixel = x - halfRange - 1;
- if (oldPixel >= targetFastBitmap.Left)
- {
- targetFastBitmap.GetColorAt(oldPixel, y, tmpColor);
- r -= tmpColor[FastBitmap.COLOR_INDEX_R];
- g -= tmpColor[FastBitmap.COLOR_INDEX_G];
- b -= tmpColor[FastBitmap.COLOR_INDEX_B];
- hits--;
- }
-
- int newPixel = x + halfRange;
- if (newPixel < targetFastBitmap.Right)
- {
- targetFastBitmap.GetColorAt(newPixel, y, tmpColor);
- r += tmpColor[FastBitmap.COLOR_INDEX_R];
- g += tmpColor[FastBitmap.COLOR_INDEX_G];
- b += tmpColor[FastBitmap.COLOR_INDEX_B];
- hits++;
- }
-
- if (x >= targetFastBitmap.Left)
- {
- newColors[x - targetFastBitmap.Left] = Color.FromArgb(255, (byte)(r / hits), (byte)(g / hits), (byte)(b / hits));
- }
- }
- for (int x = targetFastBitmap.Left; x < targetFastBitmap.Right; x++)
- {
- targetFastBitmap.SetColorAt(x, y, newColors[x - targetFastBitmap.Left]);
- }
- }
- }
-
- ///
- /// BoxBlurHorizontal is a private helper method for the BoxBlur, only for IFastBitmaps with alpha channel
- ///
- /// Target BitmapBuffer
- /// Range must be odd!
- private static void BoxBlurHorizontalAlpha(IFastBitmap targetFastBitmap, int range)
- {
- if (!targetFastBitmap.hasAlphaChannel)
- {
- throw new NotSupportedException("BoxBlurHorizontalAlpha should be called for bitmaps with alpha channel");
- }
- int halfRange = range / 2;
- Color[] newColors = new Color[targetFastBitmap.Width];
- byte[] tmpColor = new byte[4];
- for (int y = targetFastBitmap.Top; y < targetFastBitmap.Bottom; y++)
- {
- int hits = 0;
- int a = 0;
- int r = 0;
- int g = 0;
- int b = 0;
- for (int x = targetFastBitmap.Left - halfRange; x < targetFastBitmap.Right; x++)
- {
- int oldPixel = x - halfRange - 1;
- if (oldPixel >= targetFastBitmap.Left)
- {
- targetFastBitmap.GetColorAt(oldPixel, y, tmpColor);
- a -= tmpColor[FastBitmap.COLOR_INDEX_A];
- r -= tmpColor[FastBitmap.COLOR_INDEX_R];
- g -= tmpColor[FastBitmap.COLOR_INDEX_G];
- b -= tmpColor[FastBitmap.COLOR_INDEX_B];
- hits--;
- }
-
- int newPixel = x + halfRange;
- if (newPixel < targetFastBitmap.Right)
- {
- targetFastBitmap.GetColorAt(newPixel, y, tmpColor);
- a += tmpColor[FastBitmap.COLOR_INDEX_A];
- r += tmpColor[FastBitmap.COLOR_INDEX_R];
- g += tmpColor[FastBitmap.COLOR_INDEX_G];
- b += tmpColor[FastBitmap.COLOR_INDEX_B];
- hits++;
- }
-
- if (x >= targetFastBitmap.Left)
- {
- newColors[x - targetFastBitmap.Left] = Color.FromArgb((byte)(a / hits), (byte)(r / hits), (byte)(g / hits), (byte)(b / hits));
- }
- }
- for (int x = targetFastBitmap.Left; x < targetFastBitmap.Right; x++)
- {
- targetFastBitmap.SetColorAt(x, y, newColors[x - targetFastBitmap.Left]);
- }
- }
- }
-
- ///
- /// BoxBlurVertical is a private helper method for the BoxBlur
- ///
- /// BitmapBuffer which previously was created with BoxBlurHorizontal
- /// Range must be odd!
- private static void BoxBlurVertical(IFastBitmap targetFastBitmap, int range)
- {
- if (targetFastBitmap.hasAlphaChannel)
- {
- throw new NotSupportedException("BoxBlurVertical should NOT be called for bitmaps with alpha channel");
- }
- int halfRange = range / 2;
- Color[] newColors = new Color[targetFastBitmap.Height];
- byte[] tmpColor = new byte[4];
- for (int x = targetFastBitmap.Left; x < targetFastBitmap.Right; x++)
- {
- int hits = 0;
- int r = 0;
- int g = 0;
- int b = 0;
- for (int y = targetFastBitmap.Top - halfRange; y < targetFastBitmap.Bottom; y++)
- {
- int oldPixel = y - halfRange - 1;
- if (oldPixel >= targetFastBitmap.Top)
- {
- targetFastBitmap.GetColorAt(x, oldPixel, tmpColor);
- r -= tmpColor[FastBitmap.COLOR_INDEX_R];
- g -= tmpColor[FastBitmap.COLOR_INDEX_G];
- b -= tmpColor[FastBitmap.COLOR_INDEX_B];
- hits--;
- }
-
- int newPixel = y + halfRange;
- if (newPixel < targetFastBitmap.Bottom)
- {
- targetFastBitmap.GetColorAt(x, newPixel, tmpColor);
- r += tmpColor[FastBitmap.COLOR_INDEX_R];
- g += tmpColor[FastBitmap.COLOR_INDEX_G];
- b += tmpColor[FastBitmap.COLOR_INDEX_B];
- hits++;
- }
-
- if (y >= targetFastBitmap.Top)
- {
- newColors[y - targetFastBitmap.Top] = Color.FromArgb(255, (byte)(r / hits), (byte)(g / hits), (byte)(b / hits));
- }
- }
-
- for (int y = targetFastBitmap.Top; y < targetFastBitmap.Bottom; y++)
- {
- targetFastBitmap.SetColorAt(x, y, newColors[y - targetFastBitmap.Top]);
- }
- }
- }
-
- ///
- /// BoxBlurVertical is a private helper method for the BoxBlur
- ///
- /// BitmapBuffer which previously was created with BoxBlurHorizontal
- /// Range must be odd!
- private static void BoxBlurVerticalAlpha(IFastBitmap targetFastBitmap, int range)
- {
- if (!targetFastBitmap.hasAlphaChannel)
- {
- throw new NotSupportedException("BoxBlurVerticalAlpha should be called for bitmaps with alpha channel");
- }
-
- int halfRange = range / 2;
- Color[] newColors = new Color[targetFastBitmap.Height];
- byte[] tmpColor = new byte[4];
- for (int x = targetFastBitmap.Left; x < targetFastBitmap.Right; x++)
- {
- int hits = 0;
- int a = 0;
- int r = 0;
- int g = 0;
- int b = 0;
- for (int y = targetFastBitmap.Top - halfRange; y < targetFastBitmap.Bottom; y++)
- {
- int oldPixel = y - halfRange - 1;
- if (oldPixel >= targetFastBitmap.Top)
- {
- targetFastBitmap.GetColorAt(x, oldPixel, tmpColor);
- a -= tmpColor[FastBitmap.COLOR_INDEX_A];
- r -= tmpColor[FastBitmap.COLOR_INDEX_R];
- g -= tmpColor[FastBitmap.COLOR_INDEX_G];
- b -= tmpColor[FastBitmap.COLOR_INDEX_B];
- hits--;
- }
-
- int newPixel = y + halfRange;
- if (newPixel < targetFastBitmap.Bottom)
- {
- //int colorg = pixels[index + newPixelOffset];
- targetFastBitmap.GetColorAt(x, newPixel, tmpColor);
- a += tmpColor[FastBitmap.COLOR_INDEX_A];
- r += tmpColor[FastBitmap.COLOR_INDEX_R];
- g += tmpColor[FastBitmap.COLOR_INDEX_G];
- b += tmpColor[FastBitmap.COLOR_INDEX_B];
- hits++;
- }
-
- if (y >= targetFastBitmap.Top)
- {
- newColors[y - targetFastBitmap.Top] = Color.FromArgb((byte)(a / hits), (byte)(r / hits), (byte)(g / hits), (byte)(b / hits));
- }
- }
-
- for (int y = targetFastBitmap.Top; y < targetFastBitmap.Bottom; y++)
- {
- targetFastBitmap.SetColorAt(x, y, newColors[y - targetFastBitmap.Top]);
- }
- }
- }
-
- ///
- /// This method fixes the problem that we can't apply a filter outside the target bitmap,
- /// therefor the filtered-bitmap will be shifted if we try to draw it outside the target bitmap.
- /// It will also account for the Invert flag.
- ///
- ///
- ///
- ///
- ///
- public static Rectangle CreateIntersectRectangle(Size applySize, Rectangle rect, bool invert)
- {
- Rectangle myRect;
- if (invert)
- {
- myRect = new Rectangle(0, 0, applySize.Width, applySize.Height);
- }
- else
- {
- Rectangle applyRect = new Rectangle(0, 0, applySize.Width, applySize.Height);
- myRect = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
- myRect.Intersect(applyRect);
- }
- return myRect;
- }
-
- ///
- /// Create a new bitmap where the sourceBitmap has a shadow
- ///
- /// Bitmap to make a shadow on
- /// How dark is the shadow
- /// Size of the shadow
- /// What pixel format must the returning bitmap have
- ///
- /// The transform matrix which describes how the elements need to be transformed to stay at the same location
- /// Bitmap with the shadow, is bigger than the sourceBitmap!!
- public static Bitmap CreateShadow(Image sourceBitmap, float darkness, int shadowSize, Point shadowOffset, Matrix matrix, PixelFormat targetPixelformat)
- {
- Point offset = shadowOffset;
- offset.X += shadowSize - 1;
- offset.Y += shadowSize - 1;
- matrix.Translate(offset.X, offset.Y, MatrixOrder.Append);
- // Create a new "clean" image
- Bitmap returnImage = CreateEmpty(sourceBitmap.Width + (shadowSize * 2), sourceBitmap.Height + (shadowSize * 2), targetPixelformat, Color.Empty, sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution);
- // Make sure the shadow is odd, there is no reason for an even blur!
- if ((shadowSize & 1) == 0)
- {
- shadowSize++;
- }
- bool useGDIBlur = GDIplus.IsBlurPossible(shadowSize);
- // Create "mask" for the shadow
- ColorMatrix maskMatrix = new ColorMatrix();
- maskMatrix.Matrix00 = 0;
- maskMatrix.Matrix11 = 0;
- maskMatrix.Matrix22 = 0;
- if (useGDIBlur)
- {
- maskMatrix.Matrix33 = darkness + 0.1f;
- }
- else
- {
- maskMatrix.Matrix33 = darkness;
- }
- Rectangle shadowRectangle = new Rectangle(new Point(shadowSize, shadowSize), sourceBitmap.Size);
- ApplyColorMatrix((Bitmap)sourceBitmap, Rectangle.Empty, returnImage, shadowRectangle, maskMatrix);
-
- // blur "shadow", apply to whole new image
- if (useGDIBlur)
- {
- // Use GDI Blur
- Rectangle newImageRectangle = new Rectangle(0, 0, returnImage.Width, returnImage.Height);
- GDIplus.ApplyBlur(returnImage, newImageRectangle, shadowSize + 1, false);
- }
- else
- {
- // try normal software blur
- //returnImage = CreateBlur(returnImage, newImageRectangle, true, shadowSize, 1d, false, newImageRectangle);
- ApplyBoxBlur(returnImage, shadowSize);
- }
-
- // Draw the original image over the shadow
- using (Graphics graphics = Graphics.FromImage(returnImage))
- {
- // Make sure we draw with the best quality!
- graphics.SmoothingMode = SmoothingMode.HighQuality;
- graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
- graphics.CompositingQuality = CompositingQuality.HighQuality;
- graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
- // draw original with a TextureBrush so we have nice antialiasing!
- using (Brush textureBrush = new TextureBrush(sourceBitmap, WrapMode.Clamp))
- {
- // We need to do a translate-transform otherwise the image is wrapped
- graphics.TranslateTransform(offset.X, offset.Y);
- graphics.FillRectangle(textureBrush, 0, 0, sourceBitmap.Width, sourceBitmap.Height);
- }
- }
- return returnImage;
- }
-
- ///
- /// Return negative of Bitmap
- ///
- /// Bitmap to create a negative off
- /// Negative bitmap
- public static Bitmap CreateNegative(Image sourceImage)
- {
- Bitmap clone = (Bitmap)Clone(sourceImage);
- ColorMatrix invertMatrix = new ColorMatrix(new[] {
- new float[] {-1, 0, 0, 0, 0},
- new float[] {0, -1, 0, 0, 0},
- new float[] {0, 0, -1, 0, 0},
- new float[] {0, 0, 0, 1, 0},
- new float[] {1, 1, 1, 1, 1}
- });
- ApplyColorMatrix(clone, invertMatrix);
- return clone;
- }
-
- ///
- /// Apply a color matrix to the image
- ///
- /// Image to apply matrix to
- /// ColorMatrix to apply
- public static void ApplyColorMatrix(Bitmap source, ColorMatrix colorMatrix)
- {
- ApplyColorMatrix(source, Rectangle.Empty, source, Rectangle.Empty, colorMatrix);
- }
-
- ///
- /// Apply a color matrix by copying from the source to the destination
- ///
- /// Image to copy from
- /// Rectangle to copy from
- /// Rectangle to copy to
- /// Image to copy to
- /// ColorMatrix to apply
- public static void ApplyColorMatrix(Bitmap source, Rectangle sourceRect, Bitmap dest, Rectangle destRect, ColorMatrix colorMatrix)
- {
- using (ImageAttributes imageAttributes = new ImageAttributes())
- {
- imageAttributes.ClearColorMatrix();
- imageAttributes.SetColorMatrix(colorMatrix);
- ApplyImageAttributes(source, sourceRect, dest, destRect, imageAttributes);
- }
- }
-
- ///
- /// Apply image attributes to the image
- ///
- /// Image to apply matrix to
- /// ImageAttributes to apply
- public static void ApplyColorMatrix(Bitmap source, ImageAttributes imageAttributes)
- {
- ApplyImageAttributes(source, Rectangle.Empty, source, Rectangle.Empty, imageAttributes);
- }
-
- ///
- /// Apply a color matrix by copying from the source to the destination
- ///
- /// Image to copy from
- /// Rectangle to copy from
- /// Rectangle to copy to
- /// Image to copy to
- /// ImageAttributes to apply
- public static void ApplyImageAttributes(Bitmap source, Rectangle sourceRect, Bitmap dest, Rectangle destRect, ImageAttributes imageAttributes)
- {
- if (sourceRect == Rectangle.Empty)
- {
- sourceRect = new Rectangle(0, 0, source.Width, source.Height);
- }
- if (dest == null)
- {
- dest = source;
- }
- if (destRect == Rectangle.Empty)
- {
- destRect = new Rectangle(0, 0, dest.Width, dest.Height);
- }
- using (Graphics graphics = Graphics.FromImage(dest))
- {
- // Make sure we draw with the best quality!
- graphics.SmoothingMode = SmoothingMode.HighQuality;
- graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
- graphics.CompositingQuality = CompositingQuality.HighQuality;
- graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
- graphics.CompositingMode = CompositingMode.SourceCopy;
-
- graphics.DrawImage(source, destRect, sourceRect.X, sourceRect.Y, sourceRect.Width, sourceRect.Height, GraphicsUnit.Pixel, imageAttributes);
- }
- }
-
- ///
- /// Returns a b/w of Bitmap
- ///
- /// Bitmap to create a b/w of
- /// Threshold for monochrome filter (0 - 255), lower value means less black
- /// b/w bitmap
- public static Bitmap CreateMonochrome(Image sourceImage, byte threshold)
- {
- using (IFastBitmap fastBitmap = FastBitmap.CreateCloneOf(sourceImage, sourceImage.PixelFormat))
- {
- for (int y = 0; y < fastBitmap.Height; y++)
- {
- for (int x = 0; x < fastBitmap.Width; x++)
- {
- Color color = fastBitmap.GetColorAt(x, y);
- int colorBrightness = ((color.R + color.G + color.B) / 3 > threshold) ? 255 : 0;
- Color monoColor = Color.FromArgb(color.A, colorBrightness, colorBrightness, colorBrightness);
- fastBitmap.SetColorAt(x, y, monoColor);
- }
- }
- return fastBitmap.UnlockAndReturnBitmap();
- }
- }
-
- ///
- /// Create a new bitmap where the sourceBitmap has a Simple border around it
- ///
- /// Bitmap to make a border on
- /// Size of the border
- /// Color of the border
- /// What pixel format must the returning bitmap have
- /// The transform matrix which describes how the elements need to be transformed to stay at the same location
- /// Bitmap with the shadow, is bigger than the sourceBitmap!!
- public static Image CreateBorder(Image sourceImage, int borderSize, Color borderColor, PixelFormat targetPixelformat, Matrix matrix)
- {
- // "return" the shifted offset, so the caller can e.g. move elements
- Point offset = new Point(borderSize, borderSize);
- matrix.Translate(offset.X, offset.Y, MatrixOrder.Append);
-
- // Create a new "clean" image
- Bitmap newImage = CreateEmpty(sourceImage.Width + (borderSize * 2), sourceImage.Height + (borderSize * 2), targetPixelformat, Color.Empty, sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
- using (Graphics graphics = Graphics.FromImage(newImage))
- {
- // Make sure we draw with the best quality!
- graphics.SmoothingMode = SmoothingMode.HighQuality;
- graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
- graphics.CompositingQuality = CompositingQuality.HighQuality;
- graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
- using (GraphicsPath path = new GraphicsPath())
- {
- path.AddRectangle(new Rectangle(borderSize >> 1, borderSize >> 1, newImage.Width - (borderSize), newImage.Height - (borderSize)));
- using (Pen pen = new Pen(borderColor, borderSize))
- {
- pen.LineJoin = LineJoin.Round;
- pen.StartCap = LineCap.Round;
- pen.EndCap = LineCap.Round;
- graphics.DrawPath(pen, path);
- }
- }
- // draw original with a TextureBrush so we have nice antialiasing!
- using (Brush textureBrush = new TextureBrush(sourceImage, WrapMode.Clamp))
- {
- // We need to do a translate-tranform otherwise the image is wrapped
- graphics.TranslateTransform(offset.X, offset.Y);
- graphics.FillRectangle(textureBrush, 0, 0, sourceImage.Width, sourceImage.Height);
- }
- }
- return newImage;
- }
-
- ///
- /// Create ImageAttributes to modify
- ///
- ///
- ///
- ///
- /// ImageAttributes
- public static ImageAttributes CreateAdjustAttributes(float brightness, float contrast, float gamma)
- {
- float adjustedBrightness = brightness - 1.0f;
- ColorMatrix applyColorMatrix = new ColorMatrix(
- new[] {
- new[] {contrast, 0, 0, 0, 0}, // scale red
- new[] {0, contrast, 0, 0, 0}, // scale green
- new[] {0, 0, contrast, 0, 0}, // scale blue
- new[] {0, 0, 0, 1.0f, 0}, // don't scale alpha
- new[] {adjustedBrightness, adjustedBrightness, adjustedBrightness, 0, 1}
- });
-
- //create some image attributes
- ImageAttributes attributes = new ImageAttributes();
- attributes.ClearColorMatrix();
- attributes.SetColorMatrix(applyColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
- attributes.SetGamma(gamma, ColorAdjustType.Bitmap);
- return attributes;
- }
-
- ///
- /// Adjust the brightness, contract or gamma of an image.
- /// Use the value "1.0f" for no changes.
- ///
- /// Original bitmap
- ///
- ///
- ///
- /// Bitmap with grayscale
- public static Image Adjust(Image sourceImage, float brightness, float contrast, float gamma)
- {
- //create a blank bitmap the same size as original
- // If using 8bpp than the following exception comes: A Graphics object cannot be created from an image that has an indexed pixel format.
- Bitmap newBitmap = CreateEmpty(sourceImage.Width, sourceImage.Height, PixelFormat.Format24bppRgb, Color.Empty, sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
- using (ImageAttributes adjustAttributes = CreateAdjustAttributes(brightness, contrast, gamma))
- {
- ApplyImageAttributes((Bitmap)sourceImage, Rectangle.Empty, newBitmap, Rectangle.Empty, adjustAttributes);
- }
- return newBitmap;
- }
-
- ///
- /// Create a new bitmap where the sourceBitmap is in grayscale
- ///
- /// Original bitmap
- /// Bitmap with grayscale
- public static Image CreateGrayscale(Image sourceImage)
- {
- Bitmap clone = (Bitmap)Clone(sourceImage);
- ColorMatrix grayscaleMatrix = new ColorMatrix(new[] {
- new[] {.3f, .3f, .3f, 0, 0},
- new[] {.59f, .59f, .59f, 0, 0},
- new[] {.11f, .11f, .11f, 0, 0},
- new float[] {0, 0, 0, 1, 0},
- new float[] {0, 0, 0, 0, 1}
- });
- ApplyColorMatrix(clone, grayscaleMatrix);
- return clone;
- }
-
- ///
- /// Checks if the supplied Bitmap has a PixelFormat we support
- ///
- /// bitmap to check
- /// bool if we support it
- public static bool SupportsPixelFormat(Image image)
- {
- return SupportsPixelFormat(image.PixelFormat);
- }
-
- ///
- /// Checks if we support the pixel format
- ///
- /// PixelFormat to check
- /// bool if we support it
- public static bool SupportsPixelFormat(PixelFormat pixelformat)
- {
- return (pixelformat.Equals(PixelFormat.Format32bppArgb) ||
- pixelformat.Equals(PixelFormat.Format32bppPArgb) ||
- pixelformat.Equals(PixelFormat.Format32bppRgb) ||
- pixelformat.Equals(PixelFormat.Format24bppRgb));
- }
-
- ///
- /// Wrapper for just cloning which calls the CloneArea
- ///
- /// Image to clone
- /// Bitmap with clone image data
- public static Image Clone(Image sourceImage)
- {
- if (sourceImage is Metafile)
- {
- return (Image)sourceImage.Clone();
- }
- return CloneArea(sourceImage, Rectangle.Empty, PixelFormat.DontCare);
- }
-
- ///
- /// Wrapper for just cloning & TargetFormat which calls the CloneArea
- ///
- /// Image to clone
- /// Target Format, use PixelFormat.DontCare if you want the original (or a default if the source PixelFormat is not supported)
- /// Bitmap with clone image data
- public static Bitmap Clone(Image sourceBitmap, PixelFormat targetFormat)
- {
- return CloneArea(sourceBitmap, Rectangle.Empty, targetFormat);
- }
-
- ///
- /// Clone an image, taking some rules into account:
- /// 1) When sourceRect is the whole bitmap there is a GDI+ bug in Clone
- /// Clone will than return the same PixelFormat as the source
- /// a quick workaround is using new Bitmap which uses a default of Format32bppArgb
- /// 2) When going from a transparent to a non transparent bitmap, we draw the background white!
- ///
- /// Source bitmap to clone
- /// Rectangle to copy from the source, use Rectangle.Empty for all
- /// Target Format, use PixelFormat.DontCare if you want the original (or a default if the source PixelFormat is not supported)
- ///
- public static Bitmap CloneArea(Image sourceImage, Rectangle sourceRect, PixelFormat targetFormat)
- {
- Bitmap newImage = null;
- Rectangle bitmapRect = new Rectangle(0, 0, sourceImage.Width, sourceImage.Height);
-
- // Make sure the source is not Rectangle.Empty
- if (Rectangle.Empty.Equals(sourceRect))
- {
- sourceRect = new Rectangle(0, 0, sourceImage.Width, sourceImage.Height);
- }
- else
- {
- sourceRect.Intersect(bitmapRect);
- }
-
- // If no pixelformat is supplied
- if (PixelFormat.DontCare == targetFormat || PixelFormat.Undefined == targetFormat)
- {
- if (SupportsPixelFormat(sourceImage.PixelFormat))
- {
- targetFormat = sourceImage.PixelFormat;
- }
- else if (Image.IsAlphaPixelFormat(sourceImage.PixelFormat))
- {
- targetFormat = PixelFormat.Format32bppArgb;
- }
- else
- {
- targetFormat = PixelFormat.Format24bppRgb;
- }
- }
-
- // check the target format
- if (!SupportsPixelFormat(targetFormat))
- {
- if (Image.IsAlphaPixelFormat(targetFormat))
- {
- targetFormat = PixelFormat.Format32bppArgb;
- }
- else
- {
- targetFormat = PixelFormat.Format24bppRgb;
- }
- }
-
- bool destinationIsTransparent = Image.IsAlphaPixelFormat(targetFormat);
- bool sourceIsTransparent = Image.IsAlphaPixelFormat(sourceImage.PixelFormat);
- bool fromTransparentToNon = !destinationIsTransparent && sourceIsTransparent;
- bool isBitmap = sourceImage is Bitmap;
- bool isAreaEqual = sourceRect.Equals(bitmapRect);
- if (isAreaEqual || fromTransparentToNon || !isBitmap)
- {
- // Rule 1: if the areas are equal, always copy ourselves
- newImage = new Bitmap(bitmapRect.Width, bitmapRect.Height, targetFormat);
- // Make sure both images have the same resolution
- newImage.SetResolution(sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
-
- using (Graphics graphics = Graphics.FromImage(newImage))
- {
- if (fromTransparentToNon)
- {
- // Rule 2: Make sure the background color is white
- graphics.Clear(Color.White);
- }
- // decide fastest copy method
- if (isAreaEqual)
- {
- graphics.DrawImageUnscaled(sourceImage, 0, 0);
- }
- else
- {
- graphics.DrawImage(sourceImage, 0, 0, sourceRect, GraphicsUnit.Pixel);
- }
- }
- }
- else
- {
- // Let GDI+ decide how to convert, need to test what is quicker...
- newImage = (sourceImage as Bitmap).Clone(sourceRect, targetFormat);
- // Make sure both images have the same resolution
- newImage.SetResolution(sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
- }
- // Clone property items (EXIF information etc)
- if (sourceImage.PropertyItems != null)
- {
- foreach (var propertyItem in sourceImage.PropertyItems)
- {
- try
- {
- newImage.SetPropertyItem(propertyItem);
- }
- catch (Exception ex)
- {
- LOG.Warn("Problem cloning a propertyItem.", ex);
- }
- }
- }
- return newImage;
- }
-
- ///
- /// Rotate the bitmap
- ///
- ///
- ///
- ///
- public static Image RotateFlip(Image sourceImage, RotateFlipType rotateFlipType)
- {
- Image returnImage = Clone(sourceImage);
- returnImage.RotateFlip(rotateFlipType);
- return returnImage;
- }
-
- ///
- /// A generic way to create an empty image
- ///
- /// the source bitmap as the specifications for the new bitmap
- /// The color to fill with, or Color.Empty to take the default depending on the pixel format
- ///
- public static Bitmap CreateEmptyLike(Image sourceImage, Color backgroundColor)
- {
- PixelFormat pixelFormat = sourceImage.PixelFormat;
- if (backgroundColor.A < 255)
- {
- pixelFormat = PixelFormat.Format32bppArgb;
- }
- return CreateEmpty(sourceImage.Width, sourceImage.Height, pixelFormat, backgroundColor, sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
- }
-
- ///
- /// A generic way to create an empty image
- ///
- ///
- ///
- ///
- /// The color to fill with, or Color.Empty to take the default depending on the pixel format
- ///
- ///
- /// Bitmap
- public static Bitmap CreateEmpty(int width, int height, PixelFormat format, Color backgroundColor, float horizontalResolution, float verticalResolution)
- {
- // Create a new "clean" image
- Bitmap newImage = new Bitmap(width, height, format);
- newImage.SetResolution(horizontalResolution, verticalResolution);
- if (format != PixelFormat.Format8bppIndexed)
- {
- using (Graphics graphics = Graphics.FromImage(newImage))
- {
- // Make sure the background color is what we want (transparent or white, depending on the pixel format)
- if (!Color.Empty.Equals(backgroundColor))
- {
- graphics.Clear(backgroundColor);
- }
- else if (Image.IsAlphaPixelFormat(format))
- {
- graphics.Clear(Color.Transparent);
- }
- else
- {
- graphics.Clear(Color.White);
- }
- }
- }
- return newImage;
- }
-
- ///
- /// Get a scaled version of the sourceBitmap
- ///
- ///
- /// 1-99 to make smaller, use 101 and more to make the picture bigger
- ///
- public static Bitmap ScaleByPercent(Bitmap sourceBitmap, int percent)
- {
- float nPercent = ((float)percent / 100);
-
- int sourceWidth = sourceBitmap.Width;
- int sourceHeight = sourceBitmap.Height;
- int destWidth = (int)(sourceWidth * nPercent);
- int destHeight = (int)(sourceHeight * nPercent);
-
- Bitmap scaledBitmap = CreateEmpty(destWidth, destHeight, sourceBitmap.PixelFormat, Color.Empty, sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution);
- using (Graphics graphics = Graphics.FromImage(scaledBitmap))
- {
- graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
- graphics.DrawImage(sourceBitmap, new Rectangle(0, 0, destWidth, destHeight), new Rectangle(0, 0, sourceWidth, sourceHeight), GraphicsUnit.Pixel);
- }
- return scaledBitmap;
- }
-
- ///
- /// Resize canvas with pixel to the left, right, top and bottom
- ///
- ///
- /// The color to fill with, or Color.Empty to take the default depending on the pixel format
- ///
- ///
- ///
- ///
- ///
- /// a new bitmap with the source copied on it
- public static Image ResizeCanvas(Image sourceImage, Color backgroundColor, int left, int right, int top, int bottom, Matrix matrix)
- {
- matrix.Translate(left, top, MatrixOrder.Append);
- Bitmap newBitmap = CreateEmpty(sourceImage.Width + left + right, sourceImage.Height + top + bottom, sourceImage.PixelFormat, backgroundColor, sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
- using (Graphics graphics = Graphics.FromImage(newBitmap))
- {
- graphics.DrawImageUnscaled(sourceImage, left, top);
- }
- return newBitmap;
- }
-
- ///
- /// Wrapper for the more complex Resize, this resize could be used for e.g. Thumbnails
- ///
- ///
- /// true to maintain the aspect ratio
- ///
- ///
- ///
- ///
- public static Image ResizeImage(Image sourceImage, bool maintainAspectRatio, int newWidth, int newHeight, Matrix matrix)
- {
- return ResizeImage(sourceImage, maintainAspectRatio, false, Color.Empty, newWidth, newHeight, matrix);
- }
-
- ///
- /// Count how many times the supplied color exists
- ///
- /// Image to count the pixels of
- /// Color to count
- /// true if Alpha needs to be checked
- /// int with the number of pixels which have colorToCount
- public static int CountColor(Image sourceImage, Color colorToCount, bool includeAlpha)
- {
- int colors = 0;
- int toCount = colorToCount.ToArgb();
- if (!includeAlpha)
- {
- toCount = toCount & 0xffffff;
- }
- using (IFastBitmap bb = FastBitmap.Create((Bitmap)sourceImage))
- {
- for (int y = 0; y < bb.Height; y++)
- {
- for (int x = 0; x < bb.Width; x++)
- {
- int bitmapcolor = bb.GetColorAt(x, y).ToArgb();
- if (!includeAlpha)
- {
- bitmapcolor = bitmapcolor & 0xffffff;
- }
- if (bitmapcolor == toCount)
- {
- colors++;
- }
- }
- }
- return colors;
- }
- }
-
- ///
- /// Scale the bitmap, keeping aspect ratio, but the canvas will always have the specified size.
- ///
- /// Image to scale
- /// true to maintain the aspect ratio
- ///
- /// The color to fill with, or Color.Empty to take the default depending on the pixel format
- /// new width
- /// new height
- ///
- /// a new bitmap with the specified size, the source-Image scaled to fit with aspect ratio locked
- public static Image ResizeImage(Image sourceImage, bool maintainAspectRatio, bool canvasUseNewSize, Color backgroundColor, int newWidth, int newHeight, Matrix matrix)
- {
- int destX = 0;
- int destY = 0;
-
- float nPercentW = 0;
- float nPercentH = 0;
-
- nPercentW = (newWidth / (float)sourceImage.Width);
- nPercentH = (newHeight / (float)sourceImage.Height);
- if (maintainAspectRatio)
- {
- if (nPercentW == 1)
- {
- nPercentW = nPercentH;
- if (canvasUseNewSize)
- {
- destX = Math.Max(0, Convert.ToInt32((newWidth - (sourceImage.Width * nPercentW)) / 2));
- }
- }
- else if (nPercentH == 1)
- {
- nPercentH = nPercentW;
- if (canvasUseNewSize)
- {
- destY = Math.Max(0, Convert.ToInt32((newHeight - (sourceImage.Height * nPercentH)) / 2));
- }
- }
- else if (nPercentH != 0 && nPercentH < nPercentW)
- {
- nPercentW = nPercentH;
- if (canvasUseNewSize)
- {
- destX = Math.Max(0, Convert.ToInt32((newWidth - (sourceImage.Width * nPercentW)) / 2));
- }
- }
- else
- {
- nPercentH = nPercentW;
- if (canvasUseNewSize)
- {
- destY = Math.Max(0, Convert.ToInt32((newHeight - (sourceImage.Height * nPercentH)) / 2));
- }
- }
- }
-
- int destWidth = (int)(sourceImage.Width * nPercentW);
- int destHeight = (int)(sourceImage.Height * nPercentH);
- if (newWidth == 0)
- {
- newWidth = destWidth;
- }
- if (newHeight == 0)
- {
- newHeight = destHeight;
- }
- Image newImage = null;
- if (maintainAspectRatio && canvasUseNewSize)
- {
- newImage = CreateEmpty(newWidth, newHeight, sourceImage.PixelFormat, backgroundColor, sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
- if (matrix != null)
- {
- matrix.Scale((float)newWidth / sourceImage.Width, (float)newHeight / sourceImage.Height, MatrixOrder.Append);
- }
- }
- else
- {
- newImage = CreateEmpty(destWidth, destHeight, sourceImage.PixelFormat, backgroundColor, sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
- if (matrix != null)
- {
- matrix.Scale((float)destWidth / sourceImage.Width, (float)destHeight / sourceImage.Height, MatrixOrder.Append);
- }
- }
-
- using (Graphics graphics = Graphics.FromImage(newImage))
- {
- graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
- using (ImageAttributes wrapMode = new ImageAttributes())
- {
- wrapMode.SetWrapMode(WrapMode.TileFlipXY);
- graphics.DrawImage(sourceImage, new Rectangle(destX, destY, destWidth, destHeight), 0, 0, sourceImage.Width, sourceImage.Height, GraphicsUnit.Pixel, wrapMode);
- }
- }
- return newImage;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/ImageOutput.cs b/Greenshot.ImageEditor/Core/ImageOutput.cs
deleted file mode 100644
index cda7a4bcb..000000000
--- a/Greenshot.ImageEditor/Core/ImageOutput.cs
+++ /dev/null
@@ -1,728 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using Greenshot.IniFile;
-using Greenshot.Plugin;
-using GreenshotPlugin.Controls;
-using System;
-using System.Diagnostics;
-using System.Drawing;
-using System.Drawing.Drawing2D;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Windows.Forms;
-using Encoder = System.Drawing.Imaging.Encoder;
-
-namespace GreenshotPlugin.Core
-{
- ///
- /// Description of ImageOutput.
- ///
- public static class ImageOutput
- {
- private static readonly CoreConfiguration conf = IniConfig.GetIniSection();
- private static readonly int PROPERTY_TAG_SOFTWARE_USED = 0x0131;
- private static readonly Cache tmpFileCache = new Cache(10 * 60 * 60, RemoveExpiredTmpFile);
-
- ///
- /// Creates a PropertyItem (Metadata) to store with the image.
- /// For the possible ID's see: http://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!
- ///
- /// ID
- /// Text
- ///
- private static PropertyItem CreatePropertyItem(int id, string text)
- {
- PropertyItem propertyItem = null;
- try
- {
- ConstructorInfo ci = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, new Type[] { }, null);
- propertyItem = (PropertyItem)ci.Invoke(null);
- // Make sure it's of type string
- propertyItem.Type = 2;
- // Set the ID
- propertyItem.Id = id;
- // Set the text
- byte[] byteString = Encoding.ASCII.GetBytes(text + " ");
- // Set Zero byte for String end.
- byteString[byteString.Length - 1] = 0;
- propertyItem.Value = byteString;
- propertyItem.Len = text.Length + 1;
- }
- catch (Exception e)
- {
- LOG.WarnFormat("Error creating a PropertyItem: {0}", e.Message);
- }
- return propertyItem;
- }
-
- #region save
-
- ///
- /// Saves ISurface to stream with specified output settings
- ///
- /// ISurface to save
- /// Stream to save to
- /// SurfaceOutputSettings
- public static void SaveToStream(ISurface surface, Stream stream, SurfaceOutputSettings outputSettings)
- {
- Image imageToSave;
- bool disposeImage = CreateImageFromSurface(surface, outputSettings, out imageToSave);
- SaveToStream(imageToSave, surface, stream, outputSettings);
- // cleanup if needed
- if (disposeImage && imageToSave != null)
- {
- imageToSave.Dispose();
- }
- }
-
- ///
- /// Saves image to stream with specified quality
- /// To prevent problems with GDI version of before Windows 7:
- /// the stream is checked if it's seekable and if needed a MemoryStream as "cache" is used.
- ///
- /// image to save
- /// surface for the elements, needed if the greenshot format is used
- /// Stream to save to
- /// SurfaceOutputSettings
- public static void SaveToStream(Image imageToSave, ISurface surface, Stream stream, SurfaceOutputSettings outputSettings)
- {
- ImageFormat imageFormat;
- bool useMemoryStream = false;
- MemoryStream memoryStream = null;
- if (outputSettings.Format == OutputFormat.greenshot && surface == null)
- {
- throw new ArgumentException("Surface needs to be se when using OutputFormat.Greenshot");
- }
-
- try
- {
- switch (outputSettings.Format)
- {
- case OutputFormat.bmp:
- imageFormat = ImageFormat.Bmp;
- break;
- case OutputFormat.gif:
- imageFormat = ImageFormat.Gif;
- break;
- case OutputFormat.jpg:
- imageFormat = ImageFormat.Jpeg;
- break;
- case OutputFormat.tiff:
- imageFormat = ImageFormat.Tiff;
- break;
- default:
- // Problem with non-seekable streams most likely doesn't happen with Windows 7 (OS Version 6.1 and later)
- // http://stackoverflow.com/questions/8349260/generic-gdi-error-on-one-machine-but-not-the-other
- if (!stream.CanSeek)
- {
- int majorVersion = Environment.OSVersion.Version.Major;
- int minorVersion = Environment.OSVersion.Version.Minor;
- if (majorVersion < 6 || (majorVersion == 6 && minorVersion == 0))
- {
- useMemoryStream = true;
- LOG.Warn("Using memorystream prevent an issue with saving to a non seekable stream.");
- }
- }
- imageFormat = ImageFormat.Png;
- break;
- }
- 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 a issue which happens with Windows before "7".
- // The save is made to the targetStream, this is directed to either the MemoryStream or the original
- Stream targetStream = stream;
- if (useMemoryStream)
- {
- memoryStream = new MemoryStream();
- targetStream = memoryStream;
- }
-
- if (Equals(imageFormat, ImageFormat.Jpeg))
- {
- bool foundEncoder = false;
- foreach (ImageCodecInfo imageCodec in ImageCodecInfo.GetImageEncoders())
- {
- if (imageCodec.FormatID == imageFormat.Guid)
- {
- EncoderParameters parameters = new EncoderParameters(1);
- parameters.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();
- nonAlphaImage = null;
- }
- 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
- {
- 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(conf.OptimizePNGCommand))
- {
- processed = ProcessPNGImageExternally(imageToSave, targetStream);
- }
- if (!processed)
- {
- imageToSave.Save(targetStream, imageFormat);
- }
- if (needsDispose)
- {
- imageToSave.Dispose();
- imageToSave = null;
- }
- }
-
- // If we used a memory stream, we need to stream the memory stream to the original stream.
- if (useMemoryStream)
- {
- memoryStream.WriteTo(stream);
- }
-
- // Output the surface elements, size and marker to the stream
- if (outputSettings.Format == OutputFormat.greenshot)
- {
- 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(String.Format("Greenshot{0:00}.{1:00}", v.Major, v.Minor));
- writer.Write(marker);
- tmpStream.WriteTo(stream);
- }
- }
- }
- }
- finally
- {
- if (memoryStream != null)
- {
- memoryStream.Dispose();
- }
- }
- }
-
- ///
- /// Write the passed Image to a tmp-file and call an external process, than read the file back and write it to the targetStream
- ///
- /// Image to pass to the external process
- /// stream to write the processed image to
- ///
- private static bool ProcessPNGImageExternally(Image imageToProcess, Stream targetStream)
- {
- if (string.IsNullOrEmpty(conf.OptimizePNGCommand))
- {
- return false;
- }
- if (!File.Exists(conf.OptimizePNGCommand))
- {
- LOG.WarnFormat("Can't find 'OptimizePNGCommand' {0}", conf.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}", conf.OptimizePNGCommand);
- }
-
- ProcessStartInfo processStartInfo = new ProcessStartInfo(conf.OptimizePNGCommand);
- processStartInfo.Arguments = string.Format(conf.OptimizePNGCommandArguments, tmpFileName);
- processStartInfo.CreateNoWindow = true;
- processStartInfo.RedirectStandardOutput = true;
- processStartInfo.RedirectStandardError = true;
- processStartInfo.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;
- }
-
- ///
- /// Create an image from a surface with the settings from the output settings applied
- ///
- ///
- ///
- ///
- /// true if the image must be disposed
- public static bool CreateImageFromSurface(ISurface surface, SurfaceOutputSettings outputSettings, out Image imageToSave)
- {
- bool disposeImage = false;
-
- if (outputSettings.Format == OutputFormat.greenshot || outputSettings.SaveBackgroundOnly)
- {
- // We save the image of the surface, this should not be disposed
- imageToSave = surface.Image;
- }
- else
- {
- // We create the export image of the surface to save
- imageToSave = surface.GetImageForExport();
- disposeImage = true;
- }
-
- // The following block of modifications should be skipped when saving the greenshot format, no effects or otherwise!
- if (outputSettings.Format == OutputFormat.greenshot)
- {
- return disposeImage;
- }
- Image tmpImage;
- if (outputSettings.Effects != null && outputSettings.Effects.Count > 0)
- {
- // apply effects, if there are any
- using (Matrix matrix = new Matrix())
- {
- tmpImage = ImageHelper.ApplyEffects(imageToSave, outputSettings.Effects, matrix);
- }
- if (tmpImage != null)
- {
- if (disposeImage)
- {
- imageToSave.Dispose();
- }
- imageToSave = tmpImage;
- disposeImage = true;
- }
- }
-
- // check for color reduction, forced or automatically, only when the DisableReduceColors is false
- if (outputSettings.DisableReduceColors || (!conf.OutputFileAutoReduceColors && !outputSettings.ReduceColors))
- {
- return disposeImage;
- }
- bool isAlpha = Image.IsAlphaPixelFormat(imageToSave.PixelFormat);
- if (outputSettings.ReduceColors || (!isAlpha && conf.OutputFileAutoReduceColors))
- {
- using (var quantizer = new WuQuantizer((Bitmap)imageToSave))
- {
- int colorCount = quantizer.GetColorCount();
- LOG.InfoFormat("Image with format {0} has {1} colors", imageToSave.PixelFormat, colorCount);
- if (!outputSettings.ReduceColors && colorCount >= 256)
- {
- return disposeImage;
- }
- try
- {
- LOG.Info("Reducing colors on bitmap to 256.");
- tmpImage = quantizer.GetQuantizedImage(conf.OutputFileReduceColorsTo);
- if (disposeImage)
- {
- imageToSave.Dispose();
- }
- imageToSave = tmpImage;
- // Make sure the "new" image is disposed
- disposeImage = true;
- }
- catch (Exception e)
- {
- LOG.Warn("Error occurred while Quantizing the image, ignoring and using original. Error: ", e);
- }
- }
- }
- else if (isAlpha && !outputSettings.ReduceColors)
- {
- LOG.Info("Skipping 'optional' color reduction as the image has alpha");
- }
- return disposeImage;
- }
-
- ///
- /// Add the greenshot property!
- ///
- ///
- private static void AddTag(Image imageToSave)
- {
- // Create meta-data
- PropertyItem softwareUsedPropertyItem = CreatePropertyItem(PROPERTY_TAG_SOFTWARE_USED, "Greenshot");
- if (softwareUsedPropertyItem != null)
- {
- try
- {
- imageToSave.SetPropertyItem(softwareUsedPropertyItem);
- }
- catch (Exception)
- {
- LOG.WarnFormat("Couldn't set property {0}", softwareUsedPropertyItem.Id);
- }
- }
- }
-
- ///
- /// Load a Greenshot surface
- ///
- ///
- ///
- ///
- public static ISurface LoadGreenshotSurface(string fullPath, ISurface returnSurface)
- {
- if (string.IsNullOrEmpty(fullPath))
- {
- return null;
- }
- Image fileImage;
- LOG.InfoFormat("Loading image from file {0}", fullPath);
- // Fixed lock problem Bug #3431881
- using (Stream surfaceFileStream = File.OpenRead(fullPath))
- {
- // And 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 {0} with Size {1}x{2} and PixelFormat {3}", fullPath, 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);
- string greenshotMarker;
- using (StreamReader streamReader = new StreamReader(surfaceFileStream))
- {
- greenshotMarker = streamReader.ReadToEnd();
- if (!greenshotMarker.StartsWith("Greenshot"))
- {
- throw new ArgumentException(string.Format("{0} is not a Greenshot file!", fullPath));
- }
- 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 file {0}: {1}x{2}-{3} Resolution {4}x{5}", fullPath, fileImage.Width, fileImage.Height, fileImage.PixelFormat, fileImage.HorizontalResolution, fileImage.VerticalResolution);
- }
- return returnSurface;
- }
-
- ///
- /// Saves image to specific path with specified quality
- ///
- public static void Save(ISurface surface, string fullPath, bool allowOverwrite, SurfaceOutputSettings outputSettings, bool copyPathToClipboard)
- {
- fullPath = FilenameHelper.MakeFQFilenameSafe(fullPath);
- string path = Path.GetDirectoryName(fullPath);
-
- // check whether path exists - if not create it
- if (path != null)
- {
- DirectoryInfo di = new DirectoryInfo(path);
- if (!di.Exists)
- {
- Directory.CreateDirectory(di.FullName);
- }
- }
-
- if (!allowOverwrite && File.Exists(fullPath))
- {
- ArgumentException throwingException = new ArgumentException("File '" + fullPath + "' already exists.");
- throwingException.Data.Add("fullPath", fullPath);
- throw throwingException;
- }
- LOG.DebugFormat("Saving surface to {0}", fullPath);
- // Create the stream and call SaveToStream
- using (FileStream stream = new FileStream(fullPath, FileMode.Create, FileAccess.Write))
- {
- SaveToStream(surface, stream, outputSettings);
- }
-
- if (copyPathToClipboard)
- {
- ClipboardHelper.SetClipboardData(fullPath);
- }
- }
-
- ///
- /// Get the OutputFormat for a filename
- ///
- /// filename (can be a complete path)
- /// OutputFormat
- public static OutputFormat FormatForFilename(string fullPath)
- {
- // Fix for bug 2912959
- string extension = fullPath.Substring(fullPath.LastIndexOf(".") + 1);
- OutputFormat format = OutputFormat.png;
- try
- {
- format = (OutputFormat)Enum.Parse(typeof(OutputFormat), extension.ToLower());
- }
- catch (ArgumentException ae)
- {
- LOG.Warn("Couldn't parse extension: " + extension, ae);
- }
- return format;
- }
-
- #endregion save
-
- #region save-as
-
- ///
- /// Save with showing a dialog
- ///
- ///
- ///
- /// Path to filename
- public static string SaveWithDialog(ISurface surface, ICaptureDetails captureDetails)
- {
- string returnValue = null;
- using (SaveImageFileDialog saveImageFileDialog = new SaveImageFileDialog(captureDetails))
- {
- DialogResult dialogResult = saveImageFileDialog.ShowDialog();
- if (dialogResult.Equals(DialogResult.OK))
- {
- try
- {
- string fileNameWithExtension = saveImageFileDialog.FileNameWithExtension;
- SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(FormatForFilename(fileNameWithExtension));
- if (conf.OutputFilePromptQuality)
- {
- QualityDialog qualityDialog = new QualityDialog(outputSettings);
- qualityDialog.ShowDialog();
- }
- // For now we always overwrite, should be changed
- Save(surface, fileNameWithExtension, true, outputSettings, conf.OutputFileCopyPathToClipboard);
- returnValue = fileNameWithExtension;
- IniConfig.Save();
- }
- catch (ExternalException)
- {
- MessageBox.Show(string.Format("Cannot save file to {0}.\r\nPlease check write accessibility of the selected storage location.",
- saveImageFileDialog.FileName).Replace(@"\\", @"\"), "Error");
- }
- }
- }
- return returnValue;
- }
-
- #endregion save-as
-
- ///
- /// Create a tmpfile which has the name like in the configured pattern.
- /// Used e.g. by the email export
- ///
- ///
- ///
- ///
- /// Path to image file
- public static string SaveNamedTmpFile(ISurface surface, ICaptureDetails captureDetails, SurfaceOutputSettings outputSettings)
- {
- string pattern = conf.OutputFileFilenamePattern;
- if (pattern == null || string.IsNullOrEmpty(pattern.Trim()))
- {
- pattern = "greenshot ${capturetime}";
- }
- string filename = FilenameHelper.GetFilenameFromPattern(pattern, outputSettings.Format, captureDetails);
- // Prevent problems with "other characters", which causes a problem in e.g. Outlook 2007 or break our HTML
- filename = Regex.Replace(filename, @"[^\d\w\.]", "_");
- // Remove multiple "_"
- filename = Regex.Replace(filename, @"_+", "_");
- string tmpFile = Path.Combine(Path.GetTempPath(), filename);
-
- LOG.Debug("Creating TMP File: " + tmpFile);
-
- // Catching any exception to prevent that the user can't write in the directory.
- // This is done for e.g. bugs #2974608, #2963943, #2816163, #2795317, #2789218
- try
- {
- Save(surface, tmpFile, true, outputSettings, false);
- tmpFileCache.Add(tmpFile, tmpFile);
- }
- catch (Exception e)
- {
- // Show the problem
- MessageBox.Show(e.Message, "Error");
- // when save failed we present a SaveWithDialog
- tmpFile = SaveWithDialog(surface, captureDetails);
- }
- return tmpFile;
- }
-
- ///
- /// Remove a tmpfile which was created by SaveNamedTmpFile
- /// Used e.g. by the email export
- ///
- ///
- /// true if it worked
- public static bool DeleteNamedTmpFile(string tmpfile)
- {
- LOG.Debug("Deleting TMP File: " + tmpfile);
- try
- {
- if (File.Exists(tmpfile))
- {
- File.Delete(tmpfile);
- tmpFileCache.Remove(tmpfile);
- }
- return true;
- }
- catch (Exception ex)
- {
- LOG.Warn("Error deleting tmp file: ", ex);
- }
- return false;
- }
-
- ///
- /// Helper method to create a temp image file
- ///
- ///
- ///
- ///
- ///
- public static string SaveToTmpFile(ISurface surface, SurfaceOutputSettings outputSettings, string destinationPath)
- {
- string tmpFile = Path.GetRandomFileName() + "." + outputSettings.Format.ToString();
- // Prevent problems with "other characters", which could cause problems
- tmpFile = Regex.Replace(tmpFile, @"[^\d\w\.]", "");
- if (destinationPath == null)
- {
- destinationPath = Path.GetTempPath();
- }
- string tmpPath = Path.Combine(destinationPath, tmpFile);
- LOG.Debug("Creating TMP File : " + tmpPath);
-
- try
- {
- Save(surface, tmpPath, true, outputSettings, false);
- tmpFileCache.Add(tmpPath, tmpPath);
- }
- catch (Exception)
- {
- return null;
- }
- return tmpPath;
- }
-
- ///
- /// Cleanup all created tmpfiles
- ///
- public static void RemoveTmpFiles()
- {
- foreach (string tmpFile in tmpFileCache.Elements)
- {
- if (File.Exists(tmpFile))
- {
- LOG.DebugFormat("Removing old temp file {0}", tmpFile);
- File.Delete(tmpFile);
- }
- tmpFileCache.Remove(tmpFile);
- }
- }
-
- ///
- /// Cleanup handler for expired tempfiles
- ///
- ///
- ///
- private static void RemoveExpiredTmpFile(string filekey, object filename)
- {
- string path = filename as string;
- if (path != null && File.Exists(path))
- {
- LOG.DebugFormat("Removing expired file {0}", path);
- File.Delete(path);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/NetworkHelper.cs b/Greenshot.ImageEditor/Core/NetworkHelper.cs
deleted file mode 100644
index eb5e6c641..000000000
--- a/Greenshot.ImageEditor/Core/NetworkHelper.cs
+++ /dev/null
@@ -1,907 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using Greenshot.IniFile;
-using Greenshot.Plugin;
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.Globalization;
-using System.IO;
-using System.Net;
-using System.Text;
-using System.Text.RegularExpressions;
-
-namespace GreenshotPlugin.Core
-{
- ///
- /// HTTP Method to make sure we have the correct method
- ///
- public enum HTTPMethod
- {
- GET,
- POST,
- PUT,
- DELETE,
- HEAD
- };
-
- ///
- /// Description of NetworkHelper.
- ///
- public static class NetworkHelper
- {
- private static readonly CoreConfiguration Config = IniConfig.GetIniSection();
-
- static NetworkHelper()
- {
- try
- {
- // Disable certificate checking
- ServicePointManager.ServerCertificateValidationCallback += delegate
- {
- return true;
- };
- }
- catch (Exception ex)
- {
- LOG.Warn("An error has occured while allowing self-signed certificates:", ex);
- }
- }
-
- ///
- /// Download a uri response as string
- ///
- /// An Uri to specify the download location
- /// string with the file content
- public static string GetAsString(Uri uri)
- {
- return GetResponseAsString(CreateWebRequest(uri));
- }
-
- ///
- /// Download the FavIcon as a Bitmap
- ///
- ///
- /// Bitmap with the FavIcon
- public static Bitmap DownloadFavIcon(Uri baseUri)
- {
- Uri url = new Uri(baseUri, new Uri("favicon.ico"));
- try
- {
- HttpWebRequest request = CreateWebRequest(url);
- using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
- {
- if (request.HaveResponse)
- {
- using (Stream responseStream = response.GetResponseStream())
- {
- if (responseStream != null)
- {
- using (Image image = Image.FromStream(responseStream))
- {
- return (image.Height > 16 && image.Width > 16) ? new Bitmap(image, 16, 16) : new Bitmap(image);
- }
- }
- }
- }
- }
- }
- catch (Exception e)
- {
- LOG.Error("Problem downloading the FavIcon from: " + baseUri, e);
- }
- return null;
- }
-
- ///
- /// Download the uri into a memorystream, without catching exceptions
- ///
- /// Of an image
- /// MemoryStream which is already seeked to 0
- public static MemoryStream GetAsMemoryStream(string url)
- {
- HttpWebRequest request = CreateWebRequest(url);
- using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
- {
- MemoryStream memoryStream = new MemoryStream();
- using (Stream responseStream = response.GetResponseStream())
- {
- if (responseStream != null)
- {
- responseStream.CopyTo(memoryStream);
- }
- // Make sure it can be used directly
- memoryStream.Seek(0, SeekOrigin.Begin);
- }
- return memoryStream;
- }
- }
-
- ///
- /// Download the uri to Bitmap
- ///
- /// Of an image
- /// Bitmap
- public static Image DownloadImage(string url)
- {
- try
- {
- string content;
- using (MemoryStream memoryStream = GetAsMemoryStream(url))
- {
- try
- {
- using (Image image = Image.FromStream(memoryStream))
- {
- return ImageHelper.Clone(image, PixelFormat.Format32bppArgb);
- }
- }
- 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.
- using (StreamReader streamReader = new StreamReader(memoryStream, Encoding.UTF8, true))
- {
- content = streamReader.ReadLine();
- }
- if (!string.IsNullOrEmpty(content))
- {
- Regex imageUrlRegex = new Regex(@"(http|https)://.*(\.png|\.gif|\.jpg|\.tiff|\.jpeg|\.bmp)");
- Match match = imageUrlRegex.Match(content);
- if (match.Success)
- {
- using (MemoryStream memoryStream2 = GetAsMemoryStream(match.Value))
- {
- using (Image image = Image.FromStream(memoryStream2))
- {
- return ImageHelper.Clone(image, PixelFormat.Format32bppArgb);
- }
- }
- }
- }
- throw;
- }
- }
- }
- catch (Exception e)
- {
- LOG.Error("Problem downloading the image from: " + url, e);
- }
- return null;
- }
-
- ///
- /// Helper method to create a web request with a lot of default settings
- ///
- /// string with uri to connect to
- /// WebRequest
- public static HttpWebRequest CreateWebRequest(string uri)
- {
- return CreateWebRequest(new Uri(uri));
- }
-
- ///
- /// Helper method to create a web request with a lot of default settings
- ///
- /// string with uri to connect to
- /// /// Method to use
- /// WebRequest
- public static HttpWebRequest CreateWebRequest(string uri, HTTPMethod method)
- {
- return CreateWebRequest(new Uri(uri), method);
- }
-
- ///
- /// Helper method to create a web request with a lot of default settings
- ///
- /// Uri with uri to connect to
- /// Method to use
- /// WebRequest
- public static HttpWebRequest CreateWebRequest(Uri uri, HTTPMethod method)
- {
- HttpWebRequest webRequest = CreateWebRequest(uri);
- webRequest.Method = method.ToString();
- return webRequest;
- }
-
- ///
- /// Helper method to create a web request, eventually with proxy
- ///
- /// Uri with uri to connect to
- /// WebRequest
- public static HttpWebRequest CreateWebRequest(Uri uri)
- {
- HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
- webRequest.Proxy = Config.UseProxy ? CreateProxy(uri) : null;
- // Make sure the default credentials are available
- webRequest.Credentials = CredentialCache.DefaultCredentials;
-
- // Allow redirect, this is usually needed so that we don't get a problem when a service moves
- webRequest.AllowAutoRedirect = true;
- // Set default timeouts
- webRequest.Timeout = Config.WebRequestTimeout * 1000;
- webRequest.ReadWriteTimeout = Config.WebRequestReadWriteTimeout * 1000;
- return webRequest;
- }
-
- ///
- /// Create a IWebProxy Object which can be used to access the Internet
- /// This method will check the configuration if the proxy is allowed to be used.
- /// Usages can be found in the DownloadFavIcon or Jira and Confluence plugins
- ///
- ///
- /// IWebProxy filled with all the proxy details or null if none is set/wanted
- public static IWebProxy CreateProxy(Uri uri)
- {
- IWebProxy proxyToUse = null;
- if (Config.UseProxy)
- {
- proxyToUse = WebRequest.DefaultWebProxy;
- if (proxyToUse != null)
- {
- proxyToUse.Credentials = CredentialCache.DefaultCredentials;
- if (LOG.IsDebugEnabled)
- {
- // check the proxy for the Uri
- if (!proxyToUse.IsBypassed(uri))
- {
- Uri proxyUri = proxyToUse.GetProxy(uri);
- if (proxyUri != null)
- {
- LOG.Debug("Using proxy: " + proxyUri + " for " + uri);
- }
- else
- {
- LOG.Debug("No proxy found!");
- }
- }
- else
- {
- LOG.Debug("Proxy bypass for: " + uri);
- }
- }
- }
- else
- {
- LOG.Debug("No proxy found!");
- }
- }
- return proxyToUse;
- }
-
- ///
- /// UrlEncodes a string without the requirement for System.Web
- ///
- ///
- ///
- // [Obsolete("Use System.Uri.EscapeDataString instead")]
- public static string UrlEncode(string text)
- {
- if (!string.IsNullOrEmpty(text))
- {
- // Sytem.Uri provides reliable parsing, but doesn't encode spaces.
- return Uri.EscapeDataString(text).Replace("%20", "+");
- }
- return null;
- }
-
- ///
- /// A wrapper around the EscapeDataString, as the limit is 32766 characters
- /// See: http://msdn.microsoft.com/en-us/library/system.uri.escapedatastring%28v=vs.110%29.aspx
- ///
- ///
- /// escaped data string
- public static string EscapeDataString(string text)
- {
- if (!string.IsNullOrEmpty(text))
- {
- StringBuilder result = new StringBuilder();
- int currentLocation = 0;
- while (currentLocation < text.Length)
- {
- string process = text.Substring(currentLocation, Math.Min(16384, text.Length - currentLocation));
- result.Append(Uri.EscapeDataString(process));
- currentLocation = currentLocation + 16384;
- }
- return result.ToString();
- }
- return null;
- }
-
- ///
- /// UrlDecodes a string without requiring System.Web
- ///
- /// String to decode.
- /// decoded string
- public static string UrlDecode(string text)
- {
- // pre-process for + sign space formatting since System.Uri doesn't handle it
- // plus literals are encoded as %2b normally so this should be safe
- text = text.Replace("+", " ");
- return Uri.UnescapeDataString(text);
- }
-
- ///
- /// ParseQueryString without the requirement for System.Web
- ///
- ///
- /// IDictionary string, string
- public static IDictionary ParseQueryString(string queryString)
- {
- IDictionary parameters = new SortedDictionary();
- // remove anything other than query string from uri
- if (queryString.Contains("?"))
- {
- queryString = queryString.Substring(queryString.IndexOf('?') + 1);
- }
- foreach (string vp in Regex.Split(queryString, "&"))
- {
- if (string.IsNullOrEmpty(vp))
- {
- continue;
- }
- string[] singlePair = Regex.Split(vp, "=");
- if (parameters.ContainsKey(singlePair[0]))
- {
- parameters.Remove(singlePair[0]);
- }
- parameters.Add(singlePair[0], singlePair.Length == 2 ? singlePair[1] : string.Empty);
- }
- return parameters;
- }
-
- ///
- /// Generate the query paramters
- ///
- /// the list of query parameters
- /// a string with the query parameters
- public static string GenerateQueryParameters(IDictionary queryParameters)
- {
- if (queryParameters == null || queryParameters.Count == 0)
- {
- return string.Empty;
- }
-
- queryParameters = new SortedDictionary(queryParameters);
-
- StringBuilder sb = new StringBuilder();
- foreach (string key in queryParameters.Keys)
- {
- sb.AppendFormat(CultureInfo.InvariantCulture, "{0}={1}&", key, UrlEncode(string.Format("{0}", queryParameters[key])));
- }
- sb.Remove(sb.Length - 1, 1);
-
- return sb.ToString();
- }
-
- ///
- /// Write Multipart Form Data directly to the HttpWebRequest
- ///
- /// HttpWebRequest to write the multipart form data to
- /// Parameters to include in the multipart form data
- public static void WriteMultipartFormData(HttpWebRequest webRequest, IDictionary postParameters)
- {
- string boundary = String.Format("----------{0:N}", Guid.NewGuid());
- webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
- using (Stream formDataStream = webRequest.GetRequestStream())
- {
- WriteMultipartFormData(formDataStream, boundary, postParameters);
- }
- }
-
- ///
- /// Write Multipart Form Data to the HttpListenerResponse
- ///
- /// HttpListenerResponse
- /// Parameters to include in the multipart form data
- public static void WriteMultipartFormData(HttpListenerResponse response, IDictionary postParameters)
- {
- string boundary = String.Format("----------{0:N}", Guid.NewGuid());
- response.ContentType = "multipart/form-data; boundary=" + boundary;
- WriteMultipartFormData(response.OutputStream, boundary, postParameters);
- }
-
- ///
- /// Write Multipart Form Data to a Stream, content-type should be set before this!
- ///
- /// Stream to write the multipart form data to
- /// String boundary for the multipart/form-data
- /// Parameters to include in the multipart form data
- public static void WriteMultipartFormData(Stream formDataStream, string boundary, IDictionary postParameters)
- {
- bool needsClrf = false;
- foreach (var param in postParameters)
- {
- // Add a CRLF to allow multiple parameters to be added.
- // Skip it on the first parameter, add it to subsequent parameters.
- if (needsClrf)
- {
- formDataStream.Write(Encoding.UTF8.GetBytes("\r\n"), 0, Encoding.UTF8.GetByteCount("\r\n"));
- }
-
- needsClrf = true;
-
- if (param.Value is IBinaryContainer)
- {
- IBinaryContainer binaryParameter = (IBinaryContainer)param.Value;
- binaryParameter.WriteFormDataToStream(boundary, param.Key, formDataStream);
- }
- else
- {
- string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
- boundary,
- param.Key,
- param.Value);
- formDataStream.Write(Encoding.UTF8.GetBytes(postData), 0, Encoding.UTF8.GetByteCount(postData));
- }
- }
-
- // Add the end of the request. Start with a newline
- string footer = "\r\n--" + boundary + "--\r\n";
- formDataStream.Write(Encoding.UTF8.GetBytes(footer), 0, Encoding.UTF8.GetByteCount(footer));
- }
-
- ///
- /// Post the parameters "x-www-form-urlencoded"
- ///
- ///
- ///
- public static void UploadFormUrlEncoded(HttpWebRequest webRequest, IDictionary parameters)
- {
- webRequest.ContentType = "application/x-www-form-urlencoded";
- string urlEncoded = GenerateQueryParameters(parameters);
-
- byte[] data = Encoding.UTF8.GetBytes(urlEncoded);
- using (var requestStream = webRequest.GetRequestStream())
- {
- requestStream.Write(data, 0, data.Length);
- }
- }
-
- ///
- /// Log the headers of the WebResponse, if IsDebugEnabled
- ///
- /// WebResponse
- private static void DebugHeaders(WebResponse response)
- {
- if (!LOG.IsDebugEnabled)
- {
- return;
- }
- LOG.DebugFormat("Debug information on the response from {0} :", response.ResponseUri);
- foreach (string key in response.Headers.AllKeys)
- {
- LOG.DebugFormat("Reponse-header: {0}={1}", key, response.Headers[key]);
- }
- }
-
- ///
- /// Process the web response.
- ///
- /// The request object.
- /// The response data.
- /// This method should handle the StatusCode better!
- public static string GetResponseAsString(HttpWebRequest webRequest)
- {
- return GetResponseAsString(webRequest, false);
- }
-
- ///
- /// Read the response as string
- ///
- ///
- /// string or null
- private static string GetResponseAsString(HttpWebResponse response)
- {
- string responseData = null;
- if (response == null)
- {
- return null;
- }
- using (response)
- {
- Stream responseStream = response.GetResponseStream();
- if (responseStream != null)
- {
- using (StreamReader reader = new StreamReader(responseStream, true))
- {
- responseData = reader.ReadToEnd();
- }
- }
- }
- return responseData;
- }
-
- ///
- ///
- ///
- ///
- ///
- ///
- public static string GetResponseAsString(HttpWebRequest webRequest, bool alsoReturnContentOnError)
- {
- string responseData = null;
- HttpWebResponse response = null;
- bool isHttpError = false;
- try
- {
- response = (HttpWebResponse)webRequest.GetResponse();
- LOG.InfoFormat("Response status: {0}", response.StatusCode);
- isHttpError = (int)response.StatusCode >= 300;
- if (isHttpError)
- {
- LOG.ErrorFormat("HTTP error {0}", response.StatusCode);
- }
- DebugHeaders(response);
- responseData = GetResponseAsString(response);
- if (isHttpError)
- {
- LOG.ErrorFormat("HTTP response {0}", responseData);
- }
- }
- catch (WebException e)
- {
- response = (HttpWebResponse)e.Response;
- HttpStatusCode statusCode = HttpStatusCode.Unused;
- if (response != null)
- {
- statusCode = response.StatusCode;
- LOG.ErrorFormat("HTTP error {0}", statusCode);
- string errorContent = GetResponseAsString(response);
- if (alsoReturnContentOnError)
- {
- return errorContent;
- }
- LOG.ErrorFormat("Content: {0}", errorContent);
- }
- LOG.Error("WebException: ", e);
- if (statusCode == HttpStatusCode.Unauthorized)
- {
- throw new UnauthorizedAccessException(e.Message);
- }
- throw;
- }
- finally
- {
- if (response != null)
- {
- if (isHttpError)
- {
- LOG.ErrorFormat("HTTP error {0} with content: {1}", response.StatusCode, responseData);
- }
- response.Close();
- }
- }
- return responseData;
- }
-
- ///
- /// Get LastModified for a URI
- ///
- /// Uri
- /// DateTime
- public static DateTime GetLastModified(Uri uri)
- {
- try
- {
- HttpWebRequest webRequest = CreateWebRequest(uri);
- webRequest.Method = HTTPMethod.HEAD.ToString();
- using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
- {
- LOG.DebugFormat("RSS feed was updated at {0}", webResponse.LastModified);
- return webResponse.LastModified;
- }
- }
- catch (Exception wE)
- {
- LOG.WarnFormat("Problem requesting HTTP - HEAD on uri {0}", uri);
- LOG.Warn(wE.Message);
- // Pretend it is old
- return DateTime.MinValue;
- }
- }
- }
-
- ///
- /// This interface can be used to pass binary information around, like byte[] or Image
- ///
- public interface IBinaryContainer
- {
- void WriteFormDataToStream(string boundary, string name, Stream formDataStream);
-
- void WriteToStream(Stream formDataStream);
-
- string ToBase64String(Base64FormattingOptions formattingOptions);
-
- byte[] ToByteArray();
-
- void Upload(HttpWebRequest webRequest);
- }
-
- ///
- /// A container to supply files to a Multi-part form data upload
- ///
- public class ByteContainer : IBinaryContainer
- {
- private readonly byte[] _file;
- private readonly string _fileName;
- private readonly string _contentType;
- private readonly int _fileSize;
-
- public ByteContainer(byte[] file) : this(file, null)
- {
- }
-
- public ByteContainer(byte[] file, string filename) : this(file, filename, null)
- {
- }
-
- public ByteContainer(byte[] file, string filename, string contenttype) : this(file, filename, contenttype, 0)
- {
- }
-
- public ByteContainer(byte[] file, string filename, string contenttype, int filesize)
- {
- _file = file;
- _fileName = filename;
- _contentType = contenttype;
- _fileSize = filesize == 0 ? file.Length : filesize;
- }
-
- ///
- /// Create a Base64String from the byte[]
- ///
- /// string
- public string ToBase64String(Base64FormattingOptions formattingOptions)
- {
- return Convert.ToBase64String(_file, 0, _fileSize, formattingOptions);
- }
-
- ///
- /// Returns the initial byte-array which was supplied when creating the FileParameter
- ///
- /// byte[]
- public byte[] ToByteArray()
- {
- return _file;
- }
-
- ///
- /// Write Multipart Form Data directly to the HttpWebRequest response stream
- ///
- /// Separator
- /// name
- /// Stream to write to
- public void WriteFormDataToStream(string boundary, string name, Stream formDataStream)
- {
- // Add just the first part of this param, since we will write the file data directly to the Stream
- string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
- boundary,
- name,
- _fileName ?? name,
- _contentType ?? "application/octet-stream");
-
- formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
-
- // Write the file data directly to the Stream, rather than serializing it to a string.
- formDataStream.Write(_file, 0, _fileSize);
- }
-
- ///
- /// A plain "write data to stream"
- ///
- /// Stream to write to
- public void WriteToStream(Stream dataStream)
- {
- // Write the file data directly to the Stream, rather than serializing it to a string.
- dataStream.Write(_file, 0, _fileSize);
- }
-
- ///
- /// Upload the file to the webrequest
- ///
- ///
- public void Upload(HttpWebRequest webRequest)
- {
- webRequest.ContentType = _contentType;
- webRequest.ContentLength = _fileSize;
- using (var requestStream = webRequest.GetRequestStream())
- {
- WriteToStream(requestStream);
- }
- }
- }
-
- ///
- /// A container to supply images to a Multi-part form data upload
- ///
- public class BitmapContainer : IBinaryContainer
- {
- private readonly Bitmap _bitmap;
- private readonly SurfaceOutputSettings _outputSettings;
- private readonly string _fileName;
-
- public BitmapContainer(Bitmap bitmap, SurfaceOutputSettings outputSettings, string filename)
- {
- _bitmap = bitmap;
- _outputSettings = outputSettings;
- _fileName = filename;
- }
-
- ///
- /// Create a Base64String from the image by saving it to a memory stream and converting it.
- /// Should be avoided if possible, as this uses a lot of memory.
- ///
- /// string
- public string ToBase64String(Base64FormattingOptions formattingOptions)
- {
- using (MemoryStream stream = new MemoryStream())
- {
- ImageOutput.SaveToStream(_bitmap, null, stream, _outputSettings);
- return Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length, formattingOptions);
- }
- }
-
- ///
- /// Create a byte[] from the image by saving it to a memory stream.
- /// Should be avoided if possible, as this uses a lot of memory.
- ///
- /// byte[]
- public byte[] ToByteArray()
- {
- using (MemoryStream stream = new MemoryStream())
- {
- ImageOutput.SaveToStream(_bitmap, null, stream, _outputSettings);
- return stream.ToArray();
- }
- }
-
- ///
- /// Write Multipart Form Data directly to the HttpWebRequest response stream
- ///
- /// Separator
- /// Name of the thing/file
- /// Stream to write to
- public void WriteFormDataToStream(string boundary, string name, Stream formDataStream)
- {
- // Add just the first part of this param, since we will write the file data directly to the Stream
- string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
- boundary,
- name,
- _fileName ?? name,
- "image/" + _outputSettings.Format);
-
- formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
- ImageOutput.SaveToStream(_bitmap, null, formDataStream, _outputSettings);
- }
-
- ///
- /// A plain "write data to stream"
- ///
- ///
- public void WriteToStream(Stream dataStream)
- {
- // Write the file data directly to the Stream, rather than serializing it to a string.
- ImageOutput.SaveToStream(_bitmap, null, dataStream, _outputSettings);
- }
-
- ///
- /// Upload the image to the webrequest
- ///
- ///
- public void Upload(HttpWebRequest webRequest)
- {
- webRequest.ContentType = "image/" + _outputSettings.Format;
- using (var requestStream = webRequest.GetRequestStream())
- {
- WriteToStream(requestStream);
- }
- }
- }
-
- ///
- /// A container to supply surfaces to a Multi-part form data upload
- ///
- public class SurfaceContainer : IBinaryContainer
- {
- private readonly ISurface _surface;
- private readonly SurfaceOutputSettings _outputSettings;
- private readonly string _fileName;
-
- public SurfaceContainer(ISurface surface, SurfaceOutputSettings outputSettings, string filename)
- {
- _surface = surface;
- _outputSettings = outputSettings;
- _fileName = filename;
- }
-
- ///
- /// Create a Base64String from the Surface by saving it to a memory stream and converting it.
- /// Should be avoided if possible, as this uses a lot of memory.
- ///
- /// string
- public string ToBase64String(Base64FormattingOptions formattingOptions)
- {
- using (MemoryStream stream = new MemoryStream())
- {
- ImageOutput.SaveToStream(_surface, stream, _outputSettings);
- return Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length, formattingOptions);
- }
- }
-
- ///
- /// Create a byte[] from the image by saving it to a memory stream.
- /// Should be avoided if possible, as this uses a lot of memory.
- ///
- /// byte[]
- public byte[] ToByteArray()
- {
- using (MemoryStream stream = new MemoryStream())
- {
- ImageOutput.SaveToStream(_surface, stream, _outputSettings);
- return stream.ToArray();
- }
- }
-
- ///
- /// Write Multipart Form Data directly to the HttpWebRequest response stream
- ///
- /// Multipart separator
- /// Name of the thing
- /// Stream to write to
- public void WriteFormDataToStream(string boundary, string name, Stream formDataStream)
- {
- // Add just the first part of this param, since we will write the file data directly to the Stream
- string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
- boundary,
- name,
- _fileName ?? name,
- "image/" + _outputSettings.Format);
-
- formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
- ImageOutput.SaveToStream(_surface, formDataStream, _outputSettings);
- }
-
- ///
- /// A plain "write data to stream"
- ///
- ///
- public void WriteToStream(Stream dataStream)
- {
- // Write the file data directly to the Stream, rather than serializing it to a string.
- ImageOutput.SaveToStream(_surface, dataStream, _outputSettings);
- }
-
- ///
- /// Upload the Surface as image to the webrequest
- ///
- ///
- public void Upload(HttpWebRequest webRequest)
- {
- webRequest.ContentType = "image/" + _outputSettings.Format.ToString();
- using (var requestStream = webRequest.GetRequestStream())
- {
- WriteToStream(requestStream);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/Objects.cs b/Greenshot.ImageEditor/Core/Objects.cs
deleted file mode 100644
index 828ef506e..000000000
--- a/Greenshot.ImageEditor/Core/Objects.cs
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Reflection;
-using System.Runtime.Serialization;
-using System.Runtime.Serialization.Formatters.Binary;
-
-namespace GreenshotPlugin.Core
-{
- public static class Objects
- {
- ///
- /// Perform a deep Copy of the object.
- ///
- /// The type of object being copied.
- /// The object instance to copy.
- /// The copied object.
- public static T Clone(this T source)
- {
- if (!typeof(T).IsSerializable)
- {
- throw new ArgumentException("The type must be serializable.", "source");
- }
-
- // Don't serialize a null object, simply return the default for that object
- if (ReferenceEquals(source, null))
- {
- return default(T);
- }
-
- IFormatter formatter = new BinaryFormatter();
- Stream stream = new MemoryStream();
- using (stream)
- {
- formatter.Serialize(stream, source);
- stream.Seek(0, SeekOrigin.Begin);
- return (T)formatter.Deserialize(stream);
- }
- }
-
- public static void CloneTo(this T source, T destination)
- {
- Type type = typeof(T);
- FieldInfo[] myObjectFields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
-
- foreach (FieldInfo fi in myObjectFields)
- {
- fi.SetValue(destination, fi.GetValue(source));
- }
- PropertyInfo[] myObjectProperties = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
-
- foreach (PropertyInfo pi in myObjectProperties)
- {
- if (pi.CanWrite)
- {
- pi.SetValue(destination, pi.GetValue(source, null), null);
- }
- }
- }
-
- public static bool CompareLists(IList l1, IList l2)
- {
- if (l1.Count != l2.Count)
- {
- return false;
- }
- int matched = 0;
- foreach (T item in l1)
- {
- if (!l2.Contains(item))
- {
- return false;
- }
- matched++;
- }
- return matched == l1.Count;
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/OperatingSystemExtensions.cs b/Greenshot.ImageEditor/Core/OperatingSystemExtensions.cs
deleted file mode 100644
index 70a2495b6..000000000
--- a/Greenshot.ImageEditor/Core/OperatingSystemExtensions.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2016 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on GitHub: https://github.com/greenshot
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-
-namespace GreenshotPlugin.Core
-{
- ///
- /// Extensions to help with querying the Operating System
- ///
- public static class OperatingSystemExtensions
- {
- ///
- /// Test if the current OS is Windows 10
- ///
- /// OperatingSystem from Environment.OSVersion
- /// true if we are running on Windows 10
- public static bool IsWindows10(this OperatingSystem operatingSystem)
- {
- return operatingSystem.Version.Major == 10;
- }
-
- ///
- /// Test if the current OS is Windows 8(.1)
- ///
- /// OperatingSystem from Environment.OSVersion
- /// true if we are running on Windows 8(.1)
- public static bool IsWindows8(this OperatingSystem operatingSystem)
- {
- return operatingSystem.Version.Major == 6 && operatingSystem.Version.Minor >= 2;
- }
-
- ///
- /// Test if the current OS is Windows 8 or later
- ///
- /// OperatingSystem from Environment.OSVersion
- /// true if we are running on Windows 8 or later
- public static bool IsWindows8OrLater(this OperatingSystem operatingSystem)
- {
- return (operatingSystem.Version.Major == 6 && operatingSystem.Version.Minor >= 2) || operatingSystem.Version.Major >= 6;
- }
-
- ///
- /// Test if the current OS is Windows 7 or later
- ///
- /// OperatingSystem from Environment.OSVersion
- /// true if we are running on Windows 7 or later
- public static bool IsWindows7OrLater(this OperatingSystem operatingSystem)
- {
- return (operatingSystem.Version.Major == 6 && operatingSystem.Version.Minor >= 1) || operatingSystem.Version.Major >= 6;
- }
-
- ///
- /// Test if the current OS is Windows Vista or later
- ///
- /// OperatingSystem from Environment.OSVersion
- /// true if we are running on Windows Vista or later
- public static bool IsWindowsVistaOrLater(this OperatingSystem operatingSystem)
- {
- return operatingSystem.Version.Major >= 6;
- }
-
- ///
- /// Test if the current OS is Windows XP or later
- ///
- /// OperatingSystem from Environment.OSVersion
- /// true if we are running on Windows XP or later
- public static bool IsWindowsXpOrLater(this OperatingSystem operatingSystem)
- {
- // Windows 2000 is Major 5 minor 0
- return Environment.OSVersion.Version.Major > 5 || (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1);
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/PluginUtils.cs b/Greenshot.ImageEditor/Core/PluginUtils.cs
deleted file mode 100644
index 525fa0ffb..000000000
--- a/Greenshot.ImageEditor/Core/PluginUtils.cs
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using Greenshot.IniFile;
-using Greenshot.Plugin;
-using GreenshotPlugin.UnmanagedHelpers;
-using Microsoft.Win32;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
-using System.IO;
-using System.Windows.Forms;
-
-namespace GreenshotPlugin.Core
-{
- ///
- /// Description of PluginUtils.
- ///
- public static class PluginUtils
- {
- private static readonly CoreConfiguration conf = IniConfig.GetIniSection();
- private const string PATH_KEY = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\";
- private static readonly IDictionary exeIconCache = new Dictionary();
-
- static PluginUtils()
- {
- conf.PropertyChanged += OnIconSizeChanged;
- }
-
- ///
- /// Simple global property to get the Greenshot host
- ///
- public static IGreenshotHost Host
- {
- get;
- set;
- }
-
- ///
- /// Clear icon cache
- ///
- ///
- ///
- private static void OnIconSizeChanged(object sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == "IconSize")
- {
- List cachedImages = new List();
- lock (exeIconCache)
- {
- foreach (string key in exeIconCache.Keys)
- {
- cachedImages.Add(exeIconCache[key]);
- }
- exeIconCache.Clear();
- }
- foreach (Image cachedImage in cachedImages)
- {
- if (cachedImage != null)
- {
- cachedImage.Dispose();
- }
- }
- }
- }
-
- ///
- /// Get the path of an executable
- ///
- /// e.g. cmd.exe
- /// Path to file
- public static string GetExePath(string exeName)
- {
- using (RegistryKey key = Registry.LocalMachine.OpenSubKey(PATH_KEY + exeName, false))
- {
- if (key != null)
- {
- // "" is the default key, which should point to the requested location
- return (string)key.GetValue("");
- }
- }
- foreach (string pathEntry in (Environment.GetEnvironmentVariable("PATH") ?? "").Split(';'))
- {
- try
- {
- string path = pathEntry.Trim();
- if (!String.IsNullOrEmpty(path) && File.Exists(path = Path.Combine(path, exeName)))
- {
- return Path.GetFullPath(path);
- }
- }
- catch (Exception)
- {
- LOG.WarnFormat("Problem with path entry '{0}'.", pathEntry);
- }
- }
- return null;
- }
-
- ///
- /// Get icon for executable, from the cache
- ///
- /// path to the exe or dll
- /// index of the icon
- /// Bitmap with the icon or null if something happended
- public static Image GetCachedExeIcon(string path, int index)
- {
- string cacheKey = string.Format("{0}:{1}", path, index);
- Image returnValue;
- lock (exeIconCache)
- {
- if (!exeIconCache.TryGetValue(cacheKey, out returnValue))
- {
- lock (exeIconCache)
- {
- if (!exeIconCache.TryGetValue(cacheKey, out returnValue))
- {
- returnValue = GetExeIcon(path, index);
- if (returnValue != null)
- {
- exeIconCache.Add(cacheKey, returnValue);
- }
- }
- }
- }
- }
- return returnValue;
- }
-
- ///
- /// Get icon for executable
- ///
- /// path to the exe or dll
- /// index of the icon
- /// Bitmap with the icon or null if something happended
- private static Bitmap GetExeIcon(string path, int index)
- {
- if (!File.Exists(path))
- {
- return null;
- }
- try
- {
- using (Icon appIcon = ImageHelper.ExtractAssociatedIcon(path, index, conf.UseLargeIcons))
- {
- if (appIcon != null)
- {
- return appIcon.ToBitmap();
- }
- }
- using (Icon appIcon = Shell32.GetFileIcon(path, conf.UseLargeIcons ? Shell32.IconSize.Large : Shell32.IconSize.Small, false))
- {
- if (appIcon != null)
- {
- return appIcon.ToBitmap();
- }
- }
- }
- catch (Exception exIcon)
- {
- LOG.Error("error retrieving icon: ", exIcon);
- }
- return null;
- }
-
- ///
- /// Helper method to add a MenuItem to the File MenuItem of an ImageEditor
- ///
- /// Image to display in the menu
- /// Text to display in the menu
- /// The TAG value
- /// Keys which can be used as shortcut
- /// The onclick handler
- public static void AddToFileMenu(IImageEditor imageEditor, Image image, string text, object tag, Keys? shortcutKeys, EventHandler handler)
- {
- ToolStripMenuItem item = new ToolStripMenuItem();
- item.Image = image;
- item.Text = text;
- item.Tag = tag;
- if (shortcutKeys.HasValue)
- {
- item.ShortcutKeys = shortcutKeys.Value;
- }
- item.Click += handler;
- AddToFileMenu(imageEditor, item);
- }
-
- ///
- /// Helper method to add a MenuItem to the File MenuItem of an ImageEditor
- ///
- ///
- ///
- public static void AddToFileMenu(IImageEditor imageEditor, ToolStripMenuItem item)
- {
- ToolStripMenuItem toolStripMenuItem = imageEditor.GetFileMenuItem();
- bool added = false;
- for (int i = 0; i < toolStripMenuItem.DropDownItems.Count; i++)
- {
- if (toolStripMenuItem.DropDownItems[i].GetType() == typeof(ToolStripSeparator))
- {
- toolStripMenuItem.DropDownItems.Insert(i, item);
- added = true;
- break;
- }
- }
- if (!added)
- {
- toolStripMenuItem.DropDownItems.Add(item);
- }
- }
-
- ///
- /// Helper method to add a MenuItem to the Plugin MenuItem of an ImageEditor
- ///
- ///
- ///
- public static void AddToPluginMenu(IImageEditor imageEditor, ToolStripMenuItem item)
- {
- ToolStripMenuItem toolStripMenuItem = imageEditor.GetPluginMenuItem();
- bool added = false;
- for (int i = 0; i < toolStripMenuItem.DropDownItems.Count; i++)
- {
- if (toolStripMenuItem.DropDownItems[i].GetType() == typeof(ToolStripSeparator))
- {
- toolStripMenuItem.DropDownItems.Insert(i, item);
- added = true;
- break;
- }
- }
- if (!added)
- {
- toolStripMenuItem.DropDownItems.Add(item);
- }
- }
-
- ///
- /// Helper method to add a plugin MenuItem to the Greenshot context menu
- ///
- ///
- ///
- public static void AddToContextMenu(IGreenshotHost host, ToolStripMenuItem item)
- {
- // Here we can hang ourselves to the main context menu!
- ContextMenuStrip contextMenu = host.MainMenu;
- bool addedItem = false;
-
- // Try to find a separator, so we insert ourselves after it
- for (int i = 0; i < contextMenu.Items.Count; i++)
- {
- if (contextMenu.Items[i].GetType() == typeof(ToolStripSeparator))
- {
- // Check if we need to add a new separator, which is done if the first found has a Tag with the value "PluginsAreAddedBefore"
- if ("PluginsAreAddedBefore".Equals(contextMenu.Items[i].Tag))
- {
- ToolStripSeparator separator = new ToolStripSeparator();
- separator.Tag = "PluginsAreAddedAfter";
- separator.Size = new Size(305, 6);
- contextMenu.Items.Insert(i, separator);
- }
- else if (!"PluginsAreAddedAfter".Equals(contextMenu.Items[i].Tag))
- {
- continue;
- }
- contextMenu.Items.Insert(i + 1, item);
- addedItem = true;
- break;
- }
- }
- // If we didn't insert the item, we just add it...
- if (!addedItem)
- {
- contextMenu.Items.Add(item);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/QuantizerHelper.cs b/Greenshot.ImageEditor/Core/QuantizerHelper.cs
deleted file mode 100644
index c5ca60e11..000000000
--- a/Greenshot.ImageEditor/Core/QuantizerHelper.cs
+++ /dev/null
@@ -1,770 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-
-namespace GreenshotPlugin.Core
-{
- internal class WuColorCube
- {
- ///
- /// Gets or sets the red minimum.
- ///
- /// The red minimum.
- public Int32 RedMinimum { get; set; }
-
- ///
- /// Gets or sets the red maximum.
- ///
- /// The red maximum.
- public Int32 RedMaximum { get; set; }
-
- ///
- /// Gets or sets the green minimum.
- ///
- /// The green minimum.
- public Int32 GreenMinimum { get; set; }
-
- ///
- /// Gets or sets the green maximum.
- ///
- /// The green maximum.
- public Int32 GreenMaximum { get; set; }
-
- ///
- /// Gets or sets the blue minimum.
- ///
- /// The blue minimum.
- public Int32 BlueMinimum { get; set; }
-
- ///
- /// Gets or sets the blue maximum.
- ///
- /// The blue maximum.
- public Int32 BlueMaximum { get; set; }
-
- ///
- /// Gets or sets the cube volume.
- ///
- /// The volume.
- public Int32 Volume { get; set; }
- }
-
- public class WuQuantizer : IDisposable
- {
- private const Int32 MAXCOLOR = 512;
- private const Int32 RED = 2;
- private const Int32 GREEN = 1;
- private const Int32 BLUE = 0;
- private const Int32 SIDESIZE = 33;
- private const Int32 MAXSIDEINDEX = 32;
- private const Int32 MAXVOLUME = SIDESIZE * SIDESIZE * SIDESIZE;
-
- // To count the colors
- private readonly int colorCount;
-
- private Int32[] reds;
- private Int32[] greens;
- private Int32[] blues;
- private Int32[] sums;
-
- private readonly Int64[,,] weights;
- private readonly Int64[,,] momentsRed;
- private readonly Int64[,,] momentsGreen;
- private readonly Int64[,,] momentsBlue;
- private readonly Single[,,] moments;
-
- private byte[] tag;
-
- private readonly WuColorCube[] cubes;
- private readonly Bitmap sourceBitmap;
- private Bitmap resultBitmap;
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (resultBitmap != null)
- {
- resultBitmap.Dispose();
- resultBitmap = null;
- }
- }
- }
-
- ///
- /// See for more details.
- ///
- public WuQuantizer(Bitmap sourceBitmap)
- {
- this.sourceBitmap = sourceBitmap;
- // Make sure the color count variables are reset
- BitArray bitArray = new BitArray((int)Math.Pow(2, 24));
- colorCount = 0;
-
- // creates all the cubes
- cubes = new WuColorCube[MAXCOLOR];
-
- // initializes all the cubes
- for (Int32 cubeIndex = 0; cubeIndex < MAXCOLOR; cubeIndex++)
- {
- cubes[cubeIndex] = new WuColorCube();
- }
-
- // resets the reference minimums
- cubes[0].RedMinimum = 0;
- cubes[0].GreenMinimum = 0;
- cubes[0].BlueMinimum = 0;
-
- // resets the reference maximums
- cubes[0].RedMaximum = MAXSIDEINDEX;
- cubes[0].GreenMaximum = MAXSIDEINDEX;
- cubes[0].BlueMaximum = MAXSIDEINDEX;
-
- weights = new Int64[SIDESIZE, SIDESIZE, SIDESIZE];
- momentsRed = new Int64[SIDESIZE, SIDESIZE, SIDESIZE];
- momentsGreen = new Int64[SIDESIZE, SIDESIZE, SIDESIZE];
- momentsBlue = new Int64[SIDESIZE, SIDESIZE, SIDESIZE];
- moments = new Single[SIDESIZE, SIDESIZE, SIDESIZE];
-
- Int32[] table = new Int32[256];
-
- for (Int32 tableIndex = 0; tableIndex < 256; ++tableIndex)
- {
- table[tableIndex] = tableIndex * tableIndex;
- }
-
- // Use a bitmap to store the initial match, which is just as good as an array and saves us 2x the storage
- using (IFastBitmap sourceFastBitmap = FastBitmap.Create(sourceBitmap))
- {
- IFastBitmapWithBlend sourceFastBitmapWithBlend = sourceFastBitmap as IFastBitmapWithBlend;
- sourceFastBitmap.Lock();
- using (FastChunkyBitmap destinationFastBitmap = FastBitmap.CreateEmpty(sourceBitmap.Size, PixelFormat.Format8bppIndexed, Color.White) as FastChunkyBitmap)
- {
- destinationFastBitmap.Lock();
- for (int y = 0; y < sourceFastBitmap.Height; y++)
- {
- for (int x = 0; x < sourceFastBitmap.Width; x++)
- {
- Color color;
- if (sourceFastBitmapWithBlend == null)
- {
- color = sourceFastBitmap.GetColorAt(x, y);
- }
- else
- {
- color = sourceFastBitmapWithBlend.GetBlendedColorAt(x, y);
- }
- // To count the colors
- int index = color.ToArgb() & 0x00ffffff;
- // Check if we already have this color
- if (!bitArray.Get(index))
- {
- // If not, add 1 to the single colors
- colorCount++;
- bitArray.Set(index, true);
- }
-
- Int32 indexRed = (color.R >> 3) + 1;
- Int32 indexGreen = (color.G >> 3) + 1;
- Int32 indexBlue = (color.B >> 3) + 1;
-
- weights[indexRed, indexGreen, indexBlue]++;
- momentsRed[indexRed, indexGreen, indexBlue] += color.R;
- momentsGreen[indexRed, indexGreen, indexBlue] += color.G;
- momentsBlue[indexRed, indexGreen, indexBlue] += color.B;
- moments[indexRed, indexGreen, indexBlue] += table[color.R] + table[color.G] + table[color.B];
-
- // Store the initial "match"
- Int32 paletteIndex = (indexRed << 10) + (indexRed << 6) + indexRed + (indexGreen << 5) + indexGreen + indexBlue;
- destinationFastBitmap.SetColorIndexAt(x, y, (byte)(paletteIndex & 0xff));
- }
- }
- resultBitmap = destinationFastBitmap.UnlockAndReturnBitmap();
- }
- }
- }
-
- ///
- /// See for more details.
- ///
- public Int32 GetColorCount()
- {
- return colorCount;
- }
-
- ///
- /// Reindex the 24/32 BPP (A)RGB image to a 8BPP
- ///
- /// Bitmap
- public Bitmap SimpleReindex()
- {
- List colors = new List();
- Dictionary lookup = new Dictionary();
- using (FastChunkyBitmap bbbDest = FastBitmap.Create(resultBitmap) as FastChunkyBitmap)
- {
- bbbDest.Lock();
- using (IFastBitmap bbbSrc = FastBitmap.Create(sourceBitmap))
- {
- IFastBitmapWithBlend bbbSrcBlend = bbbSrc as IFastBitmapWithBlend;
-
- bbbSrc.Lock();
- byte index;
- for (int y = 0; y < bbbSrc.Height; y++)
- {
- for (int x = 0; x < bbbSrc.Width; x++)
- {
- Color color;
- if (bbbSrcBlend != null)
- {
- color = bbbSrcBlend.GetBlendedColorAt(x, y);
- }
- else
- {
- color = bbbSrc.GetColorAt(x, y);
- }
- if (lookup.ContainsKey(color))
- {
- index = lookup[color];
- }
- else
- {
- colors.Add(color);
- index = (byte)(colors.Count - 1);
- lookup.Add(color, index);
- }
- bbbDest.SetColorIndexAt(x, y, index);
- }
- }
- }
- }
-
- // generates palette
- ColorPalette imagePalette = resultBitmap.Palette;
- Color[] entries = imagePalette.Entries;
- for (Int32 paletteIndex = 0; paletteIndex < 256; paletteIndex++)
- {
- if (paletteIndex < colorCount)
- {
- entries[paletteIndex] = colors[paletteIndex];
- }
- else
- {
- entries[paletteIndex] = Color.Black;
- }
- }
- resultBitmap.Palette = imagePalette;
-
- // Make sure the bitmap is not disposed, as we return it.
- Bitmap tmpBitmap = resultBitmap;
- resultBitmap = null;
- return tmpBitmap;
- }
-
- ///
- /// Get the image
- ///
- public Bitmap GetQuantizedImage(int allowedColorCount)
- {
- if (allowedColorCount > 256)
- {
- throw new ArgumentOutOfRangeException("Quantizing muss be done to get less than 256 colors");
- }
- if (colorCount < allowedColorCount)
- {
- // Simple logic to reduce to 8 bit
- LOG.Info("Colors in the image are already less as whished for, using simple copy to indexed image, no quantizing needed!");
- return SimpleReindex();
- }
- // preprocess the colors
- CalculateMoments();
- LOG.Info("Calculated the moments...");
- Int32 next = 0;
- Single[] volumeVariance = new Single[MAXCOLOR];
-
- // processes the cubes
- for (Int32 cubeIndex = 1; cubeIndex < allowedColorCount; ++cubeIndex)
- {
- // if cut is possible; make it
- if (Cut(cubes[next], cubes[cubeIndex]))
- {
- volumeVariance[next] = cubes[next].Volume > 1 ? CalculateVariance(cubes[next]) : 0.0f;
- volumeVariance[cubeIndex] = cubes[cubeIndex].Volume > 1 ? CalculateVariance(cubes[cubeIndex]) : 0.0f;
- }
- else
- {
- // the cut was not possible, revert the index
- volumeVariance[next] = 0.0f;
- cubeIndex--;
- }
-
- next = 0;
- Single temp = volumeVariance[0];
-
- for (Int32 index = 1; index <= cubeIndex; ++index)
- {
- if (volumeVariance[index] > temp)
- {
- temp = volumeVariance[index];
- next = index;
- }
- }
-
- if (temp <= 0.0)
- {
- allowedColorCount = cubeIndex + 1;
- break;
- }
- }
-
- Int32[] lookupRed = new Int32[MAXCOLOR];
- Int32[] lookupGreen = new Int32[MAXCOLOR];
- Int32[] lookupBlue = new Int32[MAXCOLOR];
-
- tag = new byte[MAXVOLUME];
-
- // precalculates lookup tables
- for (int k = 0; k < allowedColorCount; ++k)
- {
- Mark(cubes[k], k, tag);
-
- long weight = Volume(cubes[k], weights);
-
- if (weight > 0)
- {
- lookupRed[k] = (int)(Volume(cubes[k], momentsRed) / weight);
- lookupGreen[k] = (int)(Volume(cubes[k], momentsGreen) / weight);
- lookupBlue[k] = (int)(Volume(cubes[k], momentsBlue) / weight);
- }
- else
- {
- lookupRed[k] = 0;
- lookupGreen[k] = 0;
- lookupBlue[k] = 0;
- }
- }
-
- reds = new Int32[allowedColorCount + 1];
- greens = new Int32[allowedColorCount + 1];
- blues = new Int32[allowedColorCount + 1];
- sums = new Int32[allowedColorCount + 1];
-
- LOG.Info("Starting bitmap reconstruction...");
-
- using (FastChunkyBitmap dest = FastBitmap.Create(resultBitmap) as FastChunkyBitmap)
- {
- using (IFastBitmap src = FastBitmap.Create(sourceBitmap))
- {
- IFastBitmapWithBlend srcBlend = src as IFastBitmapWithBlend;
- Dictionary lookup = new Dictionary();
- byte bestMatch;
- for (int y = 0; y < src.Height; y++)
- {
- for (int x = 0; x < src.Width; x++)
- {
- Color color;
- if (srcBlend != null)
- {
- // WithoutAlpha, this makes it possible to ignore the alpha
- color = srcBlend.GetBlendedColorAt(x, y);
- }
- else
- {
- color = src.GetColorAt(x, y);
- }
-
- // Check if we already matched the color
- if (!lookup.ContainsKey(color))
- {
- // If not we need to find the best match
-
- // First get initial match
- bestMatch = dest.GetColorIndexAt(x, y);
- bestMatch = tag[bestMatch];
-
- Int32 bestDistance = 100000000;
- for (int lookupIndex = 0; lookupIndex < allowedColorCount; lookupIndex++)
- {
- Int32 foundRed = lookupRed[lookupIndex];
- Int32 foundGreen = lookupGreen[lookupIndex];
- Int32 foundBlue = lookupBlue[lookupIndex];
- Int32 deltaRed = color.R - foundRed;
- Int32 deltaGreen = color.G - foundGreen;
- Int32 deltaBlue = color.B - foundBlue;
-
- Int32 distance = deltaRed * deltaRed + deltaGreen * deltaGreen + deltaBlue * deltaBlue;
-
- if (distance < bestDistance)
- {
- bestDistance = distance;
- bestMatch = (byte)lookupIndex;
- }
- }
- lookup.Add(color, bestMatch);
- }
- else
- {
- // Already matched, so we just use the lookup
- bestMatch = lookup[color];
- }
-
- reds[bestMatch] += color.R;
- greens[bestMatch] += color.G;
- blues[bestMatch] += color.B;
- sums[bestMatch]++;
-
- dest.SetColorIndexAt(x, y, bestMatch);
- }
- }
- }
- }
-
- // generates palette
- ColorPalette imagePalette = resultBitmap.Palette;
- Color[] entries = imagePalette.Entries;
- for (Int32 paletteIndex = 0; paletteIndex < allowedColorCount; paletteIndex++)
- {
- if (sums[paletteIndex] > 0)
- {
- reds[paletteIndex] /= sums[paletteIndex];
- greens[paletteIndex] /= sums[paletteIndex];
- blues[paletteIndex] /= sums[paletteIndex];
- }
-
- entries[paletteIndex] = Color.FromArgb(255, reds[paletteIndex], greens[paletteIndex], blues[paletteIndex]);
- }
- resultBitmap.Palette = imagePalette;
-
- // Make sure the bitmap is not disposed, as we return it.
- Bitmap tmpBitmap = resultBitmap;
- resultBitmap = null;
- return tmpBitmap;
- }
-
- ///
- /// Converts the histogram to a series of moments.
- ///
- private void CalculateMoments()
- {
- Int64[] area = new Int64[SIDESIZE];
- Int64[] areaRed = new Int64[SIDESIZE];
- Int64[] areaGreen = new Int64[SIDESIZE];
- Int64[] areaBlue = new Int64[SIDESIZE];
- Single[] area2 = new Single[SIDESIZE];
-
- for (Int32 redIndex = 1; redIndex <= MAXSIDEINDEX; ++redIndex)
- {
- for (Int32 index = 0; index <= MAXSIDEINDEX; ++index)
- {
- area[index] = 0;
- areaRed[index] = 0;
- areaGreen[index] = 0;
- areaBlue[index] = 0;
- area2[index] = 0;
- }
-
- for (Int32 greenIndex = 1; greenIndex <= MAXSIDEINDEX; ++greenIndex)
- {
- Int64 line = 0;
- Int64 lineRed = 0;
- Int64 lineGreen = 0;
- Int64 lineBlue = 0;
- Single line2 = 0.0f;
-
- for (Int32 blueIndex = 1; blueIndex <= MAXSIDEINDEX; ++blueIndex)
- {
- line += weights[redIndex, greenIndex, blueIndex];
- lineRed += momentsRed[redIndex, greenIndex, blueIndex];
- lineGreen += momentsGreen[redIndex, greenIndex, blueIndex];
- lineBlue += momentsBlue[redIndex, greenIndex, blueIndex];
- line2 += moments[redIndex, greenIndex, blueIndex];
-
- area[blueIndex] += line;
- areaRed[blueIndex] += lineRed;
- areaGreen[blueIndex] += lineGreen;
- areaBlue[blueIndex] += lineBlue;
- area2[blueIndex] += line2;
-
- weights[redIndex, greenIndex, blueIndex] = weights[redIndex - 1, greenIndex, blueIndex] + area[blueIndex];
- momentsRed[redIndex, greenIndex, blueIndex] = momentsRed[redIndex - 1, greenIndex, blueIndex] + areaRed[blueIndex];
- momentsGreen[redIndex, greenIndex, blueIndex] = momentsGreen[redIndex - 1, greenIndex, blueIndex] + areaGreen[blueIndex];
- momentsBlue[redIndex, greenIndex, blueIndex] = momentsBlue[redIndex - 1, greenIndex, blueIndex] + areaBlue[blueIndex];
- moments[redIndex, greenIndex, blueIndex] = moments[redIndex - 1, greenIndex, blueIndex] + area2[blueIndex];
- }
- }
- }
- }
-
- ///
- /// Computes the volume of the cube in a specific moment.
- ///
- private static Int64 Volume(WuColorCube cube, Int64[,,] moment)
- {
- return moment[cube.RedMaximum, cube.GreenMaximum, cube.BlueMaximum] -
- moment[cube.RedMaximum, cube.GreenMaximum, cube.BlueMinimum] -
- moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMaximum] +
- moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] -
- moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMaximum] +
- moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] +
- moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum] -
- moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum];
- }
-
- ///
- /// Computes the volume of the cube in a specific moment. For the floating-point values.
- ///
- private static Single VolumeFloat(WuColorCube cube, Single[,,] moment)
- {
- return moment[cube.RedMaximum, cube.GreenMaximum, cube.BlueMaximum] -
- moment[cube.RedMaximum, cube.GreenMaximum, cube.BlueMinimum] -
- moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMaximum] +
- moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] -
- moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMaximum] +
- moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] +
- moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum] -
- moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum];
- }
-
- ///
- /// Splits the cube in given position, and color direction.
- ///
- private static Int64 Top(WuColorCube cube, Int32 direction, Int32 position, Int64[,,] moment)
- {
- switch (direction)
- {
- case RED:
- return (moment[position, cube.GreenMaximum, cube.BlueMaximum] -
- moment[position, cube.GreenMaximum, cube.BlueMinimum] -
- moment[position, cube.GreenMinimum, cube.BlueMaximum] +
- moment[position, cube.GreenMinimum, cube.BlueMinimum]);
-
- case GREEN:
- return (moment[cube.RedMaximum, position, cube.BlueMaximum] -
- moment[cube.RedMaximum, position, cube.BlueMinimum] -
- moment[cube.RedMinimum, position, cube.BlueMaximum] +
- moment[cube.RedMinimum, position, cube.BlueMinimum]);
-
- case BLUE:
- return (moment[cube.RedMaximum, cube.GreenMaximum, position] -
- moment[cube.RedMaximum, cube.GreenMinimum, position] -
- moment[cube.RedMinimum, cube.GreenMaximum, position] +
- moment[cube.RedMinimum, cube.GreenMinimum, position]);
-
- default:
- return 0;
- }
- }
-
- ///
- /// Splits the cube in a given color direction at its minimum.
- ///
- private static Int64 Bottom(WuColorCube cube, Int32 direction, Int64[,,] moment)
- {
- switch (direction)
- {
- case RED:
- return (-moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMaximum] +
- moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] +
- moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum] -
- moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum]);
-
- case GREEN:
- return (-moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMaximum] +
- moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] +
- moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum] -
- moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum]);
-
- case BLUE:
- return (-moment[cube.RedMaximum, cube.GreenMaximum, cube.BlueMinimum] +
- moment[cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] +
- moment[cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] -
- moment[cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum]);
- default:
- return 0;
- }
- }
-
- ///
- /// Calculates statistical variance for a given cube.
- ///
- private Single CalculateVariance(WuColorCube cube)
- {
- Single volumeRed = Volume(cube, momentsRed);
- Single volumeGreen = Volume(cube, momentsGreen);
- Single volumeBlue = Volume(cube, momentsBlue);
- Single volumeMoment = VolumeFloat(cube, moments);
- Single volumeWeight = Volume(cube, weights);
-
- Single distance = volumeRed * volumeRed + volumeGreen * volumeGreen + volumeBlue * volumeBlue;
-
- return volumeMoment - (distance / volumeWeight);
- }
-
- ///
- /// Finds the optimal (maximal) position for the cut.
- ///
- private Single Maximize(WuColorCube cube, Int32 direction, Int32 first, Int32 last, Int32[] cut, Int64 wholeRed, Int64 wholeGreen, Int64 wholeBlue, Int64 wholeWeight)
- {
- Int64 bottomRed = Bottom(cube, direction, momentsRed);
- Int64 bottomGreen = Bottom(cube, direction, momentsGreen);
- Int64 bottomBlue = Bottom(cube, direction, momentsBlue);
- Int64 bottomWeight = Bottom(cube, direction, weights);
-
- Single result = 0.0f;
- cut[0] = -1;
-
- for (Int32 position = first; position < last; ++position)
- {
- // determines the cube cut at a certain position
- Int64 halfRed = bottomRed + Top(cube, direction, position, momentsRed);
- Int64 halfGreen = bottomGreen + Top(cube, direction, position, momentsGreen);
- Int64 halfBlue = bottomBlue + Top(cube, direction, position, momentsBlue);
- Int64 halfWeight = bottomWeight + Top(cube, direction, position, weights);
-
- // the cube cannot be cut at bottom (this would lead to empty cube)
- if (halfWeight != 0)
- {
- Single halfDistance = (Single)halfRed * halfRed + (Single)halfGreen * halfGreen + (Single)halfBlue * halfBlue;
- Single temp = halfDistance / halfWeight;
-
- halfRed = wholeRed - halfRed;
- halfGreen = wholeGreen - halfGreen;
- halfBlue = wholeBlue - halfBlue;
- halfWeight = wholeWeight - halfWeight;
-
- if (halfWeight != 0)
- {
- halfDistance = (Single)halfRed * halfRed + (Single)halfGreen * halfGreen + (Single)halfBlue * halfBlue;
- temp += halfDistance / halfWeight;
-
- if (temp > result)
- {
- result = temp;
- cut[0] = position;
- }
- }
- }
- }
-
- return result;
- }
-
- ///
- /// Cuts a cube with another one.
- ///
- private Boolean Cut(WuColorCube first, WuColorCube second)
- {
- Int32 direction;
-
- Int32[] cutRed = { 0 };
- Int32[] cutGreen = { 0 };
- Int32[] cutBlue = { 0 };
-
- Int64 wholeRed = Volume(first, momentsRed);
- Int64 wholeGreen = Volume(first, momentsGreen);
- Int64 wholeBlue = Volume(first, momentsBlue);
- Int64 wholeWeight = Volume(first, weights);
-
- Single maxRed = Maximize(first, RED, first.RedMinimum + 1, first.RedMaximum, cutRed, wholeRed, wholeGreen, wholeBlue, wholeWeight);
- Single maxGreen = Maximize(first, GREEN, first.GreenMinimum + 1, first.GreenMaximum, cutGreen, wholeRed, wholeGreen, wholeBlue, wholeWeight);
- Single maxBlue = Maximize(first, BLUE, first.BlueMinimum + 1, first.BlueMaximum, cutBlue, wholeRed, wholeGreen, wholeBlue, wholeWeight);
-
- if ((maxRed >= maxGreen) && (maxRed >= maxBlue))
- {
- direction = RED;
-
- // cannot split empty cube
- if (cutRed[0] < 0) return false;
- }
- else
- {
- if ((maxGreen >= maxRed) && (maxGreen >= maxBlue))
- {
- direction = GREEN;
- }
- else
- {
- direction = BLUE;
- }
- }
-
- second.RedMaximum = first.RedMaximum;
- second.GreenMaximum = first.GreenMaximum;
- second.BlueMaximum = first.BlueMaximum;
-
- // cuts in a certain direction
- switch (direction)
- {
- case RED:
- second.RedMinimum = first.RedMaximum = cutRed[0];
- second.GreenMinimum = first.GreenMinimum;
- second.BlueMinimum = first.BlueMinimum;
- break;
-
- case GREEN:
- second.GreenMinimum = first.GreenMaximum = cutGreen[0];
- second.RedMinimum = first.RedMinimum;
- second.BlueMinimum = first.BlueMinimum;
- break;
-
- case BLUE:
- second.BlueMinimum = first.BlueMaximum = cutBlue[0];
- second.RedMinimum = first.RedMinimum;
- second.GreenMinimum = first.GreenMinimum;
- break;
- }
-
- // determines the volumes after cut
- first.Volume = (first.RedMaximum - first.RedMinimum) * (first.GreenMaximum - first.GreenMinimum) * (first.BlueMaximum - first.BlueMinimum);
- second.Volume = (second.RedMaximum - second.RedMinimum) * (second.GreenMaximum - second.GreenMinimum) * (second.BlueMaximum - second.BlueMinimum);
-
- // the cut was successfull
- return true;
- }
-
- ///
- /// Marks all the tags with a given label.
- ///
- private void Mark(WuColorCube cube, Int32 label, byte[] tag)
- {
- for (Int32 redIndex = cube.RedMinimum + 1; redIndex <= cube.RedMaximum; ++redIndex)
- {
- for (Int32 greenIndex = cube.GreenMinimum + 1; greenIndex <= cube.GreenMaximum; ++greenIndex)
- {
- for (Int32 blueIndex = cube.BlueMinimum + 1; blueIndex <= cube.BlueMaximum; ++blueIndex)
- {
- tag[(redIndex << 10) + (redIndex << 6) + redIndex + (greenIndex << 5) + greenIndex + blueIndex] = (byte)label;
- }
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Greenshot.ImageEditor/Core/StringExtensions.cs b/Greenshot.ImageEditor/Core/StringExtensions.cs
deleted file mode 100644
index d1eb031a3..000000000
--- a/Greenshot.ImageEditor/Core/StringExtensions.cs
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Greenshot - a free and open source screenshot tool
- * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
- *
- * For more information see: http://getgreenshot.org/
- * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Security.Cryptography;
-using System.Text;
-using System.Text.RegularExpressions;
-
-namespace GreenshotPlugin.Core
-{
- public static class StringExtensions
- {
- private const string RGBIV = "dlgjowejgogkklwj";
- private const string KEY = "lsjvkwhvwujkagfauguwcsjgu2wueuff";
-
- ///
- /// Format a string with the specified object
- ///
- /// String with formatting, like {name}
- /// Object used for the formatting
- /// Formatted string
- public static string FormatWith(this string format, object source)
- {
- return FormatWith(format, null, source);
- }
-
- ///
- /// Format the string "format" with the source
- ///
- ///
- ///
- /// object with properties, if a property has the type IDictionary string,string it can used these parameters too
- /// Formatted string
- public static string FormatWith(this string format, IFormatProvider provider, object source)
- {
- if (format == null)
- {
- throw new ArgumentNullException("format");
- }
-
- IDictionary properties = new Dictionary();
- foreach (var propertyInfo in source.GetType().GetProperties())
- {
- if (propertyInfo.CanRead && propertyInfo.CanWrite)
- {
- object value = propertyInfo.GetValue(source, null);
- if (propertyInfo.PropertyType != typeof(IDictionary))
- {
- properties.Add(propertyInfo.Name, value);
- }
- else
- {
- IDictionary dictionary = (IDictionary)value;
- foreach (var propertyKey in dictionary.Keys)
- {
- properties.Add(propertyKey, dictionary[propertyKey]);
- }
- }
- }
- }
-
- Regex r = new Regex(@"(?\{)+(?[\w\.\[\]]+)(?:[^}]+)?(?\})+", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
-
- List