mirror of
https://github.com/greenshot/greenshot
synced 2025-08-19 13:10:00 -07:00
Fixed DWM capture to work by cutting the corners only if Windows Vista / Windows 7. This change allowed to have the redmask capture to be removed, only need to freeze processes if a transparent capture is taken. This should speedup the capture and use less memory.
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2242 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
00c1c80004
commit
93d9a8cd0c
1 changed files with 73 additions and 76 deletions
|
@ -840,7 +840,6 @@ namespace GreenshotPlugin.Core {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Prepare the displaying of the Thumbnail
|
// Prepare the displaying of the Thumbnail
|
||||||
DWM_THUMBNAIL_PROPERTIES props = new DWM_THUMBNAIL_PROPERTIES();
|
DWM_THUMBNAIL_PROPERTIES props = new DWM_THUMBNAIL_PROPERTIES();
|
||||||
props.Opacity = (byte)255;
|
props.Opacity = (byte)255;
|
||||||
|
@ -855,16 +854,11 @@ namespace GreenshotPlugin.Core {
|
||||||
|
|
||||||
// Destination bitmap for the capture
|
// Destination bitmap for the capture
|
||||||
Bitmap capturedBitmap = null;
|
Bitmap capturedBitmap = null;
|
||||||
|
bool frozen = false;
|
||||||
try {
|
try {
|
||||||
this.FreezeWindow();
|
|
||||||
// Use red to make removal of the corners possible
|
|
||||||
tempForm.BackColor = Color.Red;
|
|
||||||
// Make sure everything is visible
|
|
||||||
tempForm.Refresh();
|
|
||||||
Application.DoEvents();
|
|
||||||
using (Bitmap redMask = WindowCapture.CaptureRectangle(captureRectangle)) {
|
|
||||||
// Check if we make a transparent capture
|
// Check if we make a transparent capture
|
||||||
if (windowCaptureMode == WindowCaptureMode.AeroTransparent) {
|
if (windowCaptureMode == WindowCaptureMode.AeroTransparent) {
|
||||||
|
frozen = this.FreezeWindow();
|
||||||
// Use white, later black to capture transparent
|
// Use white, later black to capture transparent
|
||||||
tempForm.BackColor = Color.White;
|
tempForm.BackColor = Color.White;
|
||||||
// Make sure everything is visible
|
// Make sure everything is visible
|
||||||
|
@ -908,7 +902,10 @@ namespace GreenshotPlugin.Core {
|
||||||
// Capture from the screen
|
// Capture from the screen
|
||||||
capturedBitmap = WindowCapture.CaptureRectangle(captureRectangle);
|
capturedBitmap = WindowCapture.CaptureRectangle(captureRectangle);
|
||||||
}
|
}
|
||||||
if (capturedBitmap != null && redMask != null) {
|
if (capturedBitmap != null) {
|
||||||
|
// Not needed for Windows 8
|
||||||
|
if (!(Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 2)) {
|
||||||
|
if (conf.WindowCaptureRemoveCorners && !Maximised) {
|
||||||
// Remove corners
|
// Remove corners
|
||||||
if (!Image.IsAlphaPixelFormat(capturedBitmap.PixelFormat)) {
|
if (!Image.IsAlphaPixelFormat(capturedBitmap.PixelFormat)) {
|
||||||
LOG.Debug("Changing pixelformat to Alpha for the RemoveCorners");
|
LOG.Debug("Changing pixelformat to Alpha for the RemoveCorners");
|
||||||
|
@ -916,21 +913,16 @@ namespace GreenshotPlugin.Core {
|
||||||
capturedBitmap.Dispose();
|
capturedBitmap.Dispose();
|
||||||
capturedBitmap = tmpBitmap;
|
capturedBitmap = tmpBitmap;
|
||||||
}
|
}
|
||||||
}
|
RemoveCorners(capturedBitmap);
|
||||||
if (capturedBitmap != null) {
|
|
||||||
if (conf.WindowCaptureRemoveCorners && !Maximised) {
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
// Make sure to ALWAYS unfreeze!!
|
// Make sure to ALWAYS unfreeze!!
|
||||||
|
if (frozen) {
|
||||||
this.UnfreezeWindow();
|
this.UnfreezeWindow();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
capture.Image = capturedBitmap;
|
capture.Image = capturedBitmap;
|
||||||
// Make sure the capture location is the location of the window, not the copy
|
// Make sure the capture location is the location of the window, not the copy
|
||||||
|
@ -954,17 +946,19 @@ 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 to remove the corners from.</param>
|
/// <param name="image">The bitmap to remove the corners from.</param>
|
||||||
/// <param name="cornerColor">The background color</param>
|
private void RemoveCorners(Bitmap image) {
|
||||||
private void RemoveCorners(Bitmap normalBitmap, Color cornerColor) {
|
int [] cornerRange = {5,3,2,1,1};
|
||||||
int borderWidth = User32.GetSystemMetrics(SystemMetric.SM_CXFRAME)+2;
|
using (BitmapBuffer buffer = new BitmapBuffer((Bitmap)image, false)) {
|
||||||
int borderHeight = User32.GetSystemMetrics(SystemMetric.SM_CYFRAME)+2;
|
buffer.Lock();
|
||||||
IntPtr regionHandle = GDI32.CreateRoundRectRgn(0, 0, normalBitmap.Width+1, normalBitmap.Height+1, borderWidth, borderHeight);
|
for (int y = 0; y < cornerRange.Length; y++) {
|
||||||
Region region = Region.FromHrgn(regionHandle);
|
for (int x = 0; x < cornerRange[y]; x++) {
|
||||||
GDI32.DeleteObject(regionHandle);
|
buffer.SetColorAt(x, y, Color.Transparent);
|
||||||
using (Graphics graphics = Graphics.FromImage(normalBitmap)) {
|
buffer.SetColorAt(image.Width-1-x, y, Color.Transparent);
|
||||||
graphics.ExcludeClip(region);
|
buffer.SetColorAt(image.Width-1-x, image.Height-1-y, Color.Transparent);
|
||||||
graphics.Clear(cornerColor);
|
buffer.SetColorAt(x, image.Height-1-y, Color.Transparent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1131,28 +1125,31 @@ namespace GreenshotPlugin.Core {
|
||||||
/// Freezes the process belonging to the window
|
/// Freezes the process belonging to the window
|
||||||
/// Warning: Use only if no other way!!
|
/// Warning: Use only if no other way!!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void FreezeWindow() {
|
private bool FreezeWindow() {
|
||||||
Process proc = Process.GetProcessById(this.ProcessId.ToInt32());
|
Process proc = Process.GetProcessById(this.ProcessId.ToInt32());
|
||||||
string processName = proc.ProcessName;
|
string processName = proc.ProcessName;
|
||||||
if (!CanFreezeOrUnfreeze(processName)) {
|
if (!CanFreezeOrUnfreeze(processName)) {
|
||||||
LOG.DebugFormat("Not freezing {0}", processName);
|
LOG.DebugFormat("Not freezing {0}", processName);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (!CanFreezeOrUnfreeze(Text)) {
|
if (!CanFreezeOrUnfreeze(Text)) {
|
||||||
LOG.DebugFormat("Not freezing {0}", processName);
|
LOG.DebugFormat("Not freezing {0}", processName);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
LOG.DebugFormat("Freezing process: {0}", processName);
|
LOG.DebugFormat("Freezing process: {0}", processName);
|
||||||
|
|
||||||
|
bool frozen = false;
|
||||||
|
|
||||||
foreach (ProcessThread pT in proc.Threads) {
|
foreach (ProcessThread pT in proc.Threads) {
|
||||||
IntPtr pOpenThread = Kernel32.OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);
|
IntPtr pOpenThread = Kernel32.OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);
|
||||||
|
|
||||||
if (pOpenThread == IntPtr.Zero) {
|
if (pOpenThread == IntPtr.Zero) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
frozen = true;
|
||||||
Kernel32.SuspendThread(pOpenThread);
|
Kernel32.SuspendThread(pOpenThread);
|
||||||
}
|
}
|
||||||
|
return frozen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue