diff --git a/GreenshotPlugin/Core/CoreConfiguration.cs b/GreenshotPlugin/Core/CoreConfiguration.cs index 73468af52..6bed458ef 100644 --- a/GreenshotPlugin/Core/CoreConfiguration.cs +++ b/GreenshotPlugin/Core/CoreConfiguration.cs @@ -176,6 +176,9 @@ namespace GreenshotPlugin.Core { [IniProperty("MinimizeWorkingSetSize", Description="Optimize memory footprint, but with a performance penalty!", DefaultValue="False")] public bool MinimizeWorkingSetSize; + [IniProperty("WindowCaptureRemoveCorners", Description = "Remove the corners from a window capture", DefaultValue = "True")] + public bool WindowCaptureRemoveCorners; + [IniProperty("CheckForUnstable", Description = "Also check for unstable version updates", DefaultValue = "False")] public bool CheckForUnstable; diff --git a/GreenshotPlugin/Core/ImageHelper.cs b/GreenshotPlugin/Core/ImageHelper.cs index f1685d370..71c1c9777 100644 --- a/GreenshotPlugin/Core/ImageHelper.cs +++ b/GreenshotPlugin/Core/ImageHelper.cs @@ -1074,6 +1074,37 @@ namespace GreenshotPlugin.Core { return ResizeBitmap(sourceBitmap, maintainAspectRatio, false, Color.Empty, newWidth, newHeight, out throwAway); } + /// + /// Count how many times the supplied color exists + /// + /// Bitmap to count the pixels of + /// Color to count/param> + /// true if Alpha needs to be checked + /// int with the number of pixels which have colorToCount + public static int CountColor(Bitmap sourceBitmap, Color colorToCount, bool includeAlpha) { + int colors = 0; + int toCount = colorToCount.ToArgb(); + if (!includeAlpha) { + toCount = toCount & 0xffffff; + } + using (BitmapBuffer bb = new BitmapBuffer(sourceBitmap, true)) { + bb.Lock(); + for (int y = 0; y < bb.Height; y++) { + for (int x = 0; x < bb.Width; x++) { + int bitmapcolor = bb.GetColorAt(x, y).ToArgb(); + if (!includeAlpha) { + bitmapcolor = bitmapcolor & 0xffffff; + } + if (bitmapcolor == toCount) { + colors++; + } + } + } + bb.Unlock(); + return colors; + } + } + /// /// Scale the bitmap, keeping aspect ratio, but the canvas will always have the specified size. /// diff --git a/GreenshotPlugin/Core/WindowsHelper.cs b/GreenshotPlugin/Core/WindowsHelper.cs index 1609351b8..1cd7de799 100644 --- a/GreenshotPlugin/Core/WindowsHelper.cs +++ b/GreenshotPlugin/Core/WindowsHelper.cs @@ -712,7 +712,7 @@ namespace GreenshotPlugin.Core { public WindowStyleFlags WindowStyle { get { - return (WindowStyleFlags)User32.GetWindowLong(this.hWnd, (int)WindowLongIndex.GWL_STYLE); + return (WindowStyleFlags)User32.GetWindowLongWrapper(this.hWnd, (int)WindowLongIndex.GWL_STYLE); } set { User32.SetWindowLong(this.hWnd, (int)WindowLongIndex.GWL_STYLE, (uint)value); @@ -731,7 +731,7 @@ namespace GreenshotPlugin.Core { public ExtendedWindowStyleFlags ExtendedWindowStyle { get { - return (ExtendedWindowStyleFlags)User32.GetWindowLong(this.hWnd, (int)WindowLongIndex.GWL_EXSTYLE); + return (ExtendedWindowStyleFlags)User32.GetWindowLongWrapper(this.hWnd, (int)WindowLongIndex.GWL_EXSTYLE); } } @@ -916,11 +916,15 @@ namespace GreenshotPlugin.Core { capturedBitmap.Dispose(); capturedBitmap = tmpBitmap; } - Color cornerColor = Color.Transparent; - if (!Image.IsAlphaPixelFormat(capturedBitmap.PixelFormat)) { - cornerColor = Color.FromArgb(255, conf.DWMBackgroundColor.R, conf.DWMBackgroundColor.G, conf.DWMBackgroundColor.B); + } + if (capturedBitmap != null) { + if (conf.WindowCaptureRemoveCorners) { + Color cornerColor = Color.Transparent; + if (!Image.IsAlphaPixelFormat(capturedBitmap.PixelFormat)) { + cornerColor = Color.FromArgb(255, conf.DWMBackgroundColor.R, conf.DWMBackgroundColor.G, conf.DWMBackgroundColor.B); + } + RemoveCorners(capturedBitmap, cornerColor); } - RemoveCorners(capturedBitmap, redMask, cornerColor); } } } finally { @@ -950,68 +954,17 @@ namespace GreenshotPlugin.Core { /// /// Helper method to remove the corners from a DMW capture /// - /// The bitmap taken which would normally be returned to the editor etc. - /// The bitmap taken with a red background + /// The bitmap to remove the corners from. /// The background color - private void RemoveCorners(Bitmap normalBitmap, Bitmap redBitmap, Color cornerColor) { - const int thresholdTopLeft = 60; - const int thresholdTopRight = 40; - const int thresholdBottomLeft = 45; - const int thresholdBottomRight = 35; - const int range = 15; - using (BitmapBuffer redBuffer = new BitmapBuffer(redBitmap, false)) { - redBuffer.Lock(); - using (BitmapBuffer normalBuffer = new BitmapBuffer(normalBitmap, false)) { - normalBuffer.Lock(); - // top left - for (int y = 0; y < range; y++) { - for (int x = 0; x < range; x++) { - Color redBufferPixel = redBuffer.GetColorAt(x, y); - Color normalBufferPixel = normalBuffer.GetColorAt(x, y); - int redDiff = redBufferPixel.R - normalBufferPixel.R; - if (redDiff < thresholdTopLeft) { - break; - } - normalBuffer.SetColorAt(x, y, cornerColor); - } - } - // top right - for (int y = 0; y < range; y++) { - for (int x = normalBitmap.Width-1; x > normalBitmap.Width - range; x--) { - Color redBufferPixel = redBuffer.GetColorAt(x, y); - Color normalBufferPixel = normalBuffer.GetColorAt(x, y); - int redDiff = redBufferPixel.R - normalBufferPixel.R; - if (redDiff < thresholdTopRight) { - break; - } - normalBuffer.SetColorAt(x, y, cornerColor); - } - } - // bottom left - for (int y = normalBitmap.Height-1; y > normalBitmap.Height - range; y--) { - for (int x = 0; x < range; x++) { - Color redBufferPixel = redBuffer.GetColorAt(x, y); - Color normalBufferPixel = normalBuffer.GetColorAt(x, y); - int redDiff = redBufferPixel.R - normalBufferPixel.R; - if (redDiff < thresholdBottomLeft) { - break; - } - normalBuffer.SetColorAt(x, y, cornerColor); - } - } - // Bottom right - for (int y = normalBitmap.Height-1; y > normalBitmap.Height - range; y--) { - for (int x = normalBitmap.Width-1; x > normalBitmap.Width - range; x--) { - Color redBufferPixel = redBuffer.GetColorAt(x, y); - Color normalBufferPixel = normalBuffer.GetColorAt(x, y); - int redDiff = redBufferPixel.R - normalBufferPixel.R; - if (redDiff < thresholdBottomRight) { - break; - } - normalBuffer.SetColorAt(x, y, cornerColor); - } - } - } + private void RemoveCorners(Bitmap normalBitmap, Color cornerColor) { + int borderWidth = User32.GetSystemMetrics(SystemMetric.SM_CXFRAME)+2; + int borderHeight = User32.GetSystemMetrics(SystemMetric.SM_CYFRAME)+2; + IntPtr regionHandle = GDI32.CreateRoundRectRgn(0, 0, normalBitmap.Width+1, normalBitmap.Height+1, borderWidth, borderHeight); + Region region = Region.FromHrgn(regionHandle); + GDI32.DeleteObject(regionHandle); + using (Graphics graphics = Graphics.FromImage(normalBitmap)) { + graphics.ExcludeClip(region); + graphics.Clear(cornerColor); } } diff --git a/GreenshotPlugin/UnmanagedHelpers/GDI32.cs b/GreenshotPlugin/UnmanagedHelpers/GDI32.cs index 8868271c1..ec8422584 100644 --- a/GreenshotPlugin/UnmanagedHelpers/GDI32.cs +++ b/GreenshotPlugin/UnmanagedHelpers/GDI32.cs @@ -45,6 +45,8 @@ namespace GreenshotPlugin.UnmanagedHelpers { public static extern int GetClipBox(IntPtr hdc, out RECT lprc); [DllImport("gdi32", SetLastError = true)] public static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos); + [DllImport("gdi32")] + public static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int cx, int cy); } [StructLayout(LayoutKind.Sequential, Pack = 2)] diff --git a/GreenshotPlugin/UnmanagedHelpers/User32.cs b/GreenshotPlugin/UnmanagedHelpers/User32.cs index e82a53e1b..c6c846c29 100644 --- a/GreenshotPlugin/UnmanagedHelpers/User32.cs +++ b/GreenshotPlugin/UnmanagedHelpers/User32.cs @@ -353,7 +353,21 @@ namespace GreenshotPlugin.UnmanagedHelpers { [DllImport("user32", SetLastError = true)] public static extern int SetWindowLong(IntPtr hWnd, int index, uint styleFlags); [DllImport("user32", EntryPoint="GetWindowLongPtr", SetLastError=true)] - public extern static IntPtr GetWindowLongPtr(IntPtr hwnd, int nIndex); + public extern static uint GetWindowLongPtr(IntPtr hwnd, int nIndex); + + /// + /// Wrapper for the GetWindowLong which decides if the system is 64-bit or not and calls the right one. + /// + /// + /// + /// + public static uint GetWindowLongWrapper(IntPtr hwnd, int nIndex) { + if (IntPtr.Size == 8) { + return GetWindowLongPtr(hwnd, nIndex); + } else { + return GetWindowLong(hwnd, nIndex); + } + } [DllImport("user32", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetWindowInfo(IntPtr hwnd, ref WindowInfo pwi);