mirror of
https://github.com/greenshot/greenshot
synced 2025-07-16 10:03:44 -07:00
Fixed a potential issue with GetWindowLong, using a wrapper which decides upon the IntPtr size which call needs to be made.
Fixed the corner cut to work with a CreateRoundRectRgn, but made if it cuts configurable so people can turn it off. Added a CountColor method to ImageHelper.cs, which should be used to check if PrintWindow functions properly. git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2236 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
0fd12ae5fc
commit
197d46c9b9
5 changed files with 71 additions and 68 deletions
|
@ -176,6 +176,9 @@ namespace GreenshotPlugin.Core {
|
||||||
[IniProperty("MinimizeWorkingSetSize", Description="Optimize memory footprint, but with a performance penalty!", DefaultValue="False")]
|
[IniProperty("MinimizeWorkingSetSize", Description="Optimize memory footprint, but with a performance penalty!", DefaultValue="False")]
|
||||||
public bool MinimizeWorkingSetSize;
|
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")]
|
[IniProperty("CheckForUnstable", Description = "Also check for unstable version updates", DefaultValue = "False")]
|
||||||
public bool CheckForUnstable;
|
public bool CheckForUnstable;
|
||||||
|
|
||||||
|
|
|
@ -1074,6 +1074,37 @@ namespace GreenshotPlugin.Core {
|
||||||
return ResizeBitmap(sourceBitmap, maintainAspectRatio, false, Color.Empty, newWidth, newHeight, out throwAway);
|
return ResizeBitmap(sourceBitmap, maintainAspectRatio, false, Color.Empty, newWidth, newHeight, out throwAway);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Count how many times the supplied color exists
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceBitmap">Bitmap to count the pixels of</param>
|
||||||
|
/// <param name="colorToCount">Color to count/param>
|
||||||
|
/// <param name="includeAlpha">true if Alpha needs to be checked</param>
|
||||||
|
/// <returns>int with the number of pixels which have colorToCount</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scale the bitmap, keeping aspect ratio, but the canvas will always have the specified size.
|
/// Scale the bitmap, keeping aspect ratio, but the canvas will always have the specified size.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -712,7 +712,7 @@ namespace GreenshotPlugin.Core {
|
||||||
|
|
||||||
public WindowStyleFlags WindowStyle {
|
public WindowStyleFlags WindowStyle {
|
||||||
get {
|
get {
|
||||||
return (WindowStyleFlags)User32.GetWindowLong(this.hWnd, (int)WindowLongIndex.GWL_STYLE);
|
return (WindowStyleFlags)User32.GetWindowLongWrapper(this.hWnd, (int)WindowLongIndex.GWL_STYLE);
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
User32.SetWindowLong(this.hWnd, (int)WindowLongIndex.GWL_STYLE, (uint)value);
|
User32.SetWindowLong(this.hWnd, (int)WindowLongIndex.GWL_STYLE, (uint)value);
|
||||||
|
@ -731,7 +731,7 @@ namespace GreenshotPlugin.Core {
|
||||||
|
|
||||||
public ExtendedWindowStyleFlags ExtendedWindowStyle {
|
public ExtendedWindowStyleFlags ExtendedWindowStyle {
|
||||||
get {
|
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.Dispose();
|
||||||
capturedBitmap = tmpBitmap;
|
capturedBitmap = tmpBitmap;
|
||||||
}
|
}
|
||||||
Color cornerColor = Color.Transparent;
|
}
|
||||||
if (!Image.IsAlphaPixelFormat(capturedBitmap.PixelFormat)) {
|
if (capturedBitmap != null) {
|
||||||
cornerColor = Color.FromArgb(255, conf.DWMBackgroundColor.R, conf.DWMBackgroundColor.G, conf.DWMBackgroundColor.B);
|
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 {
|
} finally {
|
||||||
|
@ -950,68 +954,17 @@ namespace GreenshotPlugin.Core {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper method to remove the corners from a DMW capture
|
/// Helper method to remove the corners from a DMW capture
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="normalBitmap">The bitmap taken which would normally be returned to the editor etc.</param>
|
/// <param name="normalBitmap">The bitmap to remove the corners from.</param>
|
||||||
/// <param name="redBitmap">The bitmap taken with a red background</param>
|
|
||||||
/// <param name="cornerColor">The background color</param>
|
/// <param name="cornerColor">The background color</param>
|
||||||
private void RemoveCorners(Bitmap normalBitmap, Bitmap redBitmap, Color cornerColor) {
|
private void RemoveCorners(Bitmap normalBitmap, Color cornerColor) {
|
||||||
const int thresholdTopLeft = 60;
|
int borderWidth = User32.GetSystemMetrics(SystemMetric.SM_CXFRAME)+2;
|
||||||
const int thresholdTopRight = 40;
|
int borderHeight = User32.GetSystemMetrics(SystemMetric.SM_CYFRAME)+2;
|
||||||
const int thresholdBottomLeft = 45;
|
IntPtr regionHandle = GDI32.CreateRoundRectRgn(0, 0, normalBitmap.Width+1, normalBitmap.Height+1, borderWidth, borderHeight);
|
||||||
const int thresholdBottomRight = 35;
|
Region region = Region.FromHrgn(regionHandle);
|
||||||
const int range = 15;
|
GDI32.DeleteObject(regionHandle);
|
||||||
using (BitmapBuffer redBuffer = new BitmapBuffer(redBitmap, false)) {
|
using (Graphics graphics = Graphics.FromImage(normalBitmap)) {
|
||||||
redBuffer.Lock();
|
graphics.ExcludeClip(region);
|
||||||
using (BitmapBuffer normalBuffer = new BitmapBuffer(normalBitmap, false)) {
|
graphics.Clear(cornerColor);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,8 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
public static extern int GetClipBox(IntPtr hdc, out RECT lprc);
|
public static extern int GetClipBox(IntPtr hdc, out RECT lprc);
|
||||||
[DllImport("gdi32", SetLastError = true)]
|
[DllImport("gdi32", SetLastError = true)]
|
||||||
public static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);
|
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)]
|
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
|
|
|
@ -353,7 +353,21 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
[DllImport("user32", SetLastError = true)]
|
[DllImport("user32", SetLastError = true)]
|
||||||
public static extern int SetWindowLong(IntPtr hWnd, int index, uint styleFlags);
|
public static extern int SetWindowLong(IntPtr hWnd, int index, uint styleFlags);
|
||||||
[DllImport("user32", EntryPoint="GetWindowLongPtr", SetLastError=true)]
|
[DllImport("user32", EntryPoint="GetWindowLongPtr", SetLastError=true)]
|
||||||
public extern static IntPtr GetWindowLongPtr(IntPtr hwnd, int nIndex);
|
public extern static uint GetWindowLongPtr(IntPtr hwnd, int nIndex);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wrapper for the GetWindowLong which decides if the system is 64-bit or not and calls the right one.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hwnd"></param>
|
||||||
|
/// <param name="nIndex"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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)]
|
[DllImport("user32", SetLastError = true)]
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
public static extern bool GetWindowInfo(IntPtr hwnd, ref WindowInfo pwi);
|
public static extern bool GetWindowInfo(IntPtr hwnd, ref WindowInfo pwi);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue