diff --git a/GreenshotPlugin/Core/Effects.cs b/GreenshotPlugin/Core/Effects.cs
index 4dcbd2912..686ad7605 100644
--- a/GreenshotPlugin/Core/Effects.cs
+++ b/GreenshotPlugin/Core/Effects.cs
@@ -42,7 +42,7 @@ namespace Greenshot.Core {
public class DropShadowEffect : IEffect {
public DropShadowEffect() {
Darkness = 0.6f;
- ShadowSize = 9;
+ ShadowSize = 7;
ShadowOffset = new Point(-1, -1);
}
public float Darkness {
diff --git a/GreenshotPlugin/Core/ImageHelper.cs b/GreenshotPlugin/Core/ImageHelper.cs
index 50dc3bb0b..07c11452e 100644
--- a/GreenshotPlugin/Core/ImageHelper.cs
+++ b/GreenshotPlugin/Core/ImageHelper.cs
@@ -659,27 +659,26 @@ namespace GreenshotPlugin.Core {
/// Must be ODD!
/// Bitmap
public static Bitmap ApplyBoxBlur(Bitmap destinationBitmap, int range) {
+ // Range must be odd!
if ((range & 1) == 0) {
range++;
- //throw new InvalidOperationException("Range must be odd!");
}
+ // We only need one fastbitmap as we use it as source and target (the reading is done for one line H/V, writing after "parsing" one line H/V)
using (IFastBitmap fastBitmap = FastBitmap.Create(destinationBitmap)) {
// Box blurs are frequently used to approximate a Gaussian blur.
// By the central limit theorem, if applied 3 times on the same image, a box blur approximates the Gaussian kernel to within about 3%, yielding the same result as a quadratic convolution kernel.
+ // This might be true, but the GDI+ BlurEffect doesn't look the same, a 2x blur is more simular and we only make 2x Box-Blur.
+ // (Might also be a mistake in our blur, but for now it looks great)
if (fastBitmap.hasAlphaChannel) {
BoxBlurHorizontalAlpha(fastBitmap, range);
BoxBlurVerticalAlpha(fastBitmap, range);
BoxBlurHorizontalAlpha(fastBitmap, range);
BoxBlurVerticalAlpha(fastBitmap, range);
- BoxBlurHorizontalAlpha(fastBitmap, range);
- BoxBlurVerticalAlpha(fastBitmap, range);
} else {
BoxBlurHorizontal(fastBitmap, range);
BoxBlurVertical(fastBitmap, range);
BoxBlurHorizontal(fastBitmap, range);
BoxBlurVertical(fastBitmap, range);
- BoxBlurHorizontal(fastBitmap, range);
- BoxBlurVertical(fastBitmap, range);
}
return fastBitmap.UnlockAndReturnBitmap();
@@ -691,7 +690,7 @@ namespace GreenshotPlugin.Core {
///
/// Target BitmapBuffer
/// Range must be odd!
- public static void BoxBlurHorizontal(IFastBitmap targetFastBitmap, int range) {
+ private static void BoxBlurHorizontal(IFastBitmap targetFastBitmap, int range) {
if (targetFastBitmap.hasAlphaChannel) {
throw new NotSupportedException("BoxBlurHorizontal should NOT be called for bitmaps with alpha channel");
}
@@ -739,7 +738,7 @@ namespace GreenshotPlugin.Core {
/// Source BitmapBuffer
/// Target BitmapBuffer
/// Range must be odd!
- public static void BoxBlurHorizontalAlpha(IFastBitmap targetFastBitmap, int range) {
+ private static void BoxBlurHorizontalAlpha(IFastBitmap targetFastBitmap, int range) {
if (!targetFastBitmap.hasAlphaChannel) {
throw new NotSupportedException("BoxBlurHorizontalAlpha should be called for bitmaps with alpha channel");
}
@@ -790,7 +789,7 @@ namespace GreenshotPlugin.Core {
///
/// BitmapBuffer which previously was created with BoxBlurHorizontal
/// Range must be odd!
- public static void BoxBlurVertical(IFastBitmap targetFastBitmap, int range) {
+ private static void BoxBlurVertical(IFastBitmap targetFastBitmap, int range) {
if (targetFastBitmap.hasAlphaChannel) {
throw new NotSupportedException("BoxBlurVertical should NOT be called for bitmaps with alpha channel");
}
@@ -841,7 +840,7 @@ namespace GreenshotPlugin.Core {
///
/// BitmapBuffer which previously was created with BoxBlurHorizontal
/// Range must be odd!
- public static void BoxBlurVerticalAlpha(IFastBitmap targetFastBitmap, int range) {
+ private static void BoxBlurVerticalAlpha(IFastBitmap targetFastBitmap, int range) {
if (!targetFastBitmap.hasAlphaChannel) {
throw new NotSupportedException("BoxBlurVerticalAlpha should be called for bitmaps with alpha channel");
}
@@ -929,6 +928,11 @@ namespace GreenshotPlugin.Core {
offset.X += shadowSize - 1;
offset.Y += shadowSize - 1;
Bitmap returnImage = CreateEmpty(sourceBitmap.Width + (shadowSize * 2), sourceBitmap.Height + (shadowSize * 2), targetPixelformat, Color.Empty, sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution);
+ // Make sure the shadow is odd, there is no reason for an even blur!
+ if ((shadowSize & 1) == 0) {
+ shadowSize++;
+ }
+ bool canUseGDIBlur = GDIplus.isBlurPossible(shadowSize);
using (Graphics graphics = Graphics.FromImage(returnImage)) {
// Make sure we draw with the best quality!
graphics.SmoothingMode = SmoothingMode.HighQuality;
@@ -943,7 +947,11 @@ namespace GreenshotPlugin.Core {
cm.Matrix00 = 0;
cm.Matrix11 = 0;
cm.Matrix22 = 0;
- cm.Matrix33 = darkness;
+ if (canUseGDIBlur) {
+ cm.Matrix33 = darkness + 0.1f;
+ } else {
+ cm.Matrix33 = darkness;
+ }
ia.SetColorMatrix(cm);
Rectangle shadowRectangle = new Rectangle(new Point(shadowSize, shadowSize), sourceBitmap.Size);
graphics.DrawImage(sourceBitmap, shadowRectangle, 0, 0, sourceBitmap.Width, sourceBitmap.Height, GraphicsUnit.Pixel, ia);
@@ -951,11 +959,14 @@ namespace GreenshotPlugin.Core {
// blur "shadow", apply to whole new image
// Gaussian
- Rectangle newImageRectangle = new Rectangle(0, 0, returnImage.Width, returnImage.Height);
- if (!GDIplus.ApplyBlur(returnImage, newImageRectangle, shadowSize, false)) {
- // something went wrong, try normal software blur
+ if (canUseGDIBlur) {
+ // Use GDI Blur
+ Rectangle newImageRectangle = new Rectangle(0, 0, returnImage.Width, returnImage.Height);
+ GDIplus.ApplyBlur(returnImage, newImageRectangle, shadowSize, false);
+ } else {
+ // try normal software blur
//returnImage = CreateBlur(returnImage, newImageRectangle, true, shadowSize, 1d, false, newImageRectangle);
- ApplyBoxBlur(returnImage, shadowSize-2);
+ ApplyBoxBlur(returnImage, shadowSize);
}
if (returnImage != null) {
diff --git a/GreenshotPlugin/UnmanagedHelpers/GDIplus.cs b/GreenshotPlugin/UnmanagedHelpers/GDIplus.cs
index 0586992b9..e4a7c4508 100644
--- a/GreenshotPlugin/UnmanagedHelpers/GDIplus.cs
+++ b/GreenshotPlugin/UnmanagedHelpers/GDIplus.cs
@@ -165,7 +165,13 @@ namespace GreenshotPlugin.UnmanagedHelpers {
return (IntPtr)FIELD_INFO_NATIVE_IMAGEATTRIBUTES.GetValue(imageAttributes);
}
- private static bool isBlurPossible(int radius) {
+ ///
+ /// Returns if a GDIPlus blur can be made for the supplied radius.
+ /// This accounts for the "bug" I reported here: http://social.technet.microsoft.com/Forums/en/w8itprogeneral/thread/99ddbe9d-556d-475a-8bab-84e25aa13a2c
+ ///
+ ///
+ ///
+ public static bool isBlurPossible(int radius) {
if (Environment.OSVersion.Version.Major < 6) {
return false;
} else if ((Environment.OSVersion.Version.Major >= 6 && Environment.OSVersion.Version.Minor >= 2) && radius < 20) {