diff --git a/ShareX.HelpersLib/Helpers/ImageHelpers.cs b/ShareX.HelpersLib/Helpers/ImageHelpers.cs
index 5f80e86cc..9fb41280d 100644
--- a/ShareX.HelpersLib/Helpers/ImageHelpers.cs
+++ b/ShareX.HelpersLib/Helpers/ImageHelpers.cs
@@ -267,7 +267,7 @@ public static Bitmap CropBitmap(Bitmap bmp, Rectangle rect)
}
/// Automatically crop image to remove transparent outside area.
- public static Bitmap AutoCropImage(Bitmap bmp)
+ public static Bitmap AutoCropTransparent(Bitmap bmp)
{
Rectangle source = new Rectangle(0, 0, bmp.Width, bmp.Height);
Rectangle rect = source;
@@ -354,7 +354,7 @@ public static Bitmap AutoCropImage(Bitmap bmp)
}
/// Automatically crop image to remove transparent outside area. Only checks center pixels.
- public static Bitmap QuickAutoCropImage(Bitmap bmp)
+ public static Bitmap QuickAutoCropTransparent(Bitmap bmp)
{
Rectangle source = new Rectangle(0, 0, bmp.Width, bmp.Height);
Rectangle rect = source;
@@ -1645,5 +1645,126 @@ public static void DrawColorPickerIcon(Graphics g, Color color, Rectangle rect,
g.DrawRectangleProper(Pens.Black, holeRect);
}
}
+
+ public static Rectangle FindAutoCropRectangle(Bitmap bmp, bool sameColorCrop = false)
+ {
+ Rectangle source = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ Rectangle crop = source;
+
+ using (UnsafeBitmap unsafeBitmap = new UnsafeBitmap(bmp, true, ImageLockMode.ReadOnly))
+ {
+ bool leave = false;
+
+ ColorBgra checkColor = unsafeBitmap.GetPixel(0, 0);
+
+ // Find X (Left to right)
+ for (int x = 0; x < bmp.Width && !leave; x++)
+ {
+ for (int y = 0; y < bmp.Height; y++)
+ {
+ if (unsafeBitmap.GetPixel(x, y) != checkColor)
+ {
+ crop.X = x;
+ leave = true;
+ break;
+ }
+ }
+ }
+
+ // If all pixels same color
+ if (!leave)
+ {
+ return crop;
+ }
+
+ leave = false;
+
+ if (!sameColorCrop)
+ {
+ checkColor = unsafeBitmap.GetPixel(0, 0);
+ }
+
+ // Find Y (Top to bottom)
+ for (int y = 0; y < bmp.Height && !leave; y++)
+ {
+ for (int x = 0; x < bmp.Width; x++)
+ {
+ if (unsafeBitmap.GetPixel(x, y) != checkColor)
+ {
+ crop.Y = y;
+ leave = true;
+ break;
+ }
+ }
+ }
+
+ leave = false;
+
+ if (!sameColorCrop)
+ {
+ checkColor = unsafeBitmap.GetPixel(bmp.Width - 1, 0);
+ }
+
+ // Find Width (Right to left)
+ for (int x = bmp.Width - 1; x >= 0 && !leave; x--)
+ {
+ for (int y = 0; y < bmp.Height; y++)
+ {
+ if (unsafeBitmap.GetPixel(x, y) != checkColor)
+ {
+ crop.Width = x - crop.X + 1;
+ leave = true;
+ break;
+ }
+ }
+ }
+
+ leave = false;
+
+ if (!sameColorCrop)
+ {
+ checkColor = unsafeBitmap.GetPixel(0, bmp.Height - 1);
+ }
+
+ // Find Height (Bottom to top)
+ for (int y = bmp.Height - 1; y >= 0 && !leave; y--)
+ {
+ for (int x = 0; x < bmp.Width; x++)
+ {
+ if (unsafeBitmap.GetPixel(x, y) != checkColor)
+ {
+ crop.Height = y - crop.Y + 1;
+ leave = true;
+ break;
+ }
+ }
+ }
+ }
+
+ return crop;
+ }
+
+ ///
+ /// If crop rectangle and source image rectangle is same then null will be returned.
+ /// After auto crop, source image will be disposed.
+ ///
+ public static Bitmap AutoCropImage(Bitmap bmp, bool sameColorCrop = false)
+ {
+ Rectangle source = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ Rectangle rect = FindAutoCropRectangle(bmp, sameColorCrop);
+
+ if (source != rect)
+ {
+ Bitmap croppedBitmap = CropBitmap(bmp, rect);
+
+ if (croppedBitmap != null)
+ {
+ bmp.Dispose();
+ return croppedBitmap;
+ }
+ }
+
+ return null;
+ }
}
}
\ No newline at end of file
diff --git a/ShareX.ScreenCaptureLib/Shapes/ShapeManager.cs b/ShareX.ScreenCaptureLib/Shapes/ShapeManager.cs
index 4bd7972ff..f673939af 100644
--- a/ShareX.ScreenCaptureLib/Shapes/ShapeManager.cs
+++ b/ShareX.ScreenCaptureLib/Shapes/ShapeManager.cs
@@ -1430,6 +1430,16 @@ private void ChangeCanvasSize()
}
}
+ private void AutoCropImage()
+ {
+ Bitmap bmp = ImageHelpers.AutoCropImage((Bitmap)Form.Canvas);
+
+ if (bmp != null)
+ {
+ UpdateCanvas(bmp);
+ }
+ }
+
private void RotateImage(RotateFlipType type)
{
Image img = (Image)Form.Canvas.Clone();
diff --git a/ShareX.ScreenCaptureLib/Shapes/ShapeManagerMenu.cs b/ShareX.ScreenCaptureLib/Shapes/ShapeManagerMenu.cs
index a4d4750a7..0c5305e5c 100644
--- a/ShareX.ScreenCaptureLib/Shapes/ShapeManagerMenu.cs
+++ b/ShareX.ScreenCaptureLib/Shapes/ShapeManagerMenu.cs
@@ -618,6 +618,11 @@ internal void CreateToolbar()
tsmiCanvasSize.MouseDown += (sender, e) => ChangeCanvasSize();
tsddbImage.DropDownItems.Add(tsmiCanvasSize);
+ ToolStripMenuItem tsmiAutoCropImage = new ToolStripMenuItem("Auto crop image");
+ tsmiAutoCropImage.Image = Resources.image_crop;
+ tsmiAutoCropImage.MouseDown += (sender, e) => AutoCropImage();
+ tsddbImage.DropDownItems.Add(tsmiAutoCropImage);
+
tsddbImage.DropDownItems.Add(new ToolStripSeparator());
ToolStripMenuItem tsmiRotate90Clockwise = new ToolStripMenuItem(Resources.ShapeManager_CreateToolbar_Rotate90Clockwise);