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:
RKrom 2012-11-05 19:07:39 +00:00
commit 93d9a8cd0c

View file

@ -840,7 +840,6 @@ namespace GreenshotPlugin.Core {
}
}
// Prepare the displaying of the Thumbnail
DWM_THUMBNAIL_PROPERTIES props = new DWM_THUMBNAIL_PROPERTIES();
props.Opacity = (byte)255;
@ -855,16 +854,11 @@ namespace GreenshotPlugin.Core {
// Destination bitmap for the capture
Bitmap capturedBitmap = null;
bool frozen = false;
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
if (windowCaptureMode == WindowCaptureMode.AeroTransparent) {
frozen = this.FreezeWindow();
// Use white, later black to capture transparent
tempForm.BackColor = Color.White;
// Make sure everything is visible
@ -908,7 +902,10 @@ namespace GreenshotPlugin.Core {
// Capture from the screen
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
if (!Image.IsAlphaPixelFormat(capturedBitmap.PixelFormat)) {
LOG.Debug("Changing pixelformat to Alpha for the RemoveCorners");
@ -916,21 +913,16 @@ namespace GreenshotPlugin.Core {
capturedBitmap.Dispose();
capturedBitmap = tmpBitmap;
}
}
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);
RemoveCorners(capturedBitmap);
}
}
}
} finally {
// Make sure to ALWAYS unfreeze!!
if (frozen) {
this.UnfreezeWindow();
}
}
capture.Image = capturedBitmap;
// Make sure the capture location is the location of the window, not the copy
@ -954,17 +946,19 @@ namespace GreenshotPlugin.Core {
/// <summary>
/// Helper method to remove the corners from a DMW capture
/// </summary>
/// <param name="normalBitmap">The bitmap to remove the corners from.</param>
/// <param name="cornerColor">The background color</param>
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);
/// <param name="image">The bitmap to remove the corners from.</param>
private void RemoveCorners(Bitmap image) {
int [] cornerRange = {5,3,2,1,1};
using (BitmapBuffer buffer = new BitmapBuffer((Bitmap)image, false)) {
buffer.Lock();
for (int y = 0; y < cornerRange.Length; y++) {
for (int x = 0; x < cornerRange[y]; x++) {
buffer.SetColorAt(x, y, Color.Transparent);
buffer.SetColorAt(image.Width-1-x, y, Color.Transparent);
buffer.SetColorAt(image.Width-1-x, image.Height-1-y, Color.Transparent);
buffer.SetColorAt(x, image.Height-1-y, Color.Transparent);
}
}
}
}
@ -1131,28 +1125,31 @@ namespace GreenshotPlugin.Core {
/// Freezes the process belonging to the window
/// Warning: Use only if no other way!!
/// </summary>
private void FreezeWindow() {
private bool FreezeWindow() {
Process proc = Process.GetProcessById(this.ProcessId.ToInt32());
string processName = proc.ProcessName;
if (!CanFreezeOrUnfreeze(processName)) {
LOG.DebugFormat("Not freezing {0}", processName);
return;
return false;
}
if (!CanFreezeOrUnfreeze(Text)) {
LOG.DebugFormat("Not freezing {0}", processName);
return;
return false;
}
LOG.DebugFormat("Freezing process: {0}", processName);
bool frozen = false;
foreach (ProcessThread pT in proc.Threads) {
IntPtr pOpenThread = Kernel32.OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);
if (pOpenThread == IntPtr.Zero) {
break;
}
frozen = true;
Kernel32.SuspendThread(pOpenThread);
}
return frozen;
}
/// <summary>