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,43 +812,65 @@ 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 try {
if (windowCaptureMode == WindowCaptureMode.AeroTransparent) { this.FreezeWindow();
try { // Use red to make removal of the corners possible
this.FreezeWindow(); tempForm.BackColor = Color.Red;
using (Bitmap whiteBitmap = WindowCapture.CaptureRectangle(captureRectangle)) { // Make sure everything is visible
// Apply a white color tempForm.Refresh();
tempForm.BackColor = Color.Black; Application.DoEvents();
// Refresh the form, otherwise the color doesn't show. 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(); tempForm.Refresh();
using (Bitmap blackBitmap = WindowCapture.CaptureRectangle(captureRectangle)) { Application.DoEvents();
capturedBitmap = ApplyTransparency(blackBitmap, whiteBitmap);
try {
using (Bitmap whiteBitmap = WindowCapture.CaptureRectangle(captureRectangle)) {
// Apply a white color
tempForm.BackColor = Color.Black;
// Make sure everything is visible
tempForm.Refresh();
Application.DoEvents();
using (Bitmap blackBitmap = WindowCapture.CaptureRectangle(captureRectangle)) {
capturedBitmap = ApplyTransparency(blackBitmap, whiteBitmap);
}
}
} catch (Exception e) {
LOG.Debug("Exception: ", e);
// Some problem occured, cleanup and make a normal capture
if (capturedBitmap != null) {
capturedBitmap.Dispose();
capturedBitmap = null;
}
} }
} }
} catch (Exception e) { // If no capture up till now, create a normal capture.
LOG.Debug("Exception: ", e); if (capturedBitmap == null) {
// Some problem occured, cleanup and make a normal capture // Remove transparency, this will break the capturing
if (capturedBitmap != null) { tempForm.BackColor = Color.FromArgb(255, conf.DWMBackgroundColor.R, conf.DWMBackgroundColor.G, conf.DWMBackgroundColor.B);
capturedBitmap.Dispose(); // Make sure everything is visible
capturedBitmap = null; tempForm.Refresh();
Application.DoEvents();
// Capture from the screen
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();
} }
} } finally {
// If no capture up till now, create a normal capture. // Make sure to ALWAYS unfreeze!!
if (capturedBitmap == null) { this.UnfreezeWindow();
// Capture from the screen
capturedBitmap = WindowCapture.CaptureRectangle(captureRectangle);
} }
capture.Image = capturedBitmap; capture.Image = capturedBitmap;
@ -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.