From 7df4ad672faa6ab5210ee03c028b2110d521ba64 Mon Sep 17 00:00:00 2001 From: Jaex Date: Sat, 27 Jun 2020 01:04:43 +0300 Subject: [PATCH 01/19] Restrict extraction of image effect packages to 20mb to prevent zip bomb attacks --- ShareX.HelpersLib/MaxLengthStream.cs | 78 +++++++++++++++++++ ShareX.HelpersLib/ShareX.HelpersLib.csproj | 1 + ShareX.HelpersLib/ZipManager.cs | 38 ++++++++- ShareX.ImageEffectsLib/ImageEffectPackager.cs | 2 +- 4 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 ShareX.HelpersLib/MaxLengthStream.cs 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/ShareX.HelpersLib.csproj b/ShareX.HelpersLib/ShareX.HelpersLib.csproj index 6f10e3d65..f727c1feb 100644 --- a/ShareX.HelpersLib/ShareX.HelpersLib.csproj +++ b/ShareX.HelpersLib/ShareX.HelpersLib.csproj @@ -150,6 +150,7 @@ + diff --git a/ShareX.HelpersLib/ZipManager.cs b/ShareX.HelpersLib/ZipManager.cs index 21f67dc6a..21e4c4dc6 100644 --- a/ShareX.HelpersLib/ZipManager.cs +++ b/ShareX.HelpersLib/ZipManager.cs @@ -27,15 +27,25 @@ 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, Func filter = null) + public static void Extract(string archivePath, string destination, bool retainDirectoryStructure = true, Func filter = null, long maxLength = 0) { using (ZipArchive archive = ZipFile.OpenRead(archivePath)) { + if (maxLength > 0) + { + long declaredSize = archive.Entries.Sum(entry => entry.Length); + if (declaredSize > maxLength) + { + throw new Exception("Archive is too big."); + } + } + string fullName = Directory.CreateDirectory(Path.GetFullPath(destination)).FullName; foreach (ZipArchiveEntry entry in archive.Entries) @@ -70,13 +80,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)) diff --git a/ShareX.ImageEffectsLib/ImageEffectPackager.cs b/ShareX.ImageEffectsLib/ImageEffectPackager.cs index 36a579e4b..68335ebcf 100644 --- a/ShareX.ImageEffectsLib/ImageEffectPackager.cs +++ b/ShareX.ImageEffectsLib/ImageEffectPackager.cs @@ -99,7 +99,7 @@ public static string ExtractPackage(string packageFilePath, string destination) } return false; - }); + }, 20000000); } return configJson; From af4060ac889502dc0253dab44c0810aa11545d3e Mon Sep 17 00:00:00 2001 From: Jaex Date: Sun, 28 Jun 2020 14:05:25 +0300 Subject: [PATCH 02/19] Added aspect ratio support to image watermark when 0 is used for width or height --- ShareX.HelpersLib/Helpers/ImageHelpers.cs | 44 ++++++++++++++----- ShareX.ImageEffectsLib/Drawings/DrawImage.cs | 35 +++++++++------ .../Manipulations/Resize.cs | 9 ++-- ShareX.ImageEffectsLib/Manipulations/Scale.cs | 8 ++-- 4 files changed, 63 insertions(+), 33 deletions(-) diff --git a/ShareX.HelpersLib/Helpers/ImageHelpers.cs b/ShareX.HelpersLib/Helpers/ImageHelpers.cs index eceb7898c..6909283bc 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); @@ -2096,5 +2084,37 @@ public static InterpolationMode GetInterpolationMode(ImageInterpolationMode inte return InterpolationMode.NearestNeighbor; } } + + public static Size ApplyAspectRatio(int width, int height, Bitmap bmp) + { + int newWidth; + + if (width == 0) + { + newWidth = (int)Math.Round((float)height / bmp.Height * bmp.Width); + } + else + { + newWidth = width; + } + + int newHeight; + + if (height == 0) + { + newHeight = (int)Math.Round((float)width / bmp.Width * bmp.Height); + } + else + { + 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.ImageEffectsLib/Drawings/DrawImage.cs b/ShareX.ImageEffectsLib/Drawings/DrawImage.cs index 21a448219..4f647691e 100644 --- a/ShareX.ImageEffectsLib/Drawings/DrawImage.cs +++ b/ShareX.ImageEffectsLib/Drawings/DrawImage.cs @@ -24,6 +24,7 @@ #endregion License Information (GPL v3) using ShareX.HelpersLib; +using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Design; @@ -66,35 +67,43 @@ public DrawImage() public override Bitmap Apply(Bitmap bmp) { + 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, bmp); + } + 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)) @@ -107,7 +116,7 @@ public override Bitmap Apply(Bitmap bmp) g.InterpolationMode = ImageHelpers.GetInterpolationMode(InterpolationMode); g.PixelOffsetMode = PixelOffsetMode.Half; g.CompositingMode = CompositingMode; - g.DrawImage(bmp2, imageRectangle); + g.DrawImage(bmpWatermark, imageRectangle); } } } 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 From c737768e89d4240dd71343c1d08c6ec847f8b04e Mon Sep 17 00:00:00 2001 From: Jaex Date: Sun, 28 Jun 2020 15:26:09 +0300 Subject: [PATCH 03/19] Improve enum value preview in image watermark --- ShareX.HelpersLib/Enums.cs | 2 +- ShareX.HelpersLib/Helpers/ImageHelpers.cs | 12 +-- .../Properties/Resources.Designer.cs | 81 +++++++++---------- ShareX.HelpersLib/Properties/Resources.resx | 27 +++---- ShareX.HelpersLib/ShareX.HelpersLib.csproj | 1 + .../UITypeEditors/EnumDescriptionConverter.cs | 3 +- .../UITypeEditors/EnumProperNameConverter.cs | 70 ++++++++++++++++ ShareX.ImageEffectsLib/Drawings/DrawImage.cs | 8 +- ShareX.ImageEffectsLib/Enums.cs | 2 +- 9 files changed, 130 insertions(+), 76 deletions(-) create mode 100644 ShareX.HelpersLib/UITypeEditors/EnumProperNameConverter.cs diff --git a/ShareX.HelpersLib/Enums.cs b/ShareX.HelpersLib/Enums.cs index 9ab197155..c19ed84b7 100644 --- a/ShareX.HelpersLib/Enums.cs +++ b/ShareX.HelpersLib/Enums.cs @@ -189,7 +189,7 @@ public enum ImageCombinerAlignment RightOrBottom } - public enum ImageInterpolationMode // Localized + public enum ImageInterpolationMode { HighQualityBicubic, Bicubic, diff --git a/ShareX.HelpersLib/Helpers/ImageHelpers.cs b/ShareX.HelpersLib/Helpers/ImageHelpers.cs index 6909283bc..d3f31a20e 100644 --- a/ShareX.HelpersLib/Helpers/ImageHelpers.cs +++ b/ShareX.HelpersLib/Helpers/ImageHelpers.cs @@ -2087,25 +2087,21 @@ public static InterpolationMode GetInterpolationMode(ImageInterpolationMode inte public static Size ApplyAspectRatio(int width, int height, Bitmap bmp) { - int newWidth; + int newWidth, newHeight; if (width == 0) { newWidth = (int)Math.Round((float)height / bmp.Height * bmp.Width); + newHeight = height; } - else + else if (height == 0) { newWidth = width; - } - - int newHeight; - - if (height == 0) - { newHeight = (int)Math.Round((float)width / bmp.Width * bmp.Height); } else { + newWidth = width; newHeight = height; } diff --git a/ShareX.HelpersLib/Properties/Resources.Designer.cs b/ShareX.HelpersLib/Properties/Resources.Designer.cs index bae32c7fe..5bbec4dd5 100644 --- a/ShareX.HelpersLib/Properties/Resources.Designer.cs +++ b/ShareX.HelpersLib/Properties/Resources.Designer.cs @@ -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 watermark. + /// + internal static string DrawImageSizeMode_PercentageOfWatermark { + get { + return ResourceManager.GetString("DrawImageSizeMode_PercentageOfWatermark", resourceCulture); + } + } + /// /// Looks up a localized string similar to Error. /// @@ -2103,51 +2139,6 @@ internal class Resources { } } - /// - /// Looks up a localized string similar to Bicubic. - /// - internal static string ImageInterpolationMode_Bicubic { - get { - return ResourceManager.GetString("ImageInterpolationMode_Bicubic", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Bilinear. - /// - internal static string ImageInterpolationMode_Bilinear { - get { - return ResourceManager.GetString("ImageInterpolationMode_Bilinear", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to High quality bicubic. - /// - internal static string ImageInterpolationMode_HighQualityBicubic { - get { - return ResourceManager.GetString("ImageInterpolationMode_HighQualityBicubic", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to High quality bilinear. - /// - internal static string ImageInterpolationMode_HighQualityBilinear { - get { - return ResourceManager.GetString("ImageInterpolationMode_HighQualityBilinear", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Nearest neighbor. - /// - internal static string ImageInterpolationMode_NearestNeighbor { - get { - return ResourceManager.GetString("ImageInterpolationMode_NearestNeighbor", resourceCulture); - } - } - /// /// Looks up a localized string similar to Big square. /// diff --git a/ShareX.HelpersLib/Properties/Resources.resx b/ShareX.HelpersLib/Properties/Resources.resx index 9500916ca..cffd22f63 100644 --- a/ShareX.HelpersLib/Properties/Resources.resx +++ b/ShareX.HelpersLib/Properties/Resources.resx @@ -135,9 +135,6 @@ Custom text uploader - - High quality bicubic - None @@ -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 @@ -1253,4 +1238,16 @@ Would you like to download and install it? ..\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 watermark + \ No newline at end of file diff --git a/ShareX.HelpersLib/ShareX.HelpersLib.csproj b/ShareX.HelpersLib/ShareX.HelpersLib.csproj index f727c1feb..fb8430344 100644 --- a/ShareX.HelpersLib/ShareX.HelpersLib.csproj +++ b/ShareX.HelpersLib/ShareX.HelpersLib.csproj @@ -292,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.ImageEffectsLib/Drawings/DrawImage.cs b/ShareX.ImageEffectsLib/Drawings/DrawImage.cs index 4f647691e..171e155af 100644 --- a/ShareX.ImageEffectsLib/Drawings/DrawImage.cs +++ b/ShareX.ImageEffectsLib/Drawings/DrawImage.cs @@ -39,22 +39,22 @@ 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(EnumDescriptionConverter))] + [DefaultValue(ImageInterpolationMode.HighQualityBicubic), TypeConverter(typeof(EnumProperNameConverter))] public ImageInterpolationMode InterpolationMode { get; set; } - [DefaultValue(CompositingMode.SourceOver)] + [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.")] 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, From b5d68b721e93f9d33e1d1eef1a26ed7cd686ac58 Mon Sep 17 00:00:00 2001 From: Michael Delpach Date: Mon, 29 Jun 2020 07:36:48 +0800 Subject: [PATCH 04/19] .NET Framework upgrade to 4.7.2 to fix multi-DPI issues Starting with the .NET Framework 4.7, Windows Forms includes enhancements for common high DPI and dynamic DPI scenarios - See https://docs.microsoft.com/en-us/dotnet/framework/winforms/high-dpi-support-in-windows-forms --- ShareX.HelpersLib/ShareX.HelpersLib.csproj | 2 +- ShareX.HistoryLib/ShareX.HistoryLib.csproj | 2 +- .../Properties/Resources.Designer.cs | 2 +- .../ShareX.ImageEffectsLib.csproj | 2 +- .../Properties/Resources.Designer.cs | 5 ++--- ShareX.IndexerLib/ShareX.IndexerLib.csproj | 2 +- ShareX.MediaLib/Properties/Resources.Designer.cs | 2 +- ShareX.MediaLib/ShareX.MediaLib.csproj | 2 +- .../ShareX.NativeMessagingHost.csproj | 2 +- ShareX.NativeMessagingHost/app.config | 2 +- .../ShareX.ScreenCaptureLib.csproj | 2 +- ShareX.Setup/ShareX.Setup.csproj | 2 +- ShareX.Setup/app.config | 4 ++-- ShareX.Steam/ShareX.Steam.csproj | 2 +- ShareX.Steam/app.config | 2 +- ShareX.UploadersLib/ShareX.UploadersLib.csproj | 2 +- ShareX/ShareX.csproj | 2 +- ShareX/app.config | 16 ++++++++-------- 18 files changed, 27 insertions(+), 28 deletions(-) diff --git a/ShareX.HelpersLib/ShareX.HelpersLib.csproj b/ShareX.HelpersLib/ShareX.HelpersLib.csproj index fb8430344..f9ca5289b 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 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/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 45f067e61..58be5dbe3 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 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 466f54e5a..477164728 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..312bb3f26 100644 --- a/ShareX.NativeMessagingHost/app.config +++ b/ShareX.NativeMessagingHost/app.config @@ -1,3 +1,3 @@ - \ No newline at end of file + 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/ShareX.Setup.csproj b/ShareX.Setup/ShareX.Setup.csproj index ae441455e..bf51ccc2b 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/app.config b/ShareX.Setup/app.config index adcd8c5a5..2a2d44990 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..312bb3f26 100644 --- a/ShareX.Steam/app.config +++ b/ShareX.Steam/app.config @@ -1,3 +1,3 @@ - \ 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 a7d4b7cc8..5aad6fea4 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/app.config b/ShareX/app.config index 392e2a9fd..6317bcda0 100644 --- a/ShareX/app.config +++ b/ShareX/app.config @@ -1,19 +1,19 @@ - + - + - + - + - - + + - + - \ No newline at end of file + From de5902088806d45982b1e056e7674d1908ff5b7f Mon Sep 17 00:00:00 2001 From: Michael Delpach Date: Mon, 29 Jun 2020 19:26:19 +0800 Subject: [PATCH 05/19] Fixed #1477 #4007 #4378 #4379 #4540 In previous versions of the .NET Framework, you used the manifest to add high DPI support. This approach is no longer recommended, since it overrides settings defined on the app.config file. --- ShareX/app.config | 18 +++++++++--------- ShareX/app.manifest | 41 ++++++++++++++++++++--------------------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/ShareX/app.config b/ShareX/app.config index 6317bcda0..0fb0bb158 100644 --- a/ShareX/app.config +++ b/ShareX/app.config @@ -1,19 +1,19 @@ - + - + - + - - + + - - - - + + + + \ No newline at end of file diff --git a/ShareX/app.manifest b/ShareX/app.manifest index 0878972b1..7ef9ccd63 100644 --- a/ShareX/app.manifest +++ b/ShareX/app.manifest @@ -1,24 +1,23 @@  - - - True/PM - PerMonitorV2, PerMonitor - true - - - - - - - - - - - - - - - - + + + True/PM + true + + + + + + + + + + + + + + + + \ No newline at end of file From 6ebb2394a2f67638d1228190035a0bfeb6ee8468 Mon Sep 17 00:00:00 2001 From: Jaex Date: Tue, 30 Jun 2020 22:37:27 +0300 Subject: [PATCH 06/19] Format app config files --- ShareX.NativeMessagingHost/app.config | 5 +++- ShareX.Setup/app.config | 4 +-- ShareX.Steam/app.config | 5 +++- ShareX/app.manifest | 40 +++++++++++++-------------- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/ShareX.NativeMessagingHost/app.config b/ShareX.NativeMessagingHost/app.config index 312bb3f26..8f60dcb21 100644 --- a/ShareX.NativeMessagingHost/app.config +++ b/ShareX.NativeMessagingHost/app.config @@ -1,3 +1,6 @@ - + + + + \ No newline at end of file diff --git a/ShareX.Setup/app.config b/ShareX.Setup/app.config index 2a2d44990..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/app.config b/ShareX.Steam/app.config index 312bb3f26..8f60dcb21 100644 --- a/ShareX.Steam/app.config +++ b/ShareX.Steam/app.config @@ -1,3 +1,6 @@ - + + + + \ No newline at end of file diff --git a/ShareX/app.manifest b/ShareX/app.manifest index 7ef9ccd63..e48109748 100644 --- a/ShareX/app.manifest +++ b/ShareX/app.manifest @@ -1,23 +1,23 @@  - - - True/PM - true - - - - - - - - - - - - - - - - + + + True/PM + true + + + + + + + + + + + + + + + + \ No newline at end of file From 40e802f9ce302159b7ac1c9af5d8afe1fa17b06f Mon Sep 17 00:00:00 2001 From: Jaex Date: Tue, 30 Jun 2020 22:44:36 +0300 Subject: [PATCH 07/19] Clean .sxie registry --- ShareX.Setup/InnoSetup/ShareX-setup.iss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ShareX.Setup/InnoSetup/ShareX-setup.iss b/ShareX.Setup/InnoSetup/ShareX-setup.iss index 5332bb044..1a3f69052 100644 --- a/ShareX.Setup/InnoSetup/ShareX-setup.iss +++ b/ShareX.Setup/InnoSetup/ShareX-setup.iss @@ -105,6 +105,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] From 5a932ddda8243c1ca20ab669210ad7f586d7e096 Mon Sep 17 00:00:00 2001 From: Jaex Date: Tue, 30 Jun 2020 22:51:21 +0300 Subject: [PATCH 08/19] Support .sxie extension in Microsoft Store build --- ShareX.Setup/WindowsStore/AppxManifest.xml | 8 ++++++++ 1 file changed, 8 insertions(+) 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 + + + From 169c7c2347330c5530fd2a3bbca8db6fcd3e7477 Mon Sep 17 00:00:00 2001 From: Jaex Date: Thu, 2 Jul 2020 05:31:39 +0300 Subject: [PATCH 09/19] Improve zip extract error message --- ShareX.HelpersLib/Extensions/NumberExtensions.cs | 9 +++++---- ShareX.HelpersLib/ZipManager.cs | 14 +++++++++----- ShareX/TaskHelpers.cs | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) 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/ZipManager.cs b/ShareX.HelpersLib/ZipManager.cs index 21e4c4dc6..29af26e5d 100644 --- a/ShareX.HelpersLib/ZipManager.cs +++ b/ShareX.HelpersLib/ZipManager.cs @@ -33,16 +33,20 @@ namespace ShareX.HelpersLib { public static class ZipManager { - public static void Extract(string archivePath, string destination, bool retainDirectoryStructure = true, Func filter = null, long maxLength = 0) + public static void Extract(string archivePath, string destination, bool retainDirectoryStructure = true, Func filter = null, + long maxUncompressedSize = 0) { using (ZipArchive archive = ZipFile.OpenRead(archivePath)) { - if (maxLength > 0) + if (maxUncompressedSize > 0) { - long declaredSize = archive.Entries.Sum(entry => entry.Length); - if (declaredSize > maxLength) + long totalUncompressedSize = archive.Entries.Sum(entry => entry.Length); + + if (totalUncompressedSize > maxUncompressedSize) { - throw new Exception("Archive is too big."); + 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()}"); } } diff --git a/ShareX/TaskHelpers.cs b/ShareX/TaskHelpers.cs index d84d30727..dadc7386e 100644 --- a/ShareX/TaskHelpers.cs +++ b/ShareX/TaskHelpers.cs @@ -1698,7 +1698,7 @@ public static void ImportImageEffect(string filePath) } catch (Exception ex) { - ex.ShowError(); + ex.ShowError(false); } if (!string.IsNullOrEmpty(configJson)) From c9dd17be306fcb6afdf520ba8ef87acf07c2437f Mon Sep 17 00:00:00 2001 From: Jaex Date: Fri, 3 Jul 2020 01:43:20 +0300 Subject: [PATCH 10/19] Removed "watermark" text from image and text drawing effects --- ShareX.ImageEffectsLib/Drawings/DrawImage.cs | 2 +- ShareX.ImageEffectsLib/Drawings/DrawText.cs | 2 +- ShareX.ImageEffectsLib/ImageEffectPackager.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ShareX.ImageEffectsLib/Drawings/DrawImage.cs b/ShareX.ImageEffectsLib/Drawings/DrawImage.cs index 171e155af..83bd32364 100644 --- a/ShareX.ImageEffectsLib/Drawings/DrawImage.cs +++ b/ShareX.ImageEffectsLib/Drawings/DrawImage.cs @@ -33,7 +33,7 @@ namespace ShareX.ImageEffectsLib { - [Description("Image watermark")] + [Description("Image")] public class DrawImage : ImageEffect { [DefaultValue(""), Editor(typeof(ImageFileNameEditor), typeof(UITypeEditor))] diff --git a/ShareX.ImageEffectsLib/Drawings/DrawText.cs b/ShareX.ImageEffectsLib/Drawings/DrawText.cs index bf6743ba9..7481a3318 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)] diff --git a/ShareX.ImageEffectsLib/ImageEffectPackager.cs b/ShareX.ImageEffectsLib/ImageEffectPackager.cs index 68335ebcf..90afbe9b0 100644 --- a/ShareX.ImageEffectsLib/ImageEffectPackager.cs +++ b/ShareX.ImageEffectsLib/ImageEffectPackager.cs @@ -99,7 +99,7 @@ public static string ExtractPackage(string packageFilePath, string destination) } return false; - }, 20000000); + }, 20_000_000); } return configJson; From 5e5e2d9b31f0b510833776441f1977b44b37db3d Mon Sep 17 00:00:00 2001 From: Jaex Date: Fri, 3 Jul 2020 02:12:25 +0300 Subject: [PATCH 11/19] Set initial directory in image file name editor --- ShareX.HelpersLib/Helpers/ImageHelpers.cs | 11 ++++++++--- .../UITypeEditors/ImageFileNameEditor.cs | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/ShareX.HelpersLib/Helpers/ImageHelpers.cs b/ShareX.HelpersLib/Helpers/ImageHelpers.cs index d3f31a20e..15bfcb133 100644 --- a/ShareX.HelpersLib/Helpers/ImageHelpers.cs +++ b/ShareX.HelpersLib/Helpers/ImageHelpers.cs @@ -1526,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) { @@ -1538,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()) { @@ -1547,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; diff --git a/ShareX.HelpersLib/UITypeEditors/ImageFileNameEditor.cs b/ShareX.HelpersLib/UITypeEditors/ImageFileNameEditor.cs index 6b04c0fc3..001c41d6b 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)) { From 042a98f478603fcb8ad4e38883913a37efe4ed9e Mon Sep 17 00:00:00 2001 From: Michael Delpach Date: Fri, 3 Jul 2020 08:39:35 +0800 Subject: [PATCH 12/19] Save as and close --- .../Forms/DirectoryIndexerForm.Designer.cs | 22 +- .../Forms/DirectoryIndexerForm.cs | 28 ++ .../Forms/DirectoryIndexerForm.resx | 270 ++++++++++++------ 3 files changed, 230 insertions(+), 90 deletions(-) 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 From a05db9b66af15d3a413b25586610e5314def5dae Mon Sep 17 00:00:00 2001 From: L1Q <0xL1Q@ex.ua> Date: Fri, 3 Jul 2020 10:31:39 +0300 Subject: [PATCH 13/19] Add RGB Split image effect --- ShareX.ImageEffectsLib/Filters/RGBSplit.cs | 70 +++++++++++++++++++ ShareX.ImageEffectsLib/ImageEffectsForm.cs | 1 + .../ShareX.ImageEffectsLib.csproj | 1 + 3 files changed, 72 insertions(+) create mode 100644 ShareX.ImageEffectsLib/Filters/RGBSplit.cs diff --git a/ShareX.ImageEffectsLib/Filters/RGBSplit.cs b/ShareX.ImageEffectsLib/Filters/RGBSplit.cs new file mode 100644 index 000000000..3feb2f39a --- /dev/null +++ b/ShareX.ImageEffectsLib/Filters/RGBSplit.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 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; } + [DefaultValue(typeof(Point), "0, 0")] + public Point OffsetGreen { get; set; } + [DefaultValue(typeof(Point), "-5, 0")] + public Point OffsetBlue { get; set; } + + 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)) + { + for (int y = 0; y < dest.Height; y++) + { + for (int x = 0; x < dest.Width; x++) + { + ColorBgra colorR = source.GetPixel(MathHelpers.Clamp(x + OffsetRed.X, 0, dest.Width - 1), MathHelpers.Clamp(y + OffsetRed.Y, 0, dest.Height - 1)); + ColorBgra colorG = source.GetPixel(MathHelpers.Clamp(x + OffsetGreen.X, 0, dest.Width - 1), MathHelpers.Clamp(y + OffsetGreen.Y, 0, dest.Height - 1)); + ColorBgra colorB = source.GetPixel(MathHelpers.Clamp(x + OffsetBlue.X, 0, dest.Width - 1), MathHelpers.Clamp(y + OffsetBlue.Y, 0, dest.Height - 1)); + + byte colorR_alpha = colorR.Alpha; + byte colorG_alpha = colorG.Alpha; + byte colorB_alpha = colorB.Alpha; + byte colorA = (byte)((colorR_alpha / 3 + colorG_alpha / 3 + colorB_alpha / 3)); + + ColorBgra shiftedcolor = new ColorBgra((byte)(colorB.Blue * colorB_alpha / 255), (byte)(colorG.Green * colorG_alpha / 255), (byte)(colorR.Red * colorR_alpha / 255), colorA); + dest.SetPixel(x, y, shiftedcolor); + } + } + } + return bmpResult; + } + } +} \ No newline at end of file diff --git a/ShareX.ImageEffectsLib/ImageEffectsForm.cs b/ShareX.ImageEffectsLib/ImageEffectsForm.cs index f78846e9b..9ab7e16c6 100644 --- a/ShareX.ImageEffectsLib/ImageEffectsForm.cs +++ b/ShareX.ImageEffectsLib/ImageEffectsForm.cs @@ -162,6 +162,7 @@ private void AddAllEffectsToContextMenu() typeof(MeanRemoval), typeof(Outline), typeof(Pixelate), + typeof(RGBSplit), typeof(Reflection), typeof(Shadow), typeof(Sharpen), diff --git a/ShareX.ImageEffectsLib/ShareX.ImageEffectsLib.csproj b/ShareX.ImageEffectsLib/ShareX.ImageEffectsLib.csproj index 58be5dbe3..806400e34 100644 --- a/ShareX.ImageEffectsLib/ShareX.ImageEffectsLib.csproj +++ b/ShareX.ImageEffectsLib/ShareX.ImageEffectsLib.csproj @@ -119,6 +119,7 @@ + From 423b4d68605bd8f7c354009d5de434ee048beb77 Mon Sep 17 00:00:00 2001 From: Jaex Date: Fri, 3 Jul 2020 14:18:47 +0300 Subject: [PATCH 14/19] Code refactor --- ShareX.ImageEffectsLib/Filters/RGBSplit.cs | 19 +++++++++++-------- ShareX.ImageEffectsLib/ImageEffectsForm.cs | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ShareX.ImageEffectsLib/Filters/RGBSplit.cs b/ShareX.ImageEffectsLib/Filters/RGBSplit.cs index 3feb2f39a..07a02dbda 100644 --- a/ShareX.ImageEffectsLib/Filters/RGBSplit.cs +++ b/ShareX.ImageEffectsLib/Filters/RGBSplit.cs @@ -30,19 +30,20 @@ namespace ShareX.ImageEffectsLib { - [Description("RGB Split")] + [Description("RGB split")] internal class RGBSplit : ImageEffect { - [DefaultValue(typeof(Point), "5, 0")] - public Point OffsetRed { get; set; } + [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; } + [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)) { @@ -57,13 +58,15 @@ public override Bitmap Apply(Bitmap bmp) byte colorR_alpha = colorR.Alpha; byte colorG_alpha = colorG.Alpha; byte colorB_alpha = colorB.Alpha; - byte colorA = (byte)((colorR_alpha / 3 + colorG_alpha / 3 + colorB_alpha / 3)); + byte colorA = (byte)(colorR_alpha / 3 + colorG_alpha / 3 + colorB_alpha / 3); - ColorBgra shiftedcolor = new ColorBgra((byte)(colorB.Blue * colorB_alpha / 255), (byte)(colorG.Green * colorG_alpha / 255), (byte)(colorR.Red * colorR_alpha / 255), colorA); - dest.SetPixel(x, y, shiftedcolor); + ColorBgra shiftedColor = new ColorBgra((byte)(colorB.Blue * colorB_alpha / 255), (byte)(colorG.Green * colorG_alpha / 255), + (byte)(colorR.Red * colorR_alpha / 255), colorA); + dest.SetPixel(x, y, shiftedColor); } } } + return bmpResult; } } diff --git a/ShareX.ImageEffectsLib/ImageEffectsForm.cs b/ShareX.ImageEffectsLib/ImageEffectsForm.cs index 9ab7e16c6..cded3c838 100644 --- a/ShareX.ImageEffectsLib/ImageEffectsForm.cs +++ b/ShareX.ImageEffectsLib/ImageEffectsForm.cs @@ -162,8 +162,8 @@ private void AddAllEffectsToContextMenu() typeof(MeanRemoval), typeof(Outline), typeof(Pixelate), - typeof(RGBSplit), typeof(Reflection), + typeof(RGBSplit), typeof(Shadow), typeof(Sharpen), typeof(Slice), From 5fdf602200a82093214b0ef561ba3cda958547d0 Mon Sep 17 00:00:00 2001 From: Jaex Date: Sat, 4 Jul 2020 00:51:47 +0300 Subject: [PATCH 15/19] Code refactor --- ShareX.ImageEffectsLib/Filters/RGBSplit.cs | 25 +++++++++++----------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/ShareX.ImageEffectsLib/Filters/RGBSplit.cs b/ShareX.ImageEffectsLib/Filters/RGBSplit.cs index 07a02dbda..1c77038ac 100644 --- a/ShareX.ImageEffectsLib/Filters/RGBSplit.cs +++ b/ShareX.ImageEffectsLib/Filters/RGBSplit.cs @@ -35,8 +35,10 @@ 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); @@ -47,21 +49,18 @@ public override Bitmap Apply(Bitmap bmp) using (UnsafeBitmap source = new UnsafeBitmap(bmp, true, ImageLockMode.ReadOnly)) using (UnsafeBitmap dest = new UnsafeBitmap(bmpResult, true, ImageLockMode.WriteOnly)) { - for (int y = 0; y < dest.Height; y++) + int right = source.Width - 1; + int bottom = source.Height - 1; + + for (int y = 0; y < source.Height; y++) { - for (int x = 0; x < dest.Width; x++) + for (int x = 0; x < source.Width; x++) { - ColorBgra colorR = source.GetPixel(MathHelpers.Clamp(x + OffsetRed.X, 0, dest.Width - 1), MathHelpers.Clamp(y + OffsetRed.Y, 0, dest.Height - 1)); - ColorBgra colorG = source.GetPixel(MathHelpers.Clamp(x + OffsetGreen.X, 0, dest.Width - 1), MathHelpers.Clamp(y + OffsetGreen.Y, 0, dest.Height - 1)); - ColorBgra colorB = source.GetPixel(MathHelpers.Clamp(x + OffsetBlue.X, 0, dest.Width - 1), MathHelpers.Clamp(y + OffsetBlue.Y, 0, dest.Height - 1)); - - byte colorR_alpha = colorR.Alpha; - byte colorG_alpha = colorG.Alpha; - byte colorB_alpha = colorB.Alpha; - byte colorA = (byte)(colorR_alpha / 3 + colorG_alpha / 3 + colorB_alpha / 3); - - ColorBgra shiftedColor = new ColorBgra((byte)(colorB.Blue * colorB_alpha / 255), (byte)(colorG.Green * colorG_alpha / 255), - (byte)(colorR.Red * colorR_alpha / 255), colorA); + 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); } } From a98333c1ab8d817862fd86a5c20931eb6e87bd38 Mon Sep 17 00:00:00 2001 From: Jaex Date: Sat, 4 Jul 2020 09:45:52 +0300 Subject: [PATCH 16/19] Added confirmation for package overwrite --- ShareX.ImageEffectsLib/Drawings/DrawText.cs | 6 +++--- ShareX.ImageEffectsLib/ImageEffectPackagerForm.cs | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ShareX.ImageEffectsLib/Drawings/DrawText.cs b/ShareX.ImageEffectsLib/Drawings/DrawText.cs index 7481a3318..31227e61a 100644 --- a/ShareX.ImageEffectsLib/Drawings/DrawText.cs +++ b/ShareX.ImageEffectsLib/Drawings/DrawText.cs @@ -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/ImageEffectPackagerForm.cs b/ShareX.ImageEffectsLib/ImageEffectPackagerForm.cs index a19ce63b6..7691499de 100644 --- a/ShareX.ImageEffectsLib/ImageEffectPackagerForm.cs +++ b/ShareX.ImageEffectsLib/ImageEffectPackagerForm.cs @@ -93,8 +93,9 @@ private void btnPackage_Click(object sender, EventArgs e) // TODO: Translate MessageBox.Show("Assets folder must be inside ShareX image effects folder.", "ShareX - " + "Invalid assets folder path", MessageBoxButtons.OK, MessageBoxIcon.Warning); - } - else + } // 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); From 4a444ca164a070410789e8477c7ac2283f6a7c1f Mon Sep 17 00:00:00 2001 From: Jaex Date: Sun, 5 Jul 2020 08:12:55 +0300 Subject: [PATCH 17/19] Added area and perimeter info to ruler tool --- ShareX.HelpersLib/Extensions/Extensions.cs | 10 ++++++++++ .../Forms/RegionCaptureForm.cs | 18 ++++++++++-------- .../Properties/Resources.Designer.cs | 11 ----------- .../Properties/Resources.resx | 5 ----- ShareX.ScreenCaptureLib/RegionCaptureTasks.cs | 1 + 5 files changed, 21 insertions(+), 24 deletions(-) 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.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)) { From 7577bdd0a4a35c296fc3ea6a9f2cac7f3a520501 Mon Sep 17 00:00:00 2001 From: Jaex Date: Sun, 5 Jul 2020 11:05:43 +0300 Subject: [PATCH 18/19] Keep aspect ratio using watermark image instead of canvas --- ShareX.HelpersLib/Properties/Resources.Designer.cs | 2 +- ShareX.HelpersLib/Properties/Resources.resx | 2 +- ShareX.ImageEffectsLib/Drawings/DrawImage.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ShareX.HelpersLib/Properties/Resources.Designer.cs b/ShareX.HelpersLib/Properties/Resources.Designer.cs index 5bbec4dd5..0f8ce532e 100644 --- a/ShareX.HelpersLib/Properties/Resources.Designer.cs +++ b/ShareX.HelpersLib/Properties/Resources.Designer.cs @@ -772,7 +772,7 @@ internal class Resources { } /// - /// Looks up a localized string similar to Percentage of watermark. + /// Looks up a localized string similar to Percentage of image. /// internal static string DrawImageSizeMode_PercentageOfWatermark { get { diff --git a/ShareX.HelpersLib/Properties/Resources.resx b/ShareX.HelpersLib/Properties/Resources.resx index cffd22f63..ed2b15b05 100644 --- a/ShareX.HelpersLib/Properties/Resources.resx +++ b/ShareX.HelpersLib/Properties/Resources.resx @@ -1248,6 +1248,6 @@ Would you like to download and install it? Percentage of canvas - Percentage of watermark + Percentage of image \ No newline at end of file diff --git a/ShareX.ImageEffectsLib/Drawings/DrawImage.cs b/ShareX.ImageEffectsLib/Drawings/DrawImage.cs index 83bd32364..1a0d122d1 100644 --- a/ShareX.ImageEffectsLib/Drawings/DrawImage.cs +++ b/ShareX.ImageEffectsLib/Drawings/DrawImage.cs @@ -96,7 +96,7 @@ public override Bitmap Apply(Bitmap bmp) { 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, bmp); + imageSize = ImageHelpers.ApplyAspectRatio(width, height, bmpWatermark); } else { From 0c039b9ee029d2316b1c2676aea00d26800019e3 Mon Sep 17 00:00:00 2001 From: Jaex Date: Sun, 5 Jul 2020 17:27:31 +0300 Subject: [PATCH 19/19] Added palette size option to SelectiveColor effect --- ShareX.HelpersLib/Helpers/ImageHelpers.cs | 20 +++++++++++++++++-- .../Adjustments/SelectiveColor.cs | 6 +++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/ShareX.HelpersLib/Helpers/ImageHelpers.cs b/ShareX.HelpersLib/Helpers/ImageHelpers.cs index 15bfcb133..ac456fc6f 100644 --- a/ShareX.HelpersLib/Helpers/ImageHelpers.cs +++ b/ShareX.HelpersLib/Helpers/ImageHelpers.cs @@ -2043,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; 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; } }