diff --git a/ShareX.HelpersLib/Enums.cs b/ShareX.HelpersLib/Enums.cs index d2ac30d28..c19ed84b7 100644 --- a/ShareX.HelpersLib/Enums.cs +++ b/ShareX.HelpersLib/Enums.cs @@ -188,4 +188,13 @@ public enum ImageCombinerAlignment Center, RightOrBottom } + + public enum ImageInterpolationMode + { + HighQualityBicubic, + Bicubic, + HighQualityBilinear, + Bilinear, + NearestNeighbor + } } \ No newline at end of file diff --git a/ShareX.HelpersLib/Extensions/Extensions.cs b/ShareX.HelpersLib/Extensions/Extensions.cs index f8e5e950d..8cddbd208 100644 --- a/ShareX.HelpersLib/Extensions/Extensions.cs +++ b/ShareX.HelpersLib/Extensions/Extensions.cs @@ -650,6 +650,16 @@ public static Point Center(this Rectangle rect) return new Point(rect.X + (rect.Width / 2), rect.Y + (rect.Height / 2)); } + public static int Area(this Rectangle rect) + { + return rect.Width * rect.Height; + } + + public static int Perimeter(this Rectangle rect) + { + return 2 * (rect.Width + rect.Height); + } + public static Point Restrict(this Point point, Rectangle rect) { point.X = Math.Max(point.X, rect.X); diff --git a/ShareX.HelpersLib/Extensions/NumberExtensions.cs b/ShareX.HelpersLib/Extensions/NumberExtensions.cs index 629499f03..da9b60d61 100644 --- a/ShareX.HelpersLib/Extensions/NumberExtensions.cs +++ b/ShareX.HelpersLib/Extensions/NumberExtensions.cs @@ -74,11 +74,12 @@ public static bool IsOddNumber(this int num) public static string ToSizeString(this long size, bool binary = false, int decimalPlaces = 2) { - if (size < 1024) return Math.Max(size, 0) + " B"; - int place = (int)Math.Floor(Math.Log(size, 1024)); - double num = size / Math.Pow(1024, place); + int bytes = binary ? 1024 : 1000; + if (size < bytes) return Math.Max(size, 0) + " B"; + int place = (int)Math.Floor(Math.Log(size, bytes)); + double num = size / Math.Pow(bytes, place); string suffix = binary ? suffixBinary[place] : suffixDecimal[place]; - return string.Format("{0} {1}", num.ToDecimalString(decimalPlaces.Clamp(0, 3)), suffix); + return num.ToDecimalString(decimalPlaces.Clamp(0, 3)) + " " + suffix; } public static string ToDecimalString(this double number, int decimalPlaces) diff --git a/ShareX.HelpersLib/Helpers/ImageHelpers.cs b/ShareX.HelpersLib/Helpers/ImageHelpers.cs index 6f908a301..ac456fc6f 100644 --- a/ShareX.HelpersLib/Helpers/ImageHelpers.cs +++ b/ShareX.HelpersLib/Helpers/ImageHelpers.cs @@ -75,18 +75,6 @@ public static Bitmap ResizeImage(Bitmap bmp, Size size, InterpolationMode interp return ResizeImage(bmp, size.Width, size.Height, interpolationMode); } - public static Bitmap ResizeImageByPercentage(Bitmap bmp, float percentageWidth, float percentageHeight, InterpolationMode interpolationMode = DefaultInterpolationMode) - { - int width = (int)Math.Round(percentageWidth / 100 * bmp.Width); - int height = (int)Math.Round(percentageHeight / 100 * bmp.Height); - return ResizeImage(bmp, width, height, interpolationMode); - } - - public static Bitmap ResizeImageByPercentage(Bitmap bmp, float percentage, InterpolationMode interpolationMode = DefaultInterpolationMode) - { - return ResizeImageByPercentage(bmp, percentage, percentage, interpolationMode); - } - public static Bitmap ResizeImage(Bitmap bmp, Size size, bool allowEnlarge, bool centerImage = true) { return ResizeImage(bmp, size.Width, size.Height, allowEnlarge, centerImage); @@ -1538,9 +1526,9 @@ public static Bitmap Slice(Bitmap bmp, int minSliceHeight, int maxSliceHeight, i return bmpResult; } - public static string OpenImageFileDialog(Form form = null) + public static string OpenImageFileDialog(Form form = null, string initialDirectory = null) { - string[] images = OpenImageFileDialog(false, form); + string[] images = OpenImageFileDialog(false, form, initialDirectory); if (images != null && images.Length > 0) { @@ -1550,7 +1538,7 @@ public static string OpenImageFileDialog(Form form = null) return null; } - public static string[] OpenImageFileDialog(bool multiselect, Form form = null) + public static string[] OpenImageFileDialog(bool multiselect, Form form = null, string initialDirectory = null) { using (OpenFileDialog ofd = new OpenFileDialog()) { @@ -1559,6 +1547,11 @@ public static string[] OpenImageFileDialog(bool multiselect, Form form = null) ofd.Multiselect = multiselect; + if (!string.IsNullOrEmpty(initialDirectory)) + { + ofd.InitialDirectory = initialDirectory; + } + if (ofd.ShowDialog(form) == DialogResult.OK) { return ofd.FileNames; @@ -2050,14 +2043,30 @@ private static RotateFlipType GetRotateFlipTypeByExifOrientationData(int orienta } } - public static void SelectiveColor(Bitmap bmp, Color lightColor, Color darkColor, int threshold) + public static void SelectiveColor(Bitmap bmp, Color lightColor, Color darkColor, int paletteSize = 2) { + paletteSize = Math.Max(paletteSize, 2); + + Dictionary colors = new Dictionary(); + for (int i = 0; i < paletteSize; i++) + { + Color color = ColorHelpers.Lerp(lightColor, darkColor, (float)i / (paletteSize - 1)); + int perceivedBrightness = ColorHelpers.PerceivedBrightness(color); + if (!colors.ContainsKey(perceivedBrightness)) + { + colors.Add(perceivedBrightness, color); + } + } + using (UnsafeBitmap unsafeBitmap = new UnsafeBitmap(bmp, true)) { for (int i = 0; i < unsafeBitmap.PixelCount; i++) { ColorBgra color = unsafeBitmap.GetPixel(i); - Color newColor = ColorHelpers.PerceivedBrightness(color.ToColor()) > threshold ? lightColor : darkColor; + int perceivedBrightness = ColorHelpers.PerceivedBrightness(color.ToColor()); + KeyValuePair closest = + colors.Aggregate((current, next) => Math.Abs(current.Key - perceivedBrightness) < Math.Abs(next.Key - perceivedBrightness) ? current : next); + Color newColor = closest.Value; color.Red = newColor.R; color.Green = newColor.G; color.Blue = newColor.B; @@ -2078,5 +2087,51 @@ public static Size GetImageFileDimensions(string filePath) return Size.Empty; } + + public static InterpolationMode GetInterpolationMode(ImageInterpolationMode interpolationMode) + { + switch (interpolationMode) + { + default: + case ImageInterpolationMode.HighQualityBicubic: + return InterpolationMode.HighQualityBicubic; + case ImageInterpolationMode.Bicubic: + return InterpolationMode.Bicubic; + case ImageInterpolationMode.HighQualityBilinear: + return InterpolationMode.HighQualityBilinear; + case ImageInterpolationMode.Bilinear: + return InterpolationMode.Bilinear; + case ImageInterpolationMode.NearestNeighbor: + return InterpolationMode.NearestNeighbor; + } + } + + public static Size ApplyAspectRatio(int width, int height, Bitmap bmp) + { + int newWidth, newHeight; + + if (width == 0) + { + newWidth = (int)Math.Round((float)height / bmp.Height * bmp.Width); + newHeight = height; + } + else if (height == 0) + { + newWidth = width; + newHeight = (int)Math.Round((float)width / bmp.Width * bmp.Height); + } + else + { + newWidth = width; + newHeight = height; + } + + return new Size(newWidth, newHeight); + } + + public static Size ApplyAspectRatio(Size size, Bitmap bmp) + { + return ApplyAspectRatio(size.Width, size.Height, bmp); + } } } \ No newline at end of file diff --git a/ShareX.HelpersLib/MaxLengthStream.cs b/ShareX.HelpersLib/MaxLengthStream.cs new file mode 100644 index 000000000..c3d2ea73e --- /dev/null +++ b/ShareX.HelpersLib/MaxLengthStream.cs @@ -0,0 +1,78 @@ +#region License Information (GPL v3) + +/* + ShareX - A program that allows you to take screenshots and share any file type + Copyright (c) 2007-2020 ShareX Team + + 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 2 + 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Optionally you can also view the license at . +*/ + +#endregion License Information (GPL v3) + +using System; +using System.IO; + +namespace ShareX.HelpersLib +{ + internal sealed class MaxLengthStream : Stream + { + private readonly Stream stream; + private long length = 0L; + + public MaxLengthStream(Stream stream, long maxLength) + { + this.stream = stream ?? throw new ArgumentNullException(nameof(stream)); + MaxLength = maxLength; + } + + public long MaxLength { get; } + + public override bool CanRead => stream.CanRead; + public override bool CanSeek => false; + public override bool CanWrite => false; + public override long Length => stream.Length; + + public override long Position + { + get => stream.Position; + set => throw new NotSupportedException(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + int result = stream.Read(buffer, offset, count); + length += result; + if (length > MaxLength) + { + throw new Exception("Stream is larger than the maximum allowed size."); + } + + return result; + } + + public override void Flush() => throw new NotSupportedException(); + public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException(); + public override void SetLength(long value) => throw new NotSupportedException(); + public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException(); + + protected override void Dispose(bool disposing) + { + stream.Dispose(); + base.Dispose(disposing); + } + } +} \ No newline at end of file diff --git a/ShareX.HelpersLib/Properties/Resources.Designer.cs b/ShareX.HelpersLib/Properties/Resources.Designer.cs index eac34bfca..0f8ce532e 100644 --- a/ShareX.HelpersLib/Properties/Resources.Designer.cs +++ b/ShareX.HelpersLib/Properties/Resources.Designer.cs @@ -146,7 +146,7 @@ internal class Resources { } /// - /// Looks up a localized string similar to Add image effects / watermark. + /// Looks up a localized string similar to Add image effects. /// internal static string AfterCaptureTasks_AddImageEffects { get { @@ -744,6 +744,42 @@ internal class Resources { } } + /// + /// Looks up a localized string similar to Absolute size. + /// + internal static string DrawImageSizeMode_AbsoluteSize { + get { + return ResourceManager.GetString("DrawImageSizeMode_AbsoluteSize", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Don't resize. + /// + internal static string DrawImageSizeMode_DontResize { + get { + return ResourceManager.GetString("DrawImageSizeMode_DontResize", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Percentage of canvas. + /// + internal static string DrawImageSizeMode_PercentageOfCanvas { + get { + return ResourceManager.GetString("DrawImageSizeMode_PercentageOfCanvas", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Percentage of image. + /// + internal static string DrawImageSizeMode_PercentageOfWatermark { + get { + return ResourceManager.GetString("DrawImageSizeMode_PercentageOfWatermark", resourceCulture); + } + } + /// /// Looks up a localized string similar to Error. /// @@ -2058,51 +2094,6 @@ internal class Resources { } } - /// - /// Looks up a localized string similar to Bicubic. - /// - internal static string ImageEditorInterpolationMode_Bicubic { - get { - return ResourceManager.GetString("ImageEditorInterpolationMode_Bicubic", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Bilinear. - /// - internal static string ImageEditorInterpolationMode_Bilinear { - get { - return ResourceManager.GetString("ImageEditorInterpolationMode_Bilinear", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to High quality bicubic. - /// - internal static string ImageEditorInterpolationMode_HighQualityBicubic { - get { - return ResourceManager.GetString("ImageEditorInterpolationMode_HighQualityBicubic", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to High quality bilinear. - /// - internal static string ImageEditorInterpolationMode_HighQualityBilinear { - get { - return ResourceManager.GetString("ImageEditorInterpolationMode_HighQualityBilinear", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Nearest neighbor. - /// - internal static string ImageEditorInterpolationMode_NearestNeighbor { - get { - return ResourceManager.GetString("ImageEditorInterpolationMode_NearestNeighbor", resourceCulture); - } - } - /// /// Looks up a localized string similar to Auto size. /// @@ -2251,9 +2242,19 @@ internal class Resources { /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// - internal static System.Drawing.Bitmap LoadingSmall { + internal static System.Drawing.Bitmap LoadingSmallBlack { get { - object obj = ResourceManager.GetObject("LoadingSmall", resourceCulture); + object obj = ResourceManager.GetObject("LoadingSmallBlack", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap LoadingSmallWhite { + get { + object obj = ResourceManager.GetObject("LoadingSmallWhite", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } diff --git a/ShareX.HelpersLib/Properties/Resources.resx b/ShareX.HelpersLib/Properties/Resources.resx index b487622e4..ed2b15b05 100644 --- a/ShareX.HelpersLib/Properties/Resources.resx +++ b/ShareX.HelpersLib/Properties/Resources.resx @@ -135,9 +135,6 @@ Custom text uploader - - High quality bicubic - None @@ -477,7 +474,7 @@ Would you like to download it? Manual - Add image effects / watermark + Add image effects Delete file locally @@ -683,9 +680,6 @@ Would you like to download and install it? Screen record - - Bilinear - Browse for a sound file... @@ -710,9 +704,6 @@ Would you like to download and install it? Paste - - High quality bilinear - Forward diagonal @@ -734,9 +725,6 @@ Would you like to download and install it? Remove shape or cancel capture - - Nearest neighbor - User name @@ -746,9 +734,6 @@ Would you like to download and install it? Status: {0} - - Bicubic - Close @@ -1193,9 +1178,6 @@ Would you like to download and install it? Amazon S3 Standard-Infrequent Access - - ..\Resources\LoadingSmall.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - Random non ambiguous alphanumeric char. Repeat using {n} @@ -1250,4 +1232,22 @@ Would you like to download and install it? Amazon S3 One Zone-Infrequent Access + + ..\Resources\LoadingSmallBlack.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\LoadingSmallWhite.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Absolute size + + + Don't resize + + + Percentage of canvas + + + Percentage of image + \ No newline at end of file diff --git a/ShareX.HelpersLib/ShareX.HelpersLib.csproj b/ShareX.HelpersLib/ShareX.HelpersLib.csproj index d36e1b73c..cab96a456 100644 --- a/ShareX.HelpersLib/ShareX.HelpersLib.csproj +++ b/ShareX.HelpersLib/ShareX.HelpersLib.csproj @@ -10,7 +10,7 @@ Properties ShareX.HelpersLib ShareX.HelpersLib - v4.6.2 + v4.7.2 512 @@ -150,6 +150,7 @@ + @@ -291,6 +292,7 @@ + diff --git a/ShareX.HelpersLib/UITypeEditors/EnumDescriptionConverter.cs b/ShareX.HelpersLib/UITypeEditors/EnumDescriptionConverter.cs index d3c97da76..6a0b33c33 100644 --- a/ShareX.HelpersLib/UITypeEditors/EnumDescriptionConverter.cs +++ b/ShareX.HelpersLib/UITypeEditors/EnumDescriptionConverter.cs @@ -34,8 +34,7 @@ public class EnumDescriptionConverter : EnumConverter { private Type enumType; - public EnumDescriptionConverter(Type type) - : base(type) + public EnumDescriptionConverter(Type type) : base(type) { enumType = type; } diff --git a/ShareX.HelpersLib/UITypeEditors/EnumProperNameConverter.cs b/ShareX.HelpersLib/UITypeEditors/EnumProperNameConverter.cs new file mode 100644 index 000000000..75c07a5bb --- /dev/null +++ b/ShareX.HelpersLib/UITypeEditors/EnumProperNameConverter.cs @@ -0,0 +1,70 @@ +#region License Information (GPL v3) + +/* + ShareX - A program that allows you to take screenshots and share any file type + Copyright (c) 2007-2020 ShareX Team + + 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 2 + 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Optionally you can also view the license at . +*/ + +#endregion License Information (GPL v3) + +using System; +using System.ComponentModel; +using System.Globalization; +using System.Linq; + +namespace ShareX.HelpersLib +{ + public class EnumProperNameConverter : EnumConverter + { + private Type enumType; + + public EnumProperNameConverter(Type type) : base(type) + { + enumType = type; + } + + public override bool CanConvertTo(ITypeDescriptorContext context, Type destType) + { + return destType == typeof(string); + } + + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destType) + { + return Helpers.GetProperName(value.ToString()); + } + + public override bool CanConvertFrom(ITypeDescriptorContext context, Type srcType) + { + return srcType == typeof(string); + } + + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + foreach (Enum e in Enum.GetValues(enumType).OfType()) + { + if (Helpers.GetProperName(e.ToString()) == (string)value) + { + return e; + } + } + + return Enum.Parse(enumType, (string)value); + } + } +} \ No newline at end of file diff --git a/ShareX.HelpersLib/UITypeEditors/ImageFileNameEditor.cs b/ShareX.HelpersLib/UITypeEditors/ImageFileNameEditor.cs index c379571e7..bda6cda77 100644 --- a/ShareX.HelpersLib/UITypeEditors/ImageFileNameEditor.cs +++ b/ShareX.HelpersLib/UITypeEditors/ImageFileNameEditor.cs @@ -25,6 +25,7 @@ using System; using System.ComponentModel; +using System.IO; using System.Windows.Forms.Design; namespace ShareX.HelpersLib @@ -38,7 +39,21 @@ public override object EditValue(ITypeDescriptorContext context, IServiceProvide return base.EditValue(context, provider, value); } - string filePath = ImageHelpers.OpenImageFileDialog(); + string filePath = value as string; + string initialDirectory = null; + + if (!string.IsNullOrEmpty(filePath)) + { + filePath = Helpers.ExpandFolderVariables(filePath, true); + string directoryPath = Path.GetDirectoryName(filePath); + + if (!string.IsNullOrEmpty(directoryPath) && Directory.Exists(directoryPath)) + { + initialDirectory = directoryPath; + } + } + + filePath = ImageHelpers.OpenImageFileDialog(null, initialDirectory); if (!string.IsNullOrEmpty(filePath)) { diff --git a/ShareX.HelpersLib/ZipManager.cs b/ShareX.HelpersLib/ZipManager.cs index 0b328805a..29af26e5d 100644 --- a/ShareX.HelpersLib/ZipManager.cs +++ b/ShareX.HelpersLib/ZipManager.cs @@ -27,44 +27,48 @@ using System.Collections.Generic; using System.IO; using System.IO.Compression; +using System.Linq; namespace ShareX.HelpersLib { public static class ZipManager { - public static void Extract(string archivePath, string destination, bool retainDirectoryStructure = true, List fileFilter = null) + public static void Extract(string archivePath, string destination, bool retainDirectoryStructure = true, Func filter = null, + long maxUncompressedSize = 0) { using (ZipArchive archive = ZipFile.OpenRead(archivePath)) { + if (maxUncompressedSize > 0) + { + long totalUncompressedSize = archive.Entries.Sum(entry => entry.Length); + + if (totalUncompressedSize > maxUncompressedSize) + { + throw new Exception("Uncompressed file size of this archive is bigger than the maximum allowed file size.\r\n\r\n" + + $"Archive uncompressed file size: {totalUncompressedSize.ToSizeString()}\r\n" + + $"Maximum allowed file size: {maxUncompressedSize.ToSizeString()}"); + } + } + string fullName = Directory.CreateDirectory(Path.GetFullPath(destination)).FullName; foreach (ZipArchiveEntry entry in archive.Entries) { - string entryName = entry.Name; - - if (fileFilter != null) + if (filter != null && !filter(entry)) { - bool match = false; - - foreach (string file in fileFilter) - { - if (file.Equals(entryName, StringComparison.OrdinalIgnoreCase)) - { - match = true; - break; - } - } - - if (!match) - { - continue; - } + continue; } + string entryName; + if (retainDirectoryStructure) { entryName = entry.FullName; } + else + { + entryName = entry.Name; + } string fullPath = Path.GetFullPath(Path.Combine(fullName, entryName)); @@ -80,13 +84,37 @@ public static void Extract(string archivePath, string destination, bool retainDi else { Directory.CreateDirectory(Path.GetDirectoryName(fullPath)); - entry.ExtractToFile(fullPath, true); + ExtractToFile(entry, fullPath, true); } } } } } + private static void ExtractToFile(ZipArchiveEntry source, string destinationFileName, bool overwrite) + { + if (source == null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (destinationFileName == null) + { + throw new ArgumentNullException(nameof(destinationFileName)); + } + + FileMode fMode = overwrite ? FileMode.Create : FileMode.CreateNew; + + using (FileStream fs = new FileStream(destinationFileName, fMode, FileAccess.Write, FileShare.None, bufferSize: 0x1000, useAsync: false)) + using (Stream es = source.Open()) + using (MaxLengthStream maxLengthStream = new MaxLengthStream(es, source.Length)) + { + maxLengthStream.CopyTo(fs); + } + + File.SetLastWriteTime(destinationFileName, source.LastWriteTime.DateTime); + } + public static void Compress(string source, string archivePath, CompressionLevel compression = CompressionLevel.Optimal) { if (File.Exists(archivePath)) @@ -97,7 +125,20 @@ public static void Compress(string source, string archivePath, CompressionLevel ZipFile.CreateFromDirectory(source, archivePath, compression, false); } - public static void Compress(string archivePath, List files, string workingDirectory = "", CompressionLevel compression = CompressionLevel.Optimal) + public static void Compress(string archivePath, List files, CompressionLevel compression = CompressionLevel.Optimal) + { + Dictionary entries = new Dictionary(); + + foreach (string file in files) + { + string fileName = Path.GetFileName(file); + entries.Add(file, fileName); + } + + Compress(archivePath, entries, compression); + } + + public static void Compress(string archivePath, Dictionary files, CompressionLevel compression = CompressionLevel.Optimal) { if (File.Exists(archivePath)) { @@ -106,13 +147,14 @@ public static void Compress(string archivePath, List files, string worki using (ZipArchive archive = ZipFile.Open(archivePath, ZipArchiveMode.Update)) { - foreach (string file in files) + foreach (KeyValuePair file in files) { - string filePath = Path.Combine(workingDirectory, file); + string sourceFilePath = file.Key; - if (File.Exists(filePath)) + if (File.Exists(sourceFilePath)) { - archive.CreateEntryFromFile(filePath, file, compression); + string entryName = file.Value; + archive.CreateEntryFromFile(sourceFilePath, entryName, compression); } } } diff --git a/ShareX.HistoryLib/ShareX.HistoryLib.csproj b/ShareX.HistoryLib/ShareX.HistoryLib.csproj index de2c36ed1..f40711e51 100644 --- a/ShareX.HistoryLib/ShareX.HistoryLib.csproj +++ b/ShareX.HistoryLib/ShareX.HistoryLib.csproj @@ -10,7 +10,7 @@ Properties ShareX.HistoryLib ShareX.HistoryLib - v4.6.2 + v4.7.2 512 diff --git a/ShareX.ImageEffectsLib/Adjustments/SelectiveColor.cs b/ShareX.ImageEffectsLib/Adjustments/SelectiveColor.cs index 04f004ba9..fd6c5570f 100644 --- a/ShareX.ImageEffectsLib/Adjustments/SelectiveColor.cs +++ b/ShareX.ImageEffectsLib/Adjustments/SelectiveColor.cs @@ -39,8 +39,8 @@ internal class SelectiveColor : ImageEffect [DefaultValue(typeof(Color), "Black"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))] public Color DarkColor { get; set; } - [DefaultValue(130)] - public int Threshold { get; set; } + [DefaultValue(10)] + public int PaletteSize { get; set; } public SelectiveColor() { @@ -49,7 +49,7 @@ public SelectiveColor() public override Bitmap Apply(Bitmap bmp) { - ImageHelpers.SelectiveColor(bmp, LightColor, DarkColor, Threshold); + ImageHelpers.SelectiveColor(bmp, LightColor, DarkColor, MathHelpers.Clamp(PaletteSize, 2, 100)); return bmp; } } diff --git a/ShareX.ImageEffectsLib/Drawings/DrawImage.cs b/ShareX.ImageEffectsLib/Drawings/DrawImage.cs index 5dad1b9a2..1a0d122d1 100644 --- a/ShareX.ImageEffectsLib/Drawings/DrawImage.cs +++ b/ShareX.ImageEffectsLib/Drawings/DrawImage.cs @@ -24,31 +24,39 @@ #endregion License Information (GPL v3) using ShareX.HelpersLib; +using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Design; +using System.Drawing.Drawing2D; using System.IO; namespace ShareX.ImageEffectsLib { - [Description("Image watermark")] + [Description("Image")] public class DrawImage : ImageEffect { [DefaultValue(""), Editor(typeof(ImageFileNameEditor), typeof(UITypeEditor))] public string ImageLocation { get; set; } - [DefaultValue(ContentAlignment.BottomRight)] + [DefaultValue(ContentAlignment.BottomRight), TypeConverter(typeof(EnumProperNameConverter))] public ContentAlignment Placement { get; set; } [DefaultValue(typeof(Point), "5, 5")] public Point Offset { get; set; } - [DefaultValue(DrawImageSizeMode.DontResize), Description("How the image watermark should be rescaled, if at all.")] + [DefaultValue(DrawImageSizeMode.DontResize), Description("How the image watermark should be rescaled, if at all."), TypeConverter(typeof(EnumDescriptionConverter))] public DrawImageSizeMode SizeMode { get; set; } [DefaultValue(typeof(Size), "0, 0")] public Size Size { get; set; } + [DefaultValue(ImageInterpolationMode.HighQualityBicubic), TypeConverter(typeof(EnumProperNameConverter))] + public ImageInterpolationMode InterpolationMode { get; set; } + + [DefaultValue(CompositingMode.SourceOver), TypeConverter(typeof(EnumProperNameConverter))] + public CompositingMode CompositingMode { get; set; } + [DefaultValue(true), Description("If image watermark size bigger than source image then don't draw it.")] public bool AutoHide { get; set; } @@ -59,35 +67,43 @@ public DrawImage() public override Bitmap Apply(Bitmap bmp) { - string imageFilePath = Helpers.ExpandFolderVariables(ImageLocation); + if (SizeMode != DrawImageSizeMode.DontResize && Size.Width <= 0 && Size.Height <= 0) + { + return bmp; + } + + string imageFilePath = Helpers.ExpandFolderVariables(ImageLocation, true); if (!string.IsNullOrEmpty(imageFilePath) && File.Exists(imageFilePath)) { - using (Bitmap bmp2 = ImageHelpers.LoadImage(imageFilePath)) + using (Bitmap bmpWatermark = ImageHelpers.LoadImage(imageFilePath)) { - if (bmp2 != null) + if (bmpWatermark != null) { - // Calculate size first - Size imageSize = bmp2.Size; + Size imageSize; + if (SizeMode == DrawImageSizeMode.AbsoluteSize) { - // Use Size property - imageSize = Size; + imageSize = ImageHelpers.ApplyAspectRatio(Size, bmpWatermark); } else if (SizeMode == DrawImageSizeMode.PercentageOfWatermark) { - // Relative size (percentage of watermark) - imageSize = new Size((int)(bmp2.Width * (Size.Width / 100.0)), (int)(bmp2.Height * (Size.Height / 100.0))); + int width = (int)Math.Round(Size.Width / 100f * bmpWatermark.Width); + int height = (int)Math.Round(Size.Height / 100f * bmpWatermark.Height); + imageSize = ImageHelpers.ApplyAspectRatio(width, height, bmpWatermark); } else if (SizeMode == DrawImageSizeMode.PercentageOfCanvas) { - // Relative size (percentage of image) - imageSize = new Size((int)(bmp.Width * (Size.Width / 100.0)), (int)(bmp.Height * (Size.Height / 100.0))); + int width = (int)Math.Round(Size.Width / 100f * bmp.Width); + int height = (int)Math.Round(Size.Height / 100f * bmp.Height); + imageSize = ImageHelpers.ApplyAspectRatio(width, height, bmpWatermark); + } + else + { + imageSize = bmpWatermark.Size; } - // Place the image Point imagePosition = Helpers.GetPosition(Placement, Offset, bmp.Size, imageSize); - Rectangle imageRectangle = new Rectangle(imagePosition, imageSize); if (AutoHide && !new Rectangle(0, 0, bmp.Width, bmp.Height).Contains(imageRectangle)) @@ -97,8 +113,10 @@ public override Bitmap Apply(Bitmap bmp) using (Graphics g = Graphics.FromImage(bmp)) { - g.SetHighQuality(); - g.DrawImage(bmp2, imageRectangle); + g.InterpolationMode = ImageHelpers.GetInterpolationMode(InterpolationMode); + g.PixelOffsetMode = PixelOffsetMode.Half; + g.CompositingMode = CompositingMode; + g.DrawImage(bmpWatermark, imageRectangle); } } } diff --git a/ShareX.ImageEffectsLib/Drawings/DrawText.cs b/ShareX.ImageEffectsLib/Drawings/DrawText.cs index bf6743ba9..31227e61a 100644 --- a/ShareX.ImageEffectsLib/Drawings/DrawText.cs +++ b/ShareX.ImageEffectsLib/Drawings/DrawText.cs @@ -33,7 +33,7 @@ namespace ShareX.ImageEffectsLib { - [Description("Text watermark")] + [Description("Text")] public class DrawText : ImageEffect { [DefaultValue(ContentAlignment.BottomRight)] @@ -67,7 +67,7 @@ public Font TextFont } } - [DefaultValue(typeof(Color), "White"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))] + [DefaultValue(typeof(Color), "235, 235, 235"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))] public Color TextColor { get; set; } [DefaultValue(true)] @@ -109,7 +109,7 @@ public int CornerRadius [DefaultValue(true)] public bool DrawBackground { get; set; } - [DefaultValue(typeof(Color), "10, 110, 230"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))] + [DefaultValue(typeof(Color), "42, 47, 56"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))] public Color BackgroundColor { get; set; } [DefaultValue(true)] @@ -118,7 +118,7 @@ public int CornerRadius [DefaultValue(LinearGradientMode.Vertical)] public LinearGradientMode GradientType { get; set; } - [DefaultValue(typeof(Color), "0, 30, 80"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))] + [DefaultValue(typeof(Color), "28, 32, 38"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))] public Color BackgroundColor2 { get; set; } [DefaultValue(false)] diff --git a/ShareX.ImageEffectsLib/Enums.cs b/ShareX.ImageEffectsLib/Enums.cs index 6dd69f4ce..1fe5cc1c2 100644 --- a/ShareX.ImageEffectsLib/Enums.cs +++ b/ShareX.ImageEffectsLib/Enums.cs @@ -43,7 +43,7 @@ public enum ResizeMode ResizeIfSmaller } - public enum DrawImageSizeMode + public enum DrawImageSizeMode // Localized { DontResize, AbsoluteSize, diff --git a/ShareX.ImageEffectsLib/Filters/RGBSplit.cs b/ShareX.ImageEffectsLib/Filters/RGBSplit.cs new file mode 100644 index 000000000..1c77038ac --- /dev/null +++ b/ShareX.ImageEffectsLib/Filters/RGBSplit.cs @@ -0,0 +1,72 @@ +#region License Information (GPL v3) + +/* + ShareX - A program that allows you to take screenshots and share any file type + Copyright (c) 2007-2020 ShareX Team + + 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 2 + 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Optionally you can also view the license at . +*/ + +#endregion License Information (GPL v3) + +using ShareX.HelpersLib; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Imaging; + +namespace ShareX.ImageEffectsLib +{ + [Description("RGB split")] + internal class RGBSplit : ImageEffect + { + [DefaultValue(typeof(Point), "-5, 0")] + public Point OffsetRed { get; set; } = new Point(-5, 0); + + [DefaultValue(typeof(Point), "0, 0")] + public Point OffsetGreen { get; set; } + + [DefaultValue(typeof(Point), "5, 0")] + public Point OffsetBlue { get; set; } = new Point(5, 0); + + public override Bitmap Apply(Bitmap bmp) + { + Bitmap bmpResult = bmp.CreateEmptyBitmap(); + + using (UnsafeBitmap source = new UnsafeBitmap(bmp, true, ImageLockMode.ReadOnly)) + using (UnsafeBitmap dest = new UnsafeBitmap(bmpResult, true, ImageLockMode.WriteOnly)) + { + int right = source.Width - 1; + int bottom = source.Height - 1; + + for (int y = 0; y < source.Height; y++) + { + for (int x = 0; x < source.Width; x++) + { + ColorBgra colorR = source.GetPixel(MathHelpers.Clamp(x - OffsetRed.X, 0, right), MathHelpers.Clamp(y - OffsetRed.Y, 0, bottom)); + ColorBgra colorG = source.GetPixel(MathHelpers.Clamp(x - OffsetGreen.X, 0, right), MathHelpers.Clamp(y - OffsetGreen.Y, 0, bottom)); + ColorBgra colorB = source.GetPixel(MathHelpers.Clamp(x - OffsetBlue.X, 0, right), MathHelpers.Clamp(y - OffsetBlue.Y, 0, bottom)); + ColorBgra shiftedColor = new ColorBgra((byte)(colorB.Blue * colorB.Alpha / 255), (byte)(colorG.Green * colorG.Alpha / 255), + (byte)(colorR.Red * colorR.Alpha / 255), (byte)((colorR.Alpha + colorG.Alpha + colorB.Alpha) / 3)); + dest.SetPixel(x, y, shiftedColor); + } + } + } + + return bmpResult; + } + } +} \ No newline at end of file diff --git a/ShareX.ImageEffectsLib/ImageEffectPackager.cs b/ShareX.ImageEffectsLib/ImageEffectPackager.cs new file mode 100644 index 000000000..90afbe9b0 --- /dev/null +++ b/ShareX.ImageEffectsLib/ImageEffectPackager.cs @@ -0,0 +1,108 @@ +#region License Information (GPL v3) + +/* + ShareX - A program that allows you to take screenshots and share any file type + Copyright (c) 2007-2020 ShareX Team + + 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 2 + 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Optionally you can also view the license at . +*/ + +#endregion License Information (GPL v3) + +using ShareX.HelpersLib; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace ShareX.ImageEffectsLib +{ + public static class ImageEffectPackager + { + private const string ConfigFileName = "Config.json"; + + public static string Package(string outputFilePath, string configJson, string assetsFolderPath) + { + if (!string.IsNullOrEmpty(outputFilePath)) + { + string outputFolder = Path.GetDirectoryName(outputFilePath); + Helpers.CreateDirectory(outputFolder); + + string configFilePath = Path.Combine(outputFolder, ConfigFileName); + File.WriteAllText(configFilePath, configJson, Encoding.UTF8); + + Dictionary files = new Dictionary(); + files.Add(configFilePath, ConfigFileName); + + if (!string.IsNullOrEmpty(assetsFolderPath) && Directory.Exists(assetsFolderPath)) + { + string parentFolderPath = Directory.GetParent(assetsFolderPath).FullName; + int entryNamePosition = parentFolderPath.Length + 1; + + foreach (string assetPath in Directory.EnumerateFiles(assetsFolderPath, "*.*", SearchOption.AllDirectories).Where(x => Helpers.IsImageFile(x))) + { + string entryName = assetPath.Substring(entryNamePosition); + files.Add(assetPath, entryName); + } + } + + try + { + ZipManager.Compress(outputFilePath, files); + } + finally + { + File.Delete(configFilePath); + } + + return outputFilePath; + } + + return null; + } + + public static string ExtractPackage(string packageFilePath, string destination) + { + string configJson = null; + + if (!string.IsNullOrEmpty(packageFilePath) && File.Exists(packageFilePath) && !string.IsNullOrEmpty(destination)) + { + ZipManager.Extract(packageFilePath, destination, true, entry => + { + if (Helpers.IsImageFile(entry.Name)) + { + return true; + } + + if (configJson == null && entry.FullName.Equals(ConfigFileName, StringComparison.OrdinalIgnoreCase)) + { + using (Stream stream = entry.Open()) + using (StreamReader streamReader = new StreamReader(stream, Encoding.UTF8)) + { + configJson = streamReader.ReadToEnd(); + } + } + + return false; + }, 20_000_000); + } + + return configJson; + } + } +} \ No newline at end of file diff --git a/ShareX.ImageEffectsLib/ImageEffectPackagerForm.cs b/ShareX.ImageEffectsLib/ImageEffectPackagerForm.cs new file mode 100644 index 000000000..7691499de --- /dev/null +++ b/ShareX.ImageEffectsLib/ImageEffectPackagerForm.cs @@ -0,0 +1,114 @@ +#region License Information (GPL v3) + +/* + ShareX - A program that allows you to take screenshots and share any file type + Copyright (c) 2007-2020 ShareX Team + + 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 2 + 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Optionally you can also view the license at . +*/ + +#endregion License Information (GPL v3) + +using ShareX.HelpersLib; +using System; +using System.IO; +using System.Windows.Forms; + +namespace ShareX.ImageEffectsLib +{ + public partial class ImageEffectPackagerForm : Form + { + public string ImageEffectJson { get; private set; } + public string ImageEffectName { get; private set; } + public string ShareXImageEffectsFolderPath { get; private set; } + public string AssetsFolderPath { get; set; } + public string PackageFilePath { get; set; } + + public ImageEffectPackagerForm(string json, string name, string imageEffectsFolderPath) + { + ImageEffectJson = json; + ImageEffectName = name; + ShareXImageEffectsFolderPath = imageEffectsFolderPath; + + InitializeComponent(); + ShareXResources.ApplyTheme(this); + + AssetsFolderPath = Path.Combine(ShareXImageEffectsFolderPath, ImageEffectName); + txtAssetsFolderPath.Text = AssetsFolderPath; + PackageFilePath = AssetsFolderPath + ".sxie"; + txtPackageFilePath.Text = PackageFilePath; + } + + private void txtAssetsFolderPath_TextChanged(object sender, EventArgs e) + { + AssetsFolderPath = txtAssetsFolderPath.Text; + } + + private void btnAssetsFolderPathBrowse_Click(object sender, EventArgs e) + { + Helpers.BrowseFolder(txtAssetsFolderPath, ShareXImageEffectsFolderPath); + } + + private void txtPackageFilePath_TextChanged(object sender, EventArgs e) + { + PackageFilePath = txtPackageFilePath.Text; + } + + private void btnPackageFilePathBrowse_Click(object sender, EventArgs e) + { + using (SaveFileDialog sfd = new SaveFileDialog()) + { + sfd.DefaultExt = "sxie"; + sfd.FileName = ImageEffectName + ".sxie"; + sfd.Filter = "ShareX image effect (*.sxie)|*.sxie"; + sfd.InitialDirectory = ShareXImageEffectsFolderPath; + + if (sfd.ShowDialog() == DialogResult.OK) + { + txtPackageFilePath.Text = sfd.FileName; + } + } + } + + private void btnPackage_Click(object sender, EventArgs e) + { + try + { + if (!string.IsNullOrEmpty(AssetsFolderPath) && !AssetsFolderPath.StartsWith(ShareXImageEffectsFolderPath + "\\", StringComparison.OrdinalIgnoreCase)) + { + // TODO: Translate + MessageBox.Show("Assets folder must be inside ShareX image effects folder.", "ShareX - " + "Invalid assets folder path", + MessageBoxButtons.OK, MessageBoxIcon.Warning); + } // TODO: Translate + else if (!File.Exists(PackageFilePath) || MessageBox.Show("Package with this file name already exists.\r\nWould you like to overwrite it?", "ShareX", + MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + string outputFilePath = ImageEffectPackager.Package(PackageFilePath, ImageEffectJson, AssetsFolderPath); + + if (!string.IsNullOrEmpty(outputFilePath) && File.Exists(outputFilePath)) + { + Helpers.OpenFolderWithFile(outputFilePath); + } + } + } + catch (Exception ex) + { + ex.ShowError(); + } + } + } +} \ No newline at end of file diff --git a/ShareX.ImageEffectsLib/ImageEffectsForm.cs b/ShareX.ImageEffectsLib/ImageEffectsForm.cs index 646b6b13f..3784daf4c 100644 --- a/ShareX.ImageEffectsLib/ImageEffectsForm.cs +++ b/ShareX.ImageEffectsLib/ImageEffectsForm.cs @@ -137,6 +137,7 @@ private void AddAllEffectsToContextMenu() typeof(Outline), typeof(Pixelate), typeof(Reflection), + typeof(RGBSplit), typeof(Shadow), typeof(Sharpen), typeof(Slice), diff --git a/ShareX.ImageEffectsLib/Manipulations/Resize.cs b/ShareX.ImageEffectsLib/Manipulations/Resize.cs index 617642320..6bd50b733 100644 --- a/ShareX.ImageEffectsLib/Manipulations/Resize.cs +++ b/ShareX.ImageEffectsLib/Manipulations/Resize.cs @@ -58,16 +58,15 @@ public override Bitmap Apply(Bitmap bmp) return bmp; } - int width = Width <= 0 ? (int)((float)Height / bmp.Height * bmp.Width) : Width; - int height = Height <= 0 ? (int)((float)Width / bmp.Width * bmp.Height) : Height; + Size size = ImageHelpers.ApplyAspectRatio(Width, Height, bmp); - if ((Mode == ResizeMode.ResizeIfBigger && bmp.Width <= width && bmp.Height <= height) || - (Mode == ResizeMode.ResizeIfSmaller && bmp.Width >= width && bmp.Height >= height)) + if ((Mode == ResizeMode.ResizeIfBigger && bmp.Width <= size.Width && bmp.Height <= size.Height) || + (Mode == ResizeMode.ResizeIfSmaller && bmp.Width >= size.Width && bmp.Height >= size.Height)) { return bmp; } - return ImageHelpers.ResizeImage(bmp, width, height); + return ImageHelpers.ResizeImage(bmp, size); } } } \ No newline at end of file diff --git a/ShareX.ImageEffectsLib/Manipulations/Scale.cs b/ShareX.ImageEffectsLib/Manipulations/Scale.cs index f15a6d410..7e1ced8a6 100644 --- a/ShareX.ImageEffectsLib/Manipulations/Scale.cs +++ b/ShareX.ImageEffectsLib/Manipulations/Scale.cs @@ -24,6 +24,7 @@ #endregion License Information (GPL v3) using ShareX.HelpersLib; +using System; using System.ComponentModel; using System.Drawing; @@ -49,10 +50,11 @@ public override Bitmap Apply(Bitmap bmp) return bmp; } - float widthPercentage = WidthPercentage <= 0 ? HeightPercentage : WidthPercentage; - float heightPercentage = HeightPercentage <= 0 ? WidthPercentage : HeightPercentage; + int width = (int)Math.Round(WidthPercentage / 100 * bmp.Width); + int height = (int)Math.Round(HeightPercentage / 100 * bmp.Height); + Size size = ImageHelpers.ApplyAspectRatio(width, height, bmp); - return ImageHelpers.ResizeImageByPercentage(bmp, widthPercentage, heightPercentage); + return ImageHelpers.ResizeImage(bmp, size); } } } \ No newline at end of file diff --git a/ShareX.ImageEffectsLib/Properties/Resources.Designer.cs b/ShareX.ImageEffectsLib/Properties/Resources.Designer.cs index ef998d0d8..871af8190 100644 --- a/ShareX.ImageEffectsLib/Properties/Resources.Designer.cs +++ b/ShareX.ImageEffectsLib/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace ShareX.ImageEffectsLib.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/ShareX.ImageEffectsLib/ShareX.ImageEffectsLib.csproj b/ShareX.ImageEffectsLib/ShareX.ImageEffectsLib.csproj index 9388f7e6d..5625bae11 100644 --- a/ShareX.ImageEffectsLib/ShareX.ImageEffectsLib.csproj +++ b/ShareX.ImageEffectsLib/ShareX.ImageEffectsLib.csproj @@ -10,7 +10,7 @@ Properties ShareX.ImageEffectsLib ShareX.ImageEffectsLib - v4.6.2 + v4.7.2 512 @@ -118,6 +118,7 @@ + diff --git a/ShareX.IndexerLib/Forms/DirectoryIndexerForm.Designer.cs b/ShareX.IndexerLib/Forms/DirectoryIndexerForm.Designer.cs index 1b73a0dd3..55801e24d 100644 --- a/ShareX.IndexerLib/Forms/DirectoryIndexerForm.Designer.cs +++ b/ShareX.IndexerLib/Forms/DirectoryIndexerForm.Designer.cs @@ -29,7 +29,6 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DirectoryIndexerForm)); - this.wbPreview = new System.Windows.Forms.WebBrowser(); this.txtFolderPath = new System.Windows.Forms.TextBox(); this.btnBrowseFolder = new System.Windows.Forms.Button(); this.btnIndexFolder = new System.Windows.Forms.Button(); @@ -39,16 +38,13 @@ private void InitializeComponent() this.txtPreview = new System.Windows.Forms.TextBox(); this.tpSettings = new System.Windows.Forms.TabPage(); this.pgSettings = new System.Windows.Forms.PropertyGrid(); + this.btnSaveAs = new System.Windows.Forms.Button(); + this.wbPreview = new System.Windows.Forms.WebBrowser(); this.tcMain.SuspendLayout(); this.tpPreview.SuspendLayout(); this.tpSettings.SuspendLayout(); this.SuspendLayout(); // - // wbPreview - // - resources.ApplyResources(this.wbPreview, "wbPreview"); - this.wbPreview.Name = "wbPreview"; - // // txtFolderPath // resources.ApplyResources(this.txtFolderPath, "txtFolderPath"); @@ -112,11 +108,24 @@ private void InitializeComponent() this.pgSettings.PropertySort = System.Windows.Forms.PropertySort.Categorized; this.pgSettings.ToolbarVisible = false; // + // btnSaveAs + // + resources.ApplyResources(this.btnSaveAs, "btnSaveAs"); + this.btnSaveAs.Name = "btnSaveAs"; + this.btnSaveAs.UseVisualStyleBackColor = true; + this.btnSaveAs.Click += new System.EventHandler(this.btnSaveAs_Click); + // + // wbPreview + // + resources.ApplyResources(this.wbPreview, "wbPreview"); + this.wbPreview.Name = "wbPreview"; + // // DirectoryIndexerForm // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.SystemColors.Window; + this.Controls.Add(this.btnSaveAs); this.Controls.Add(this.tcMain); this.Controls.Add(this.btnUpload); this.Controls.Add(this.btnIndexFolder); @@ -145,5 +154,6 @@ private void InitializeComponent() private System.Windows.Forms.PropertyGrid pgSettings; private System.Windows.Forms.TabPage tpPreview; private System.Windows.Forms.TextBox txtPreview; + private System.Windows.Forms.Button btnSaveAs; } } \ No newline at end of file diff --git a/ShareX.IndexerLib/Forms/DirectoryIndexerForm.cs b/ShareX.IndexerLib/Forms/DirectoryIndexerForm.cs index 372efdd51..31200aa52 100644 --- a/ShareX.IndexerLib/Forms/DirectoryIndexerForm.cs +++ b/ShareX.IndexerLib/Forms/DirectoryIndexerForm.cs @@ -26,6 +26,7 @@ using ShareX.HelpersLib; using System; using System.IO; +using System.Text; using System.Threading.Tasks; using System.Windows.Forms; @@ -84,6 +85,7 @@ private async Task IndexFolder() { btnIndexFolder.Enabled = false; btnUpload.Enabled = false; + btnSaveAs.Enabled = false; await Task.Run(() => { @@ -113,6 +115,7 @@ private async Task IndexFolder() } btnIndexFolder.Enabled = true; + btnSaveAs.Enabled = true; } } } @@ -133,5 +136,30 @@ protected void OnUploadRequested(string source) UploadRequested(source); } } + + private void btnSaveAs_Click(object sender, EventArgs e) + { + if (!string.IsNullOrEmpty(Source)) + { + using (SaveFileDialog sfd = new SaveFileDialog()) + { + string indexType = Settings.Output.ToString().ToLower(); + sfd.FileName = "Index for " + Path.GetFileNameWithoutExtension(txtFolderPath.Text); + sfd.DefaultExt = indexType; + sfd.Filter = string.Format("*.{0}|*.{0}|All files (*.*)|*.*", indexType); + + if (!string.IsNullOrEmpty(HelpersOptions.LastSaveDirectory) && Directory.Exists(HelpersOptions.LastSaveDirectory)) + { + sfd.InitialDirectory = HelpersOptions.LastSaveDirectory; + } + + if (sfd.ShowDialog() == DialogResult.OK) + { + File.WriteAllText(sfd.FileName, Source, Encoding.UTF8); + Close(); + } + } + } + } } } \ No newline at end of file diff --git a/ShareX.IndexerLib/Forms/DirectoryIndexerForm.resx b/ShareX.IndexerLib/Forms/DirectoryIndexerForm.resx index 9196f6792..535b1e1c8 100644 --- a/ShareX.IndexerLib/Forms/DirectoryIndexerForm.resx +++ b/ShareX.IndexerLib/Forms/DirectoryIndexerForm.resx @@ -118,44 +118,17 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Fill - - - - 0, 0 - - - 20, 20 - - - 860, 564 - - - - 0 - - - wbPreview - - - System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tpPreview - - - 1 - Top, Left, Right + 192, 8 682, 20 + 2 @@ -169,7 +142,10 @@ $this - 4 + 5 + + + NoControl 8, 7 @@ -193,16 +169,19 @@ $this - 3 + 4 False + + NoControl + 8, 32 - 344, 23 + 294, 23 3 @@ -220,16 +199,19 @@ $this - 2 + 3 False + + NoControl + - 360, 32 + 308, 32 - 344, 23 + 276, 23 0 @@ -247,11 +229,104 @@ $this - 1 + 2 Top, Bottom, Left, Right + + tpPreview + + + System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tcMain + + + 0 + + + tpSettings + + + System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tcMain + + + 1 + + + 8, 64 + + + 868, 590 + + + 4 + + + tcMain + + + System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 1 + + + txtPreview + + + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tpPreview + + + 0 + + + wbPreview + + + System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tpPreview + + + 1 + + + 4, 22 + + + 860, 564 + + + 1 + + + Preview + + + tpPreview + + + System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tcMain + + + 0 + Fill @@ -282,42 +357,6 @@ 0 - - 4, 22 - - - 860, 564 - - - 1 - - - Preview - - - tpPreview - - - System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tcMain - - - 0 - - - Fill - - - 0, 0 - - - 860, 564 - - - 0 - pgSettings @@ -354,27 +393,87 @@ 1 - - 8, 64 + + Fill - - 868, 590 + + 0, 0 - - 4 + + 860, 564 - - tcMain + + 0 - - System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + pgSettings - + + System.Windows.Forms.PropertyGrid, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tpSettings + + + 0 + + + False + + + NoControl + + + 590, 32 + + + 284, 23 + + + 5 + + + Save as and close this window... + + + btnSaveAs + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + $this - + 0 + + Fill + + + 0, 0 + + + 20, 20 + + + 860, 564 + + + 0 + + + wbPreview + + + System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tpPreview + + + 1 + True @@ -384,6 +483,9 @@ 884, 661 + + NoControl + CenterScreen diff --git a/ShareX.IndexerLib/Properties/Resources.Designer.cs b/ShareX.IndexerLib/Properties/Resources.Designer.cs index 2b3308ffe..919d9d90e 100644 --- a/ShareX.IndexerLib/Properties/Resources.Designer.cs +++ b/ShareX.IndexerLib/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace ShareX.IndexerLib.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -90,8 +90,7 @@ internal class Resources { /// border-top-right-radius: 5px; /// padding: 4px 0px 4px 10px; /// margin: 0px 10px -10px 10px; - /// color: #FFFFFF; - /// font-family: Aria [rest of string was truncated]";. + /// color: # [rest of string was truncated]";. /// internal static string IndexerDefault { get { diff --git a/ShareX.IndexerLib/ShareX.IndexerLib.csproj b/ShareX.IndexerLib/ShareX.IndexerLib.csproj index 4b46c0f67..0b3ee4bdc 100644 --- a/ShareX.IndexerLib/ShareX.IndexerLib.csproj +++ b/ShareX.IndexerLib/ShareX.IndexerLib.csproj @@ -9,7 +9,7 @@ Properties ShareX.IndexerLib ShareX.IndexerLib - v4.6.2 + v4.7.2 512 diff --git a/ShareX.MediaLib/Properties/Resources.Designer.cs b/ShareX.MediaLib/Properties/Resources.Designer.cs index e5933c0eb..008a37481 100644 --- a/ShareX.MediaLib/Properties/Resources.Designer.cs +++ b/ShareX.MediaLib/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace ShareX.MediaLib.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/ShareX.MediaLib/ShareX.MediaLib.csproj b/ShareX.MediaLib/ShareX.MediaLib.csproj index d5e2aa3fc..40ebb4d38 100644 --- a/ShareX.MediaLib/ShareX.MediaLib.csproj +++ b/ShareX.MediaLib/ShareX.MediaLib.csproj @@ -9,7 +9,7 @@ Properties ShareX.MediaLib ShareX.MediaLib - v4.6.2 + v4.7.2 512 diff --git a/ShareX.NativeMessagingHost/ShareX.NativeMessagingHost.csproj b/ShareX.NativeMessagingHost/ShareX.NativeMessagingHost.csproj index d4d602ab0..c1180ab6f 100644 --- a/ShareX.NativeMessagingHost/ShareX.NativeMessagingHost.csproj +++ b/ShareX.NativeMessagingHost/ShareX.NativeMessagingHost.csproj @@ -9,7 +9,7 @@ Properties ShareX.NativeMessagingHost ShareX_NativeMessagingHost - v4.6.2 + v4.7.2 512 diff --git a/ShareX.NativeMessagingHost/app.config b/ShareX.NativeMessagingHost/app.config index b972e1946..8f60dcb21 100644 --- a/ShareX.NativeMessagingHost/app.config +++ b/ShareX.NativeMessagingHost/app.config @@ -1,3 +1,6 @@ - \ No newline at end of file + + + + \ No newline at end of file diff --git a/ShareX.ScreenCaptureLib/Forms/RegionCaptureForm.cs b/ShareX.ScreenCaptureLib/Forms/RegionCaptureForm.cs index 9b3811639..6a16d1b89 100644 --- a/ShareX.ScreenCaptureLib/Forms/RegionCaptureForm.cs +++ b/ShareX.ScreenCaptureLib/Forms/RegionCaptureForm.cs @@ -339,7 +339,7 @@ internal void InitBackground(Bitmap canvas, bool centerCanvas = true) { DimmedCanvas?.Dispose(); DimmedCanvas = (Bitmap)Canvas.Clone(); - + using (Graphics g = Graphics.FromImage(DimmedCanvas)) using (Brush brush = new SolidBrush(Color.FromArgb(30, Color.Black))) { @@ -841,7 +841,7 @@ private void Draw(Graphics g) { if (Mode == RegionCaptureMode.Ruler) { - using (SolidBrush brush = new SolidBrush(Color.FromArgb(100, 255, 255, 255))) + using (SolidBrush brush = new SolidBrush(Color.FromArgb(50, 255, 255, 255))) { g.FillRectangle(brush, ShapeManager.CurrentRectangle); } @@ -1032,20 +1032,22 @@ private void DrawBottomTipAnimation(Graphics g, TextAnimation textAnimation) DrawTextAnimation(g, textAnimation, textRectangle, padding); } - internal string GetAreaText(Rectangle area) + internal string GetAreaText(Rectangle rect) { if (IsEditorMode) { - area = new Rectangle(area.X - CanvasRectangle.X, area.Y - CanvasRectangle.Y, area.Width, area.Height); + rect = new Rectangle(rect.X - CanvasRectangle.X, rect.Y - CanvasRectangle.Y, rect.Width, rect.Height); } else if (Mode == RegionCaptureMode.Ruler) { - Point endPos = new Point(area.Right - 1, area.Bottom - 1); - return string.Format(Resources.RectangleRegion_GetRulerText_Ruler_info, area.X, area.Y, endPos.X, endPos.Y, - area.Width, area.Height, MathHelpers.Distance(area.Location, endPos), MathHelpers.LookAtDegree(area.Location, endPos)); + Point endLocation = new Point(rect.Right - 1, rect.Bottom - 1); + string text = $"X: {rect.X} | Y: {rect.Y} | Right: {endLocation.X} | Bottom: {endLocation.Y}\r\n" + + $"Width: {rect.Width} px | Height: {rect.Height} px | Area: {rect.Area()} px | Perimeter: {rect.Perimeter()} px\r\n" + + $"Distance: {MathHelpers.Distance(rect.Location, endLocation):0.00} px | Angle: {MathHelpers.LookAtDegree(rect.Location, endLocation):0.00}°"; + return text; } - return string.Format(Resources.RectangleRegion_GetAreaText_Area, area.X, area.Y, area.Width, area.Height); + return string.Format(Resources.RectangleRegion_GetAreaText_Area, rect.X, rect.Y, rect.Width, rect.Height); } private string GetInfoText() diff --git a/ShareX.ScreenCaptureLib/Properties/Resources.Designer.cs b/ShareX.ScreenCaptureLib/Properties/Resources.Designer.cs index 430548db2..d4bb52e5f 100644 --- a/ShareX.ScreenCaptureLib/Properties/Resources.Designer.cs +++ b/ShareX.ScreenCaptureLib/Properties/Resources.Designer.cs @@ -1107,17 +1107,6 @@ internal class Resources { } } - /// - /// Looks up a localized string similar to X: {0} / Y: {1} / X2: {2} / Y2: {3} - ///Width: {4} px / Height: {5} px - ///Distance: {6:0.00} px / Angle: {7:0.00}°. - /// - internal static string RectangleRegion_GetRulerText_Ruler_info { - get { - return ResourceManager.GetString("RectangleRegion_GetRulerText_Ruler_info", resourceCulture); - } - } - /// /// Looks up a localized string similar to Rectangle capture transparent. /// diff --git a/ShareX.ScreenCaptureLib/Properties/Resources.resx b/ShareX.ScreenCaptureLib/Properties/Resources.resx index fe97e8104..4173c4c0d 100644 --- a/ShareX.ScreenCaptureLib/Properties/Resources.resx +++ b/ShareX.ScreenCaptureLib/Properties/Resources.resx @@ -139,11 +139,6 @@ ..\Resources\image-resize.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - X: {0} / Y: {1} / X2: {2} / Y2: {3} -Width: {4} px / Height: {5} px -Distance: {6:0.00} px / Angle: {7:0.00}° - ..\Resources\arrow-circle-135-left.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/ShareX.ScreenCaptureLib/RegionCaptureTasks.cs b/ShareX.ScreenCaptureLib/RegionCaptureTasks.cs index d7997ccf6..348ccbbaf 100644 --- a/ShareX.ScreenCaptureLib/RegionCaptureTasks.cs +++ b/ShareX.ScreenCaptureLib/RegionCaptureTasks.cs @@ -166,6 +166,7 @@ public static void ShowScreenRuler(RegionCaptureOptions options) { RegionCaptureOptions newOptions = GetRegionCaptureOptions(options); newOptions.QuickCrop = false; + newOptions.UseLightResizeNodes = true; using (RegionCaptureForm form = new RegionCaptureForm(RegionCaptureMode.Ruler, newOptions)) { diff --git a/ShareX.ScreenCaptureLib/ShareX.ScreenCaptureLib.csproj b/ShareX.ScreenCaptureLib/ShareX.ScreenCaptureLib.csproj index 09071f524..b5aaaf990 100644 --- a/ShareX.ScreenCaptureLib/ShareX.ScreenCaptureLib.csproj +++ b/ShareX.ScreenCaptureLib/ShareX.ScreenCaptureLib.csproj @@ -10,7 +10,7 @@ Properties ShareX.ScreenCaptureLib ShareX.ScreenCaptureLib - v4.6.2 + v4.7.2 512 diff --git a/ShareX.Setup/InnoSetup/ShareX-setup.iss b/ShareX.Setup/InnoSetup/ShareX-setup.iss index f600f142a..9ce7c0e0e 100644 --- a/ShareX.Setup/InnoSetup/ShareX-setup.iss +++ b/ShareX.Setup/InnoSetup/ShareX-setup.iss @@ -106,6 +106,8 @@ Root: "HKCU"; Subkey: "Software\Classes\*\shell\{#MyAppName}"; Flags: dontcreate Root: "HKCU"; Subkey: "Software\Classes\Directory\shell\{#MyAppName}"; Flags: dontcreatekey uninsdeletekey Root: "HKCU"; Subkey: "Software\Classes\.sxcu"; Flags: dontcreatekey uninsdeletekey Root: "HKCU"; Subkey: "Software\Classes\ShareX.sxcu"; Flags: dontcreatekey uninsdeletekey +Root: "HKCU"; Subkey: "Software\Classes\.sxie"; Flags: dontcreatekey uninsdeletekey +Root: "HKCU"; Subkey: "Software\Classes\ShareX.sxie"; Flags: dontcreatekey uninsdeletekey Root: "HKCU"; Subkey: "Software\Classes\SystemFileAssociations\image\shell\ShareXImageEditor"; Flags: dontcreatekey uninsdeletekey [CustomMessages] diff --git a/ShareX.Setup/ShareX.Setup.csproj b/ShareX.Setup/ShareX.Setup.csproj index a2371671b..96805e8e4 100644 --- a/ShareX.Setup/ShareX.Setup.csproj +++ b/ShareX.Setup/ShareX.Setup.csproj @@ -9,7 +9,7 @@ Properties ShareX.Setup ShareX.Setup - v4.6.2 + v4.7.2 512 diff --git a/ShareX.Setup/WindowsStore/AppxManifest.xml b/ShareX.Setup/WindowsStore/AppxManifest.xml index 5373b5fe0..04940349c 100644 --- a/ShareX.Setup/WindowsStore/AppxManifest.xml +++ b/ShareX.Setup/WindowsStore/AppxManifest.xml @@ -43,6 +43,14 @@ + + + ShareX image effect + + .sxie + + + diff --git a/ShareX.Setup/app.config b/ShareX.Setup/app.config index adcd8c5a5..8f60dcb21 100644 --- a/ShareX.Setup/app.config +++ b/ShareX.Setup/app.config @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/ShareX.Steam/ShareX.Steam.csproj b/ShareX.Steam/ShareX.Steam.csproj index e1697087b..74b788cdf 100644 --- a/ShareX.Steam/ShareX.Steam.csproj +++ b/ShareX.Steam/ShareX.Steam.csproj @@ -9,7 +9,7 @@ Properties ShareX.Steam ShareX_Launcher - v4.6.2 + v4.7.2 512 diff --git a/ShareX.Steam/app.config b/ShareX.Steam/app.config index b972e1946..8f60dcb21 100644 --- a/ShareX.Steam/app.config +++ b/ShareX.Steam/app.config @@ -1,3 +1,6 @@ - \ No newline at end of file + + + + \ No newline at end of file diff --git a/ShareX.UploadersLib/ShareX.UploadersLib.csproj b/ShareX.UploadersLib/ShareX.UploadersLib.csproj index 9f608cc7c..647f15ceb 100644 --- a/ShareX.UploadersLib/ShareX.UploadersLib.csproj +++ b/ShareX.UploadersLib/ShareX.UploadersLib.csproj @@ -10,7 +10,7 @@ Properties ShareX.UploadersLib ShareX.UploadersLib - v4.6.2 + v4.7.2 512 false diff --git a/ShareX/ShareX.csproj b/ShareX/ShareX.csproj index 4bb4ddc0e..3e19f4183 100644 --- a/ShareX/ShareX.csproj +++ b/ShareX/ShareX.csproj @@ -10,7 +10,7 @@ Properties ShareX ShareX - v4.6.2 + v4.7.2 512 ShareX_Icon.ico diff --git a/ShareX/TaskHelpers.cs b/ShareX/TaskHelpers.cs index bdad016f7..dadc7386e 100644 --- a/ShareX/TaskHelpers.cs +++ b/ShareX/TaskHelpers.cs @@ -578,7 +578,7 @@ public static void PrintImage(Image img) } } - public static Bitmap AddImageEffects(Bitmap bmp, TaskSettingsImage taskSettingsImage) + public static Bitmap ApplyImageEffects(Bitmap bmp, TaskSettingsImage taskSettingsImage) { if (bmp != null && !bmp.PixelFormat.HasFlag(PixelFormat.Indexed)) { @@ -1061,6 +1061,28 @@ public static void OpenImageEffects(TaskSettings taskSettings = null) } } + public static ImageEffectsForm OpenImageEffectsSingleton(TaskSettings taskSettings = null) + { + if (taskSettings == null) taskSettings = Program.DefaultTaskSettings; + + bool firstInstance = !ImageEffectsForm.IsInstanceActive; + + ImageEffectsForm imageEffectsForm = ImageEffectsForm.GetFormInstance(taskSettings.ImageSettings.ImageEffectPresets, + taskSettings.ImageSettings.SelectedImageEffectPreset); + + if (firstInstance) + { + imageEffectsForm.FormClosed += (sender, e) => taskSettings.ImageSettings.SelectedImageEffectPreset = imageEffectsForm.SelectedPresetIndex; + imageEffectsForm.Show(); + } + else + { + imageEffectsForm.ForceActivate(); + } + + return imageEffectsForm; + } + public static void OpenMonitorTest() { using (MonitorTestForm monitorTestForm = new MonitorTestForm()) @@ -1566,7 +1588,7 @@ public static Screenshot GetScreenshot(TaskSettings taskSettings = null) return screenshot; } - public static void AddCustomUploader(string filePath) + public static void ImportCustomUploader(string filePath) { if (Program.UploadersConfig != null) { @@ -1595,7 +1617,7 @@ public static void AddCustomUploader(string filePath) if (cui.DestinationType.HasFlag(CustomUploaderDestinationType.TextUploader)) destinations.Add("texts"); if (cui.DestinationType.HasFlag(CustomUploaderDestinationType.FileUploader)) destinations.Add("files"); if (cui.DestinationType.HasFlag(CustomUploaderDestinationType.URLShortener) || - (cui.DestinationType.HasFlag(CustomUploaderDestinationType.URLSharingService))) destinations.Add("urls"); + cui.DestinationType.HasFlag(CustomUploaderDestinationType.URLSharingService)) destinations.Add("urls"); string destinationsText = string.Join("/", destinations); @@ -1666,6 +1688,30 @@ public static void AddCustomUploader(string filePath) } } + public static void ImportImageEffect(string filePath) + { + string configJson = null; + + try + { + configJson = ImageEffectPackager.ExtractPackage(filePath, Program.ImageEffectsFolder); + } + catch (Exception ex) + { + ex.ShowError(false); + } + + if (!string.IsNullOrEmpty(configJson)) + { + ImageEffectsForm imageEffectsForm = OpenImageEffectsSingleton(Program.DefaultTaskSettings); + + if (imageEffectsForm != null) + { + imageEffectsForm.ImportImageEffect(configJson); + } + } + } + public static void OpenActionsToolbar() { ActionsToolbarForm.Instance.ForceActivate(); diff --git a/ShareX/app.config b/ShareX/app.config index 392e2a9fd..0fb0bb158 100644 --- a/ShareX/app.config +++ b/ShareX/app.config @@ -1,7 +1,7 @@ - + - + @@ -13,7 +13,7 @@ - - - + + + \ No newline at end of file diff --git a/ShareX/app.manifest b/ShareX/app.manifest index 0878972b1..e48109748 100644 --- a/ShareX/app.manifest +++ b/ShareX/app.manifest @@ -3,7 +3,6 @@ True/PM - PerMonitorV2, PerMonitor true