Revert "Revert "Merge branch 'master' of https://github.com/ShareX/ShareX""

This reverts commit 85fdab3c56.
This commit is contained in:
Michael Delpach 2020-07-06 06:37:56 +08:00
parent 85fdab3c56
commit 50f86ee79a
50 changed files with 1076 additions and 292 deletions

View file

@ -188,4 +188,13 @@ public enum ImageCombinerAlignment
Center,
RightOrBottom
}
public enum ImageInterpolationMode
{
HighQualityBicubic,
Bicubic,
HighQualityBilinear,
Bilinear,
NearestNeighbor
}
}

View file

@ -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);

View file

@ -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)

View file

@ -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<int, Color> colors = new Dictionary<int, Color>();
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<int, Color> 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);
}
}
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#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);
}
}
}

View file

@ -146,7 +146,7 @@ internal class Resources {
}
/// <summary>
/// Looks up a localized string similar to Add image effects / watermark.
/// Looks up a localized string similar to Add image effects.
/// </summary>
internal static string AfterCaptureTasks_AddImageEffects {
get {
@ -744,6 +744,42 @@ internal class Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Absolute size.
/// </summary>
internal static string DrawImageSizeMode_AbsoluteSize {
get {
return ResourceManager.GetString("DrawImageSizeMode_AbsoluteSize", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Don&apos;t resize.
/// </summary>
internal static string DrawImageSizeMode_DontResize {
get {
return ResourceManager.GetString("DrawImageSizeMode_DontResize", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Percentage of canvas.
/// </summary>
internal static string DrawImageSizeMode_PercentageOfCanvas {
get {
return ResourceManager.GetString("DrawImageSizeMode_PercentageOfCanvas", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Percentage of image.
/// </summary>
internal static string DrawImageSizeMode_PercentageOfWatermark {
get {
return ResourceManager.GetString("DrawImageSizeMode_PercentageOfWatermark", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error.
/// </summary>
@ -2058,51 +2094,6 @@ internal class Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Bicubic.
/// </summary>
internal static string ImageEditorInterpolationMode_Bicubic {
get {
return ResourceManager.GetString("ImageEditorInterpolationMode_Bicubic", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Bilinear.
/// </summary>
internal static string ImageEditorInterpolationMode_Bilinear {
get {
return ResourceManager.GetString("ImageEditorInterpolationMode_Bilinear", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to High quality bicubic.
/// </summary>
internal static string ImageEditorInterpolationMode_HighQualityBicubic {
get {
return ResourceManager.GetString("ImageEditorInterpolationMode_HighQualityBicubic", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to High quality bilinear.
/// </summary>
internal static string ImageEditorInterpolationMode_HighQualityBilinear {
get {
return ResourceManager.GetString("ImageEditorInterpolationMode_HighQualityBilinear", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Nearest neighbor.
/// </summary>
internal static string ImageEditorInterpolationMode_NearestNeighbor {
get {
return ResourceManager.GetString("ImageEditorInterpolationMode_NearestNeighbor", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Auto size.
/// </summary>
@ -2251,9 +2242,19 @@ internal class Resources {
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
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));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap LoadingSmallWhite {
get {
object obj = ResourceManager.GetObject("LoadingSmallWhite", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}

View file

@ -135,9 +135,6 @@
<data name="TextDestination_CustomTextUploader" xml:space="preserve">
<value>Custom text uploader</value>
</data>
<data name="ImageEditorInterpolationMode_HighQualityBicubic" xml:space="preserve">
<value>High quality bicubic</value>
</data>
<data name="ProxyMethod_None" xml:space="preserve">
<value>None</value>
</data>
@ -477,7 +474,7 @@ Would you like to download it?</value>
<value>Manual</value>
</data>
<data name="AfterCaptureTasks_AddImageEffects" xml:space="preserve">
<value>Add image effects / watermark</value>
<value>Add image effects</value>
</data>
<data name="AfterCaptureTasks_DeleteFile" xml:space="preserve">
<value>Delete file locally</value>
@ -683,9 +680,6 @@ Would you like to download and install it?</value>
<data name="HotkeyType_ScreenRecorderGIF_Category" xml:space="preserve">
<value>Screen record</value>
</data>
<data name="ImageEditorInterpolationMode_Bilinear" xml:space="preserve">
<value>Bilinear</value>
</data>
<data name="WavFileNameEditor_EditValue_Browse_for_a_sound_file___" xml:space="preserve">
<value>Browse for a sound file...</value>
</data>
@ -710,9 +704,6 @@ Would you like to download and install it?</value>
<data name="Extensions_AddContextMenu_Paste" xml:space="preserve">
<value>Paste</value>
</data>
<data name="ImageEditorInterpolationMode_HighQualityBilinear" xml:space="preserve">
<value>High quality bilinear</value>
</data>
<data name="LinearGradientMode_ForwardDiagonal" xml:space="preserve">
<value>Forward diagonal</value>
</data>
@ -734,9 +725,6 @@ Would you like to download and install it?</value>
<data name="RegionCaptureAction_RemoveShapeCancelCapture" xml:space="preserve">
<value>Remove shape or cancel capture</value>
</data>
<data name="ImageEditorInterpolationMode_NearestNeighbor" xml:space="preserve">
<value>Nearest neighbor</value>
</data>
<data name="ReplCodeMenuEntry_un_User_name" xml:space="preserve">
<value>User name</value>
</data>
@ -746,9 +734,6 @@ Would you like to download and install it?</value>
<data name="DownloaderForm_ChangeStatus_Status___0_" xml:space="preserve">
<value>Status: {0}</value>
</data>
<data name="ImageEditorInterpolationMode_Bicubic" xml:space="preserve">
<value>Bicubic</value>
</data>
<data name="CodeMenu_Create_Close" xml:space="preserve">
<value>Close</value>
</data>
@ -1193,9 +1178,6 @@ Would you like to download and install it?</value>
<data name="AmazonS3StorageClass_STANDARD_IA" xml:space="preserve">
<value>Amazon S3 Standard-Infrequent Access</value>
</data>
<data name="LoadingSmall" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\LoadingSmall.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="RandomNonAmbiguousAlphanumericCharRepeatUsingN" xml:space="preserve">
<value>Random non ambiguous alphanumeric char. Repeat using {n}</value>
</data>
@ -1250,4 +1232,22 @@ Would you like to download and install it?</value>
<data name="AmazonS3StorageClass_ONEZONE_IA" xml:space="preserve">
<value>Amazon S3 One Zone-Infrequent Access</value>
</data>
<data name="LoadingSmallBlack" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\LoadingSmallBlack.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="LoadingSmallWhite" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\LoadingSmallWhite.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="DrawImageSizeMode_AbsoluteSize" xml:space="preserve">
<value>Absolute size</value>
</data>
<data name="DrawImageSizeMode_DontResize" xml:space="preserve">
<value>Don't resize</value>
</data>
<data name="DrawImageSizeMode_PercentageOfCanvas" xml:space="preserve">
<value>Percentage of canvas</value>
</data>
<data name="DrawImageSizeMode_PercentageOfWatermark" xml:space="preserve">
<value>Percentage of image</value>
</data>
</root>

View file

@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShareX.HelpersLib</RootNamespace>
<AssemblyName>ShareX.HelpersLib</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<StartupObject>
</StartupObject>
@ -150,6 +150,7 @@
</Compile>
<Compile Include="Helpers\JsonHelpers.cs" />
<Compile Include="ImageFilesCache.cs" />
<Compile Include="MaxLengthStream.cs" />
<Compile Include="PointInfo.cs" />
<Compile Include="Random\RandomCrypto.cs" />
<Compile Include="Random\RandomFast.cs" />
@ -291,6 +292,7 @@
<Compile Include="Settings\TypeNameSerializationBinder.cs" />
<Compile Include="UITypeEditors\EnumDescriptionConverter.cs" />
<Compile Include="UITypeEditors\DirectoryNameEditor.cs" />
<Compile Include="UITypeEditors\EnumProperNameConverter.cs" />
<Compile Include="UITypeEditors\GradientEditor.cs" />
<Compile Include="UITypeEditors\JsonFileNameEditor.cs" />
<Compile Include="UITypeEditors\MyColorConverter.cs" />

View file

@ -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;
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#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<Enum>())
{
if (Helpers.GetProperName(e.ToString()) == (string)value)
{
return e;
}
}
return Enum.Parse(enumType, (string)value);
}
}
}

View file

@ -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))
{

View file

@ -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<string> fileFilter = null)
public static void Extract(string archivePath, string destination, bool retainDirectoryStructure = true, Func<ZipArchiveEntry, bool> 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<string> files, string workingDirectory = "", CompressionLevel compression = CompressionLevel.Optimal)
public static void Compress(string archivePath, List<string> files, CompressionLevel compression = CompressionLevel.Optimal)
{
Dictionary<string, string> entries = new Dictionary<string, string>();
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<string, string> files, CompressionLevel compression = CompressionLevel.Optimal)
{
if (File.Exists(archivePath))
{
@ -106,13 +147,14 @@ public static void Compress(string archivePath, List<string> files, string worki
using (ZipArchive archive = ZipFile.Open(archivePath, ZipArchiveMode.Update))
{
foreach (string file in files)
foreach (KeyValuePair<string, string> 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);
}
}
}

View file

@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShareX.HistoryLib</RootNamespace>
<AssemblyName>ShareX.HistoryLib</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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)]

View file

@ -43,7 +43,7 @@ public enum ResizeMode
ResizeIfSmaller
}
public enum DrawImageSizeMode
public enum DrawImageSizeMode // Localized
{
DontResize,
AbsoluteSize,

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}
}
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#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<string, string> files = new Dictionary<string, string>();
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;
}
}
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#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();
}
}
}
}

View file

@ -137,6 +137,7 @@ private void AddAllEffectsToContextMenu()
typeof(Outline),
typeof(Pixelate),
typeof(Reflection),
typeof(RGBSplit),
typeof(Shadow),
typeof(Sharpen),
typeof(Slice),

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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 {

View file

@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShareX.ImageEffectsLib</RootNamespace>
<AssemblyName>ShareX.ImageEffectsLib</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
@ -118,6 +118,7 @@
<Compile Include="Filters\MatrixConvolution.cs" />
<Compile Include="Filters\MeanRemoval.cs" />
<Compile Include="Filters\Outline.cs" />
<Compile Include="Filters\RGBSplit.cs" />
<Compile Include="Filters\Pixelate.cs" />
<Compile Include="Filters\Sharpen.cs" />
<Compile Include="Filters\Slice.cs" />

View file

@ -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;
}
}

View file

@ -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();
}
}
}
}
}
}

View file

@ -118,44 +118,17 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="wbPreview.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="wbPreview.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</data>
<data name="wbPreview.MinimumSize" type="System.Drawing.Size, System.Drawing">
<value>20, 20</value>
</data>
<data name="wbPreview.Size" type="System.Drawing.Size, System.Drawing">
<value>860, 564</value>
</data>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="wbPreview.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="&gt;&gt;wbPreview.Name" xml:space="preserve">
<value>wbPreview</value>
</data>
<data name="&gt;&gt;wbPreview.Type" xml:space="preserve">
<value>System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;wbPreview.Parent" xml:space="preserve">
<value>tpPreview</value>
</data>
<data name="&gt;&gt;wbPreview.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="txtFolderPath.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Left, Right</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="txtFolderPath.Location" type="System.Drawing.Point, System.Drawing">
<value>192, 8</value>
</data>
<data name="txtFolderPath.Size" type="System.Drawing.Size, System.Drawing">
<value>682, 20</value>
</data>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="txtFolderPath.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
@ -169,7 +142,10 @@
<value>$this</value>
</data>
<data name="&gt;&gt;txtFolderPath.ZOrder" xml:space="preserve">
<value>4</value>
<value>5</value>
</data>
<data name="btnBrowseFolder.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="btnBrowseFolder.Location" type="System.Drawing.Point, System.Drawing">
<value>8, 7</value>
@ -193,16 +169,19 @@
<value>$this</value>
</data>
<data name="&gt;&gt;btnBrowseFolder.ZOrder" xml:space="preserve">
<value>3</value>
<value>4</value>
</data>
<data name="btnIndexFolder.Enabled" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="btnIndexFolder.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="btnIndexFolder.Location" type="System.Drawing.Point, System.Drawing">
<value>8, 32</value>
</data>
<data name="btnIndexFolder.Size" type="System.Drawing.Size, System.Drawing">
<value>344, 23</value>
<value>294, 23</value>
</data>
<data name="btnIndexFolder.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
@ -220,16 +199,19 @@
<value>$this</value>
</data>
<data name="&gt;&gt;btnIndexFolder.ZOrder" xml:space="preserve">
<value>2</value>
<value>3</value>
</data>
<data name="btnUpload.Enabled" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="btnUpload.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="btnUpload.Location" type="System.Drawing.Point, System.Drawing">
<value>360, 32</value>
<value>308, 32</value>
</data>
<data name="btnUpload.Size" type="System.Drawing.Size, System.Drawing">
<value>344, 23</value>
<value>276, 23</value>
</data>
<data name="btnUpload.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
@ -247,11 +229,104 @@
<value>$this</value>
</data>
<data name="&gt;&gt;btnUpload.ZOrder" xml:space="preserve">
<value>1</value>
<value>2</value>
</data>
<data name="tcMain.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Bottom, Left, Right</value>
</data>
<data name="&gt;&gt;tpPreview.Name" xml:space="preserve">
<value>tpPreview</value>
</data>
<data name="&gt;&gt;tpPreview.Type" xml:space="preserve">
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tpPreview.Parent" xml:space="preserve">
<value>tcMain</value>
</data>
<data name="&gt;&gt;tpPreview.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;tpSettings.Name" xml:space="preserve">
<value>tpSettings</value>
</data>
<data name="&gt;&gt;tpSettings.Type" xml:space="preserve">
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tpSettings.Parent" xml:space="preserve">
<value>tcMain</value>
</data>
<data name="&gt;&gt;tpSettings.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="tcMain.Location" type="System.Drawing.Point, System.Drawing">
<value>8, 64</value>
</data>
<data name="tcMain.Size" type="System.Drawing.Size, System.Drawing">
<value>868, 590</value>
</data>
<data name="tcMain.TabIndex" type="System.Int32, mscorlib">
<value>4</value>
</data>
<data name="&gt;&gt;tcMain.Name" xml:space="preserve">
<value>tcMain</value>
</data>
<data name="&gt;&gt;tcMain.Type" xml:space="preserve">
<value>System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tcMain.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;tcMain.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="&gt;&gt;txtPreview.Name" xml:space="preserve">
<value>txtPreview</value>
</data>
<data name="&gt;&gt;txtPreview.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;txtPreview.Parent" xml:space="preserve">
<value>tpPreview</value>
</data>
<data name="&gt;&gt;txtPreview.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;wbPreview.Name" xml:space="preserve">
<value>wbPreview</value>
</data>
<data name="&gt;&gt;wbPreview.Type" xml:space="preserve">
<value>System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;wbPreview.Parent" xml:space="preserve">
<value>tpPreview</value>
</data>
<data name="&gt;&gt;wbPreview.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="tpPreview.Location" type="System.Drawing.Point, System.Drawing">
<value>4, 22</value>
</data>
<data name="tpPreview.Size" type="System.Drawing.Size, System.Drawing">
<value>860, 564</value>
</data>
<data name="tpPreview.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="tpPreview.Text" xml:space="preserve">
<value>Preview</value>
</data>
<data name="&gt;&gt;tpPreview.Name" xml:space="preserve">
<value>tpPreview</value>
</data>
<data name="&gt;&gt;tpPreview.Type" xml:space="preserve">
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tpPreview.Parent" xml:space="preserve">
<value>tcMain</value>
</data>
<data name="&gt;&gt;tpPreview.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="txtPreview.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
@ -282,42 +357,6 @@
<data name="&gt;&gt;txtPreview.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="tpPreview.Location" type="System.Drawing.Point, System.Drawing">
<value>4, 22</value>
</data>
<data name="tpPreview.Size" type="System.Drawing.Size, System.Drawing">
<value>860, 564</value>
</data>
<data name="tpPreview.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="tpPreview.Text" xml:space="preserve">
<value>Preview</value>
</data>
<data name="&gt;&gt;tpPreview.Name" xml:space="preserve">
<value>tpPreview</value>
</data>
<data name="&gt;&gt;tpPreview.Type" xml:space="preserve">
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tpPreview.Parent" xml:space="preserve">
<value>tcMain</value>
</data>
<data name="&gt;&gt;tpPreview.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="pgSettings.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="pgSettings.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</data>
<data name="pgSettings.Size" type="System.Drawing.Size, System.Drawing">
<value>860, 564</value>
</data>
<data name="pgSettings.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="&gt;&gt;pgSettings.Name" xml:space="preserve">
<value>pgSettings</value>
</data>
@ -354,27 +393,87 @@
<data name="&gt;&gt;tpSettings.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="tcMain.Location" type="System.Drawing.Point, System.Drawing">
<value>8, 64</value>
<data name="pgSettings.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="tcMain.Size" type="System.Drawing.Size, System.Drawing">
<value>868, 590</value>
<data name="pgSettings.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</data>
<data name="tcMain.TabIndex" type="System.Int32, mscorlib">
<value>4</value>
<data name="pgSettings.Size" type="System.Drawing.Size, System.Drawing">
<value>860, 564</value>
</data>
<data name="&gt;&gt;tcMain.Name" xml:space="preserve">
<value>tcMain</value>
<data name="pgSettings.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="&gt;&gt;tcMain.Type" xml:space="preserve">
<value>System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<data name="&gt;&gt;pgSettings.Name" xml:space="preserve">
<value>pgSettings</value>
</data>
<data name="&gt;&gt;tcMain.Parent" xml:space="preserve">
<data name="&gt;&gt;pgSettings.Type" xml:space="preserve">
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;pgSettings.Parent" xml:space="preserve">
<value>tpSettings</value>
</data>
<data name="&gt;&gt;pgSettings.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="btnSaveAs.Enabled" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="btnSaveAs.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="btnSaveAs.Location" type="System.Drawing.Point, System.Drawing">
<value>590, 32</value>
</data>
<data name="btnSaveAs.Size" type="System.Drawing.Size, System.Drawing">
<value>284, 23</value>
</data>
<data name="btnSaveAs.TabIndex" type="System.Int32, mscorlib">
<value>5</value>
</data>
<data name="btnSaveAs.Text" xml:space="preserve">
<value>Save as and close this window...</value>
</data>
<data name="&gt;&gt;btnSaveAs.Name" xml:space="preserve">
<value>btnSaveAs</value>
</data>
<data name="&gt;&gt;btnSaveAs.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;btnSaveAs.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;tcMain.ZOrder" xml:space="preserve">
<data name="&gt;&gt;btnSaveAs.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="wbPreview.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="wbPreview.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</data>
<data name="wbPreview.MinimumSize" type="System.Drawing.Size, System.Drawing">
<value>20, 20</value>
</data>
<data name="wbPreview.Size" type="System.Drawing.Size, System.Drawing">
<value>860, 564</value>
</data>
<data name="wbPreview.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="&gt;&gt;wbPreview.Name" xml:space="preserve">
<value>wbPreview</value>
</data>
<data name="&gt;&gt;wbPreview.Type" xml:space="preserve">
<value>System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;wbPreview.Parent" xml:space="preserve">
<value>tpPreview</value>
</data>
<data name="&gt;&gt;wbPreview.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
@ -384,6 +483,9 @@
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
<value>884, 661</value>
</data>
<data name="$this.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
<value>CenterScreen</value>
</data>

View file

@ -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]&quot;;.
/// color: # [rest of string was truncated]&quot;;.
/// </summary>
internal static string IndexerDefault {
get {

View file

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShareX.IndexerLib</RootNamespace>
<AssemblyName>ShareX.IndexerLib</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>

View file

@ -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 {

View file

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShareX.MediaLib</RootNamespace>
<AssemblyName>ShareX.MediaLib</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>

View file

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShareX.NativeMessagingHost</RootNamespace>
<AssemblyName>ShareX_NativeMessagingHost</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>

View file

@ -1,3 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /></startup></configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>

View file

@ -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()

View file

@ -1107,17 +1107,6 @@ internal class Resources {
}
}
/// <summary>
/// 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}°.
/// </summary>
internal static string RectangleRegion_GetRulerText_Ruler_info {
get {
return ResourceManager.GetString("RectangleRegion_GetRulerText_Ruler_info", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Rectangle capture transparent.
/// </summary>

View file

@ -139,11 +139,6 @@
<data name="image_resize" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\image-resize.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="RectangleRegion_GetRulerText_Ruler_info" xml:space="preserve">
<value>X: {0} / Y: {1} / X2: {2} / Y2: {3}
Width: {4} px / Height: {5} px
Distance: {6:0.00} px / Angle: {7:0.00}°</value>
</data>
<data name="arrow_circle_135_left" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\arrow-circle-135-left.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>

View file

@ -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))
{

View file

@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShareX.ScreenCaptureLib</RootNamespace>
<AssemblyName>ShareX.ScreenCaptureLib</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>
</TargetFrameworkProfile>

View file

@ -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]

View file

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShareX.Setup</RootNamespace>
<AssemblyName>ShareX.Setup</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>

View file

@ -43,6 +43,14 @@
</uap:SupportedFileTypes>
</uap3:FileTypeAssociation>
</uap:Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap3:FileTypeAssociation Name="sharex-image-effect" desktop2:UseUrl="false" Parameters='-ImageEffect "%1"'>
<uap:DisplayName>ShareX image effect</uap:DisplayName>
<uap:SupportedFileTypes>
<uap:FileType>.sxie</uap:FileType>
</uap:SupportedFileTypes>
</uap3:FileTypeAssociation>
</uap:Extension>
</Extensions>
</Application>
</Applications>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>

View file

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShareX.Steam</RootNamespace>
<AssemblyName>ShareX_Launcher</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>

View file

@ -1,3 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /></startup></configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>

View file

@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShareX.UploadersLib</RootNamespace>
<AssemblyName>ShareX.UploadersLib</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SignAssembly>false</SignAssembly>
<SccProjectName>

View file

@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShareX</RootNamespace>
<AssemblyName>ShareX</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ApplicationIcon>ShareX_Icon.ico</ApplicationIcon>
<FileUpgradeFlags>

View file

@ -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();

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
@ -13,7 +13,7 @@
<idn enabled="All" />
<iriParsing enabled="true" />
</uri>
<appSettings>
<add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
</appSettings>
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
</configuration>

View file

@ -3,7 +3,6 @@
<asmv3:application>
<asmv3:windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</asmv3:windowsSettings>
</asmv3:application>