Removed sleep from the DWM capture, replaced with with DoEvents. Added logic to remove the corners from a DWM window capture, making it a cleaner capture.

git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@1645 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
RKrom 2012-02-09 11:51:44 +00:00
parent 8374aa5fb6
commit 4ab2d151e5

View file

@ -726,18 +726,6 @@ namespace GreenshotPlugin.Core {
tempForm.ShowInTaskbar = false; tempForm.ShowInTaskbar = false;
tempForm.FormBorderStyle = FormBorderStyle.None; tempForm.FormBorderStyle = FormBorderStyle.None;
tempForm.TopMost = true; tempForm.TopMost = true;
// Transparent would give an error here
if (windowCaptureMode == WindowCaptureMode.Aero) {
Color formColor = conf.DWMBackgroundColor;
// Remove transparency, this will break the capturing
formColor = Color.FromArgb(255, formColor.R, formColor.G, formColor.B);
tempForm.BackColor = formColor;
} else {
// Make sure the user sees transparent when going into the color picker
conf.DWMBackgroundColor = Color.Transparent;
// Use white, later black to capture transparent
tempForm.BackColor = Color.White;
}
// Register the Thumbnail // Register the Thumbnail
DWM.DwmRegisterThumbnail(tempForm.Handle, Handle, out thumbnailHandle); DWM.DwmRegisterThumbnail(tempForm.Handle, Handle, out thumbnailHandle);
@ -824,23 +812,34 @@ namespace GreenshotPlugin.Core {
tempForm.Show(); tempForm.Show();
tempFormShown = true; tempFormShown = true;
// Wait, to make sure everything is visible
Thread.Sleep(250);
// Intersect with screen // Intersect with screen
captureRectangle.Intersect(capture.ScreenBounds); captureRectangle.Intersect(capture.ScreenBounds);
// Destination bitmap for the capture // Destination bitmap for the capture
Bitmap capturedBitmap = null; Bitmap capturedBitmap = null;
// Check if we make a transparent capture
if (windowCaptureMode == WindowCaptureMode.AeroTransparent) {
try { try {
this.FreezeWindow(); 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) {
// Use white, later black to capture transparent
tempForm.BackColor = Color.White;
// Make sure everything is visible
tempForm.Refresh();
Application.DoEvents();
try {
using (Bitmap whiteBitmap = WindowCapture.CaptureRectangle(captureRectangle)) { using (Bitmap whiteBitmap = WindowCapture.CaptureRectangle(captureRectangle)) {
// Apply a white color // Apply a white color
tempForm.BackColor = Color.Black; tempForm.BackColor = Color.Black;
// Refresh the form, otherwise the color doesn't show. // Make sure everything is visible
tempForm.Refresh(); tempForm.Refresh();
Application.DoEvents();
using (Bitmap blackBitmap = WindowCapture.CaptureRectangle(captureRectangle)) { using (Bitmap blackBitmap = WindowCapture.CaptureRectangle(captureRectangle)) {
capturedBitmap = ApplyTransparency(blackBitmap, whiteBitmap); capturedBitmap = ApplyTransparency(blackBitmap, whiteBitmap);
} }
@ -852,16 +851,27 @@ namespace GreenshotPlugin.Core {
capturedBitmap.Dispose(); capturedBitmap.Dispose();
capturedBitmap = null; capturedBitmap = null;
} }
} finally {
// Make sure to ALWAYS unfreeze!!
this.UnfreezeWindow();
} }
} }
// If no capture up till now, create a normal capture. // If no capture up till now, create a normal capture.
if (capturedBitmap == null) { if (capturedBitmap == null) {
// Remove transparency, this will break the capturing
tempForm.BackColor = Color.FromArgb(255, conf.DWMBackgroundColor.R, conf.DWMBackgroundColor.G, conf.DWMBackgroundColor.B);
// Make sure everything is visible
tempForm.Refresh();
Application.DoEvents();
// Capture from the screen // Capture from the screen
capturedBitmap = WindowCapture.CaptureRectangle(captureRectangle); capturedBitmap = WindowCapture.CaptureRectangle(captureRectangle);
} }
if (capturedBitmap != null && redMask != null) {
// Remove corners
RemoveCorners(capturedBitmap, redMask, windowCaptureMode, conf.DWMBackgroundColor);
}
}
} finally {
// Make sure to ALWAYS unfreeze!!
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
@ -882,6 +892,57 @@ namespace GreenshotPlugin.Core {
return capture; return capture;
} }
/// <summary>
/// Helper method to remove the corners from a DMW capture
/// </summary>
/// <param name="normalBitmap">The bitmap taken which would normally be returned to the editor etc.</param>
/// <param name="redBitmap">The bitmap taken with a red background</param>
/// <param name="captureMode">The capturemode so we can take transparency into accound</param>
/// <param name="destinationColor">The background color</param>
private void RemoveCorners(Bitmap normalBitmap, Bitmap redBitmap, WindowCaptureMode captureMode, Color destinationColor) {
if (captureMode == WindowCaptureMode.AeroTransparent) {
destinationColor = Color.Transparent;
}
using (BitmapBuffer redBuffer = new BitmapBuffer(redBitmap, false)) {
redBuffer.Lock();
using (BitmapBuffer normalBuffer = new BitmapBuffer(normalBitmap, false)) {
normalBuffer.Lock();
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
// top left
int cornerX = x;
int cornerY = y;
Color currentPixel = redBuffer.GetColorAt(cornerX, cornerY);
if (currentPixel.R > 0 && currentPixel.G == 0 && currentPixel.B == 0) {
normalBuffer.SetColorAt(cornerX, cornerY, destinationColor);
}
// top right
cornerX = normalBitmap.Width - x;
cornerY = y;
currentPixel = redBuffer.GetColorAt(cornerX, cornerY);
if (currentPixel.R > 0 && currentPixel.G == 0 && currentPixel.B == 0) {
normalBuffer.SetColorAt(cornerX, cornerY, destinationColor);
}
// bottom right
cornerX = normalBitmap.Width - x;
cornerY = normalBitmap.Height - y;
currentPixel = redBuffer.GetColorAt(cornerX, cornerY);
if (currentPixel.R > 0 && currentPixel.G == 0 && currentPixel.B == 0) {
normalBuffer.SetColorAt(cornerX, cornerY, destinationColor);
}
// bottom left
cornerX = x;
cornerY = normalBitmap.Height - y;
currentPixel = redBuffer.GetColorAt(cornerX, cornerY);
if (currentPixel.R > 0 && currentPixel.G == 0 && currentPixel.B == 0) {
normalBuffer.SetColorAt(cornerX, cornerY, destinationColor);
}
}
}
}
}
}
/// <summary> /// <summary>
/// Apply transparency by comparing a transparent capture with a black and white background /// Apply transparency by comparing a transparent capture with a black and white background
/// A "Math.min" makes sure there is no overflow, but this could cause the picture to have shifted colors. /// A "Math.min" makes sure there is no overflow, but this could cause the picture to have shifted colors.