mirror of
https://github.com/ShareX/ShareX.git
synced 2025-12-28 07:54:19 +00:00
Added "Spotlight" tool to image editor
This commit is contained in:
parent
e26232d068
commit
874c7eee7f
@ -3245,6 +3245,15 @@ namespace ShareX.HelpersLib.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Spotlight.
|
||||
/// </summary>
|
||||
internal static string ShapeType_ToolSpotlight {
|
||||
get {
|
||||
return ResourceManager.GetString("ShapeType_ToolSpotlight", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||
/// </summary>
|
||||
|
||||
@ -1323,4 +1323,7 @@ Would you like to download and install it?</value>
|
||||
<data name="HotkeyType_AnalyzeImage" xml:space="preserve">
|
||||
<value>Analyze image</value>
|
||||
</data>
|
||||
<data name="ShapeType_ToolSpotlight" xml:space="preserve">
|
||||
<value>Spotlight</value>
|
||||
</data>
|
||||
</root>
|
||||
@ -315,6 +315,7 @@ namespace ShareX.ScreenCaptureLib
|
||||
EffectBlur,
|
||||
EffectPixelate,
|
||||
EffectHighlight,
|
||||
ToolSpotlight,
|
||||
ToolCrop,
|
||||
ToolCutOut
|
||||
}
|
||||
|
||||
@ -33,8 +33,10 @@ namespace ShareX.ScreenCaptureLib
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public Color ButtonColor { get; set; }
|
||||
public int ButtonDepth { get; set; } = 3;
|
||||
public Color ButtonDepthColor => ColorHelpers.DarkerColor(ButtonColor, 0.5f);
|
||||
public Color IconColor { get; set; }
|
||||
public int ButtonDepth { get; set; } = 5;
|
||||
public Color ButtonDepthColor => ColorHelpers.DarkerColor(ButtonColor, 0.3f);
|
||||
public Color IconDepthColor => ColorHelpers.DarkerColor(IconColor, 0.7f);
|
||||
|
||||
public override void OnDraw(Graphics g)
|
||||
{
|
||||
@ -66,12 +68,13 @@ namespace ShareX.ScreenCaptureLib
|
||||
|
||||
g.SmoothingMode = SmoothingMode.None;
|
||||
|
||||
using (Font font = new Font("Arial", 18))
|
||||
using (Font font = new Font("Arial", 20))
|
||||
using (StringFormat sf = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center })
|
||||
using (SolidBrush textDepthBrush = new SolidBrush(ButtonDepthColor))
|
||||
using (SolidBrush textBrush = new SolidBrush(IconColor))
|
||||
using (SolidBrush textDepthBrush = new SolidBrush(IconDepthColor))
|
||||
{
|
||||
g.DrawString(Text, font, textDepthBrush, rect.LocationOffset(0, 4), sf);
|
||||
g.DrawString(Text, font, Brushes.White, rect.LocationOffset(0, 2), sf);
|
||||
g.DrawString(Text, font, textDepthBrush, rect.LocationOffset(0, -1), sf);
|
||||
g.DrawString(Text, font, textBrush, rect.LocationOffset(0, 2), sf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +77,8 @@ namespace ShareX.ScreenCaptureLib
|
||||
|
||||
public void CreateShapesMemento()
|
||||
{
|
||||
if (!shapeManager.IsCurrentShapeTypeRegion && shapeManager.CurrentTool != ShapeType.ToolCrop && shapeManager.CurrentTool != ShapeType.ToolCutOut)
|
||||
if (!shapeManager.IsCurrentShapeTypeRegion && shapeManager.CurrentTool != ShapeType.ToolCrop &&
|
||||
shapeManager.CurrentTool != ShapeType.ToolCutOut && shapeManager.CurrentTool != ShapeType.ToolSpotlight)
|
||||
{
|
||||
ImageEditorMemento memento = GetMementoFromShapes();
|
||||
AddMemento(memento);
|
||||
|
||||
@ -666,6 +666,16 @@ namespace ShareX.ScreenCaptureLib.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap flashlight_shine {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("flashlight_shine", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
||||
@ -857,4 +857,7 @@ Would you like to save the changes before closing the image editor?</value>
|
||||
<data name="RulerBottom" xml:space="preserve">
|
||||
<value>Bottom</value>
|
||||
</data>
|
||||
<data name="flashlight_shine" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\flashlight-shine.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
BIN
ShareX.ScreenCaptureLib/Resources/flashlight-shine.png
Normal file
BIN
ShareX.ScreenCaptureLib/Resources/flashlight-shine.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 657 B |
@ -1223,6 +1223,9 @@ namespace ShareX.ScreenCaptureLib
|
||||
case ShapeType.EffectHighlight:
|
||||
shape = new HighlightEffectShape();
|
||||
break;
|
||||
case ShapeType.ToolSpotlight:
|
||||
shape = new SpotlightTool();
|
||||
break;
|
||||
case ShapeType.ToolCrop:
|
||||
shape = new CropTool();
|
||||
break;
|
||||
@ -1963,6 +1966,13 @@ namespace ShareX.ScreenCaptureLib
|
||||
}
|
||||
}
|
||||
|
||||
public void SpotlightArea(RectangleF rect, int dim, int blur)
|
||||
{
|
||||
history.CreateCanvasMemento();
|
||||
Bitmap bmp = Spotlight(rect.Round(), dim, blur);
|
||||
UpdateCanvas(bmp);
|
||||
}
|
||||
|
||||
public Bitmap CropImage(RectangleF rect, bool onlyIfSizeDifferent = false)
|
||||
{
|
||||
rect = CaptureHelpers.ScreenToClient(rect.Round());
|
||||
@ -1993,15 +2003,50 @@ namespace ShareX.ScreenCaptureLib
|
||||
if (isHorizontal && cropRect.Width > 0)
|
||||
{
|
||||
CollapseAllHorizontal(rect.X, rect.Width);
|
||||
UpdateCanvas(ImageHelpers.CutOutBitmapMiddle(Form.Canvas, Orientation.Horizontal, cropRect.X, cropRect.Width, AnnotationOptions.CutOutEffectType, AnnotationOptions.CutOutEffectSize, AnnotationOptions.CutOutBackgroundColor));
|
||||
UpdateCanvas(ImageHelpers.CutOutBitmapMiddle(Form.Canvas, Orientation.Horizontal, cropRect.X, cropRect.Width,
|
||||
AnnotationOptions.CutOutEffectType, AnnotationOptions.CutOutEffectSize, AnnotationOptions.CutOutBackgroundColor));
|
||||
}
|
||||
else if (!isHorizontal && cropRect.Height > 0)
|
||||
{
|
||||
CollapseAllVertical(rect.Y, rect.Height);
|
||||
UpdateCanvas(ImageHelpers.CutOutBitmapMiddle(Form.Canvas, Orientation.Vertical, cropRect.Y, cropRect.Height, AnnotationOptions.CutOutEffectType, AnnotationOptions.CutOutEffectSize, AnnotationOptions.CutOutBackgroundColor));
|
||||
UpdateCanvas(ImageHelpers.CutOutBitmapMiddle(Form.Canvas, Orientation.Vertical, cropRect.Y, cropRect.Height,
|
||||
AnnotationOptions.CutOutEffectType, AnnotationOptions.CutOutEffectSize, AnnotationOptions.CutOutBackgroundColor));
|
||||
}
|
||||
}
|
||||
|
||||
public Bitmap Spotlight(Rectangle rect, int dim, int blur)
|
||||
{
|
||||
Bitmap bmp = (Bitmap)Form.Canvas.Clone();
|
||||
|
||||
if (dim > 0)
|
||||
{
|
||||
float value = 1f - dim / 100f;
|
||||
Bitmap bmpDimmed = ColorMatrixManager.Contrast(value).Apply(bmp);
|
||||
bmp.Dispose();
|
||||
bmp = bmpDimmed;
|
||||
}
|
||||
|
||||
if (blur > 0)
|
||||
{
|
||||
ImageHelpers.BoxBlur(bmp, blur);
|
||||
}
|
||||
|
||||
using (Graphics g = Graphics.FromImage(bmp))
|
||||
{
|
||||
Bitmap selection = CropImage(rect);
|
||||
|
||||
Rectangle adjustedRect = CaptureHelpers.ScreenToClient(rect);
|
||||
Point offset = CaptureHelpers.ScreenToClient(Form.CanvasRectangle.Location.Round());
|
||||
adjustedRect.X -= offset.X;
|
||||
adjustedRect.Y -= offset.Y;
|
||||
Rectangle cropRect = Rectangle.Intersect(new Rectangle(0, 0, Form.Canvas.Width, Form.Canvas.Height), adjustedRect);
|
||||
|
||||
g.DrawImage(selection, cropRect);
|
||||
}
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public Color GetColor(Bitmap bmp, Point pos)
|
||||
{
|
||||
if (bmp != null)
|
||||
|
||||
@ -221,7 +221,7 @@ namespace ShareX.ScreenCaptureLib
|
||||
{
|
||||
tsMain.Items.Add(new ToolStripSeparator());
|
||||
}
|
||||
else if (shapeType == ShapeType.ToolCrop || shapeType == ShapeType.ToolCutOut)
|
||||
else if (shapeType == ShapeType.ToolCrop || shapeType == ShapeType.ToolCutOut || shapeType == ShapeType.ToolSpotlight)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -306,6 +306,9 @@ namespace ShareX.ScreenCaptureLib
|
||||
case ShapeType.EffectHighlight:
|
||||
img = Resources.highlighter_text;
|
||||
break;
|
||||
case ShapeType.ToolSpotlight:
|
||||
img = Resources.flashlight_shine;
|
||||
break;
|
||||
case ShapeType.ToolCrop:
|
||||
img = Resources.image_crop;
|
||||
break;
|
||||
|
||||
@ -36,7 +36,7 @@ namespace ShareX.ScreenCaptureLib
|
||||
public override bool LimitRectangleToInsideCanvas { get; } = true;
|
||||
|
||||
private ImageEditorButton confirmButton, cancelButton;
|
||||
private Size buttonSize = new Size(80, 40);
|
||||
private Size buttonSize = new Size(50, 40);
|
||||
private int buttonOffset = 15;
|
||||
|
||||
public override void OnUpdate()
|
||||
@ -78,7 +78,8 @@ namespace ShareX.ScreenCaptureLib
|
||||
confirmButton = new ImageEditorButton()
|
||||
{
|
||||
Text = "\u2714",
|
||||
ButtonColor = Color.ForestGreen,
|
||||
ButtonColor = ShareXResources.Theme.LightBackgroundColor,
|
||||
IconColor = Color.ForestGreen,
|
||||
Rectangle = new Rectangle(new Point(), buttonSize),
|
||||
Visible = true
|
||||
};
|
||||
@ -90,7 +91,8 @@ namespace ShareX.ScreenCaptureLib
|
||||
cancelButton = new ImageEditorButton()
|
||||
{
|
||||
Text = "\u2716",
|
||||
ButtonColor = Color.FromArgb(227, 45, 45),
|
||||
ButtonColor = ShareXResources.Theme.LightBackgroundColor,
|
||||
IconColor = Color.FromArgb(227, 45, 45),
|
||||
Rectangle = new Rectangle(new Point(), buttonSize),
|
||||
Visible = true
|
||||
};
|
||||
|
||||
@ -69,7 +69,7 @@ namespace ShareX.ScreenCaptureLib
|
||||
}
|
||||
|
||||
private ImageEditorButton confirmButton, cancelButton;
|
||||
private Size buttonSize = new Size(80, 40);
|
||||
private Size buttonSize = new Size(50, 40);
|
||||
private int buttonOffset = 15;
|
||||
|
||||
public override void ShowNodes()
|
||||
@ -149,7 +149,8 @@ namespace ShareX.ScreenCaptureLib
|
||||
confirmButton = new ImageEditorButton()
|
||||
{
|
||||
Text = "\u2714",
|
||||
ButtonColor = Color.ForestGreen,
|
||||
ButtonColor = ShareXResources.Theme.LightBackgroundColor,
|
||||
IconColor = Color.ForestGreen,
|
||||
Rectangle = new Rectangle(new Point(), buttonSize),
|
||||
Visible = true
|
||||
};
|
||||
@ -161,7 +162,8 @@ namespace ShareX.ScreenCaptureLib
|
||||
cancelButton = new ImageEditorButton()
|
||||
{
|
||||
Text = "\u2716",
|
||||
ButtonColor = Color.FromArgb(227, 45, 45),
|
||||
ButtonColor = ShareXResources.Theme.LightBackgroundColor,
|
||||
IconColor = Color.FromArgb(227, 45, 45),
|
||||
Rectangle = new Rectangle(new Point(), buttonSize),
|
||||
Visible = true
|
||||
};
|
||||
|
||||
148
ShareX.ScreenCaptureLib/Shapes/Tool/SpotlightTool.cs
Normal file
148
ShareX.ScreenCaptureLib/Shapes/Tool/SpotlightTool.cs
Normal file
@ -0,0 +1,148 @@
|
||||
#region License Information (GPL v3)
|
||||
|
||||
/*
|
||||
ShareX - A program that allows you to take screenshots and share any file type
|
||||
Copyright (c) 2007-2025 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.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ShareX.ScreenCaptureLib
|
||||
{
|
||||
public class SpotlightTool : BaseTool
|
||||
{
|
||||
public override ShapeType ShapeType { get; } = ShapeType.ToolSpotlight;
|
||||
|
||||
public override bool LimitRectangleToInsideCanvas { get; } = true;
|
||||
public int Dim { get; set; } = 30;
|
||||
public int Blur { get; set; } = 10;
|
||||
|
||||
private ImageEditorButton confirmButton, cancelButton;
|
||||
private Size buttonSize = new Size(50, 40);
|
||||
private int buttonOffset = 15;
|
||||
|
||||
public override void OnUpdate()
|
||||
{
|
||||
base.OnUpdate();
|
||||
|
||||
if (confirmButton != null && cancelButton != null)
|
||||
{
|
||||
if (Rectangle.Bottom + buttonOffset + buttonSize.Height > Manager.Form.ClientArea.Bottom &&
|
||||
Rectangle.Width > (buttonSize.Width * 2) + (buttonOffset * 3) &&
|
||||
Rectangle.Height > buttonSize.Height + (buttonOffset * 2))
|
||||
{
|
||||
confirmButton.Rectangle = new RectangleF(Rectangle.Right - (buttonOffset * 2) - (buttonSize.Width * 2),
|
||||
Rectangle.Bottom - buttonOffset - buttonSize.Height, buttonSize.Width, buttonSize.Height);
|
||||
cancelButton.Rectangle = new RectangleF(Rectangle.Right - buttonOffset - buttonSize.Width,
|
||||
Rectangle.Bottom - buttonOffset - buttonSize.Height, buttonSize.Width, buttonSize.Height);
|
||||
}
|
||||
else
|
||||
{
|
||||
confirmButton.Rectangle = new RectangleF(Rectangle.Right - (buttonSize.Width * 2) - buttonOffset,
|
||||
Rectangle.Bottom + buttonOffset, buttonSize.Width, buttonSize.Height);
|
||||
cancelButton.Rectangle = new RectangleF(Rectangle.Right - buttonSize.Width,
|
||||
Rectangle.Bottom + buttonOffset, buttonSize.Width, buttonSize.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDraw(Graphics g)
|
||||
{
|
||||
if (IsValidShape)
|
||||
{
|
||||
Manager.DrawRegionArea(g, Rectangle, true, Manager.Options.ShowInfo);
|
||||
g.DrawCross(Pens.Black, Rectangle.Center(), 10);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnCreated()
|
||||
{
|
||||
confirmButton = new ImageEditorButton()
|
||||
{
|
||||
Text = "\u2714",
|
||||
ButtonColor = ShareXResources.Theme.LightBackgroundColor,
|
||||
IconColor = Color.ForestGreen,
|
||||
Rectangle = new Rectangle(new Point(), buttonSize),
|
||||
Visible = true
|
||||
};
|
||||
confirmButton.MouseDown += ConfirmButton_MousePressed;
|
||||
confirmButton.MouseEnter += () => Manager.Form.Cursor = Cursors.Hand;
|
||||
confirmButton.MouseLeave += () => Manager.Form.SetDefaultCursor();
|
||||
Manager.DrawableObjects.Add(confirmButton);
|
||||
|
||||
cancelButton = new ImageEditorButton()
|
||||
{
|
||||
Text = "\u2716",
|
||||
ButtonColor = ShareXResources.Theme.LightBackgroundColor,
|
||||
IconColor = Color.FromArgb(227, 45, 45),
|
||||
Rectangle = new Rectangle(new Point(), buttonSize),
|
||||
Visible = true
|
||||
};
|
||||
cancelButton.MouseDown += CancelButton_MousePressed;
|
||||
cancelButton.MouseEnter += () => Manager.Form.Cursor = Cursors.Hand;
|
||||
cancelButton.MouseLeave += () => Manager.Form.SetDefaultCursor();
|
||||
Manager.DrawableObjects.Add(cancelButton);
|
||||
}
|
||||
|
||||
private void ConfirmButton_MousePressed(object sender, MouseEventArgs e)
|
||||
{
|
||||
Manager.SpotlightArea(Rectangle, Dim, Blur);
|
||||
Remove();
|
||||
}
|
||||
|
||||
private void CancelButton_MousePressed(object sender, MouseEventArgs e)
|
||||
{
|
||||
Remove();
|
||||
}
|
||||
|
||||
public override void Remove()
|
||||
{
|
||||
base.Remove();
|
||||
|
||||
if (Options.SwitchToSelectionToolAfterDrawing)
|
||||
{
|
||||
Manager.CurrentTool = ShapeType.ToolSelect;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
if ((confirmButton != null && confirmButton.IsCursorHover) || (cancelButton != null && cancelButton.IsCursorHover))
|
||||
{
|
||||
Manager.Form.SetDefaultCursor();
|
||||
}
|
||||
|
||||
if (confirmButton != null)
|
||||
{
|
||||
Manager.DrawableObjects.Remove(confirmButton);
|
||||
}
|
||||
|
||||
if (cancelButton != null)
|
||||
{
|
||||
Manager.DrawableObjects.Remove(cancelButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user