mirror of
https://github.com/greenshot/greenshot
synced 2025-07-14 09:03:44 -07:00
Improved "speed" of the ApplyBlur by using "static final readonly" for the FieldInfo to get the private field and improved stability by using finally to cleanup. (as it should be)
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2490 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
0408c755d6
commit
9f86db6828
1 changed files with 42 additions and 21 deletions
|
@ -51,6 +51,8 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
/// GDIplus Helpers
|
/// GDIplus Helpers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class GDIplus {
|
public static class GDIplus {
|
||||||
|
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(GDIplus));
|
||||||
|
|
||||||
[DllImport("gdiplus.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
|
[DllImport("gdiplus.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
|
||||||
private static extern int GdipBitmapApplyEffect(IntPtr bitmap, IntPtr effect, ref RECT rectOfInterest, bool useAuxData, IntPtr auxData, int auxDataSize);
|
private static extern int GdipBitmapApplyEffect(IntPtr bitmap, IntPtr effect, ref RECT rectOfInterest, bool useAuxData, IntPtr auxData, int auxDataSize);
|
||||||
[DllImport("gdiplus.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
|
[DllImport("gdiplus.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
|
||||||
|
@ -61,17 +63,16 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
private static extern int GdipDeleteEffect(IntPtr effect);
|
private static extern int GdipDeleteEffect(IntPtr effect);
|
||||||
private static Guid BlurEffectGuid = new Guid("{633C80A4-1843-482B-9EF2-BE2834C5FDD4}");
|
private static Guid BlurEffectGuid = new Guid("{633C80A4-1843-482B-9EF2-BE2834C5FDD4}");
|
||||||
|
|
||||||
internal static TResult GetPrivateField<TResult>(object obj, string fieldName) {
|
// Constant "FieldInfo" for getting the nativeImage from the image
|
||||||
if (obj == null) {
|
private static readonly FieldInfo FIELD_INFO_NATIVE_IMAGE = typeof(Bitmap).GetField("nativeImage", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
return default(TResult);
|
|
||||||
}
|
/// <summary>
|
||||||
Type ltType = obj.GetType();
|
/// Get the nativeImage field from the bitmap
|
||||||
FieldInfo lfiFieldInfo = ltType.GetField( fieldName,System.Reflection.BindingFlags.GetField |System.Reflection.BindingFlags.Instance |System.Reflection.BindingFlags.NonPublic);
|
/// </summary>
|
||||||
if (lfiFieldInfo != null) {
|
/// <param name="bitmap"></param>
|
||||||
return (TResult)lfiFieldInfo.GetValue(obj);
|
/// <returns></returns>
|
||||||
} else {
|
private static IntPtr GetNativeImage(Bitmap bitmap) {
|
||||||
throw new InvalidOperationException(string.Format("Instance field '{0}' could not be located in object of type '{1}'.",fieldName, obj.GetType().FullName));
|
return (IntPtr)FIELD_INFO_NATIVE_IMAGE.GetValue(bitmap);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -85,29 +86,49 @@ namespace GreenshotPlugin.UnmanagedHelpers {
|
||||||
if (Environment.OSVersion.Version.Major < 6) {
|
if (Environment.OSVersion.Version.Major < 6) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
IntPtr hBlurParams = IntPtr.Zero;
|
||||||
|
IntPtr hEffect = IntPtr.Zero;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Create a BlurParams struct and set the values
|
||||||
BlurParams blurParams = new BlurParams();
|
BlurParams blurParams = new BlurParams();
|
||||||
blurParams.Radius = radius;
|
blurParams.Radius = radius;
|
||||||
blurParams.ExpandEdges = false;
|
blurParams.ExpandEdges = false;
|
||||||
IntPtr hBlurParams = Marshal.AllocHGlobal(Marshal.SizeOf(blurParams));
|
|
||||||
|
// Allocate space in unmanaged memory
|
||||||
|
hBlurParams = Marshal.AllocHGlobal(Marshal.SizeOf(blurParams));
|
||||||
|
// Copy the structure to the unmanaged memory
|
||||||
Marshal.StructureToPtr(blurParams, hBlurParams, true);
|
Marshal.StructureToPtr(blurParams, hBlurParams, true);
|
||||||
|
|
||||||
uint paramsSize = (uint)Marshal.SizeOf(blurParams);
|
// Create the GDI+ BlurEffect, using the Guid
|
||||||
|
|
||||||
IntPtr hEffect = IntPtr.Zero;
|
|
||||||
|
|
||||||
int status = GdipCreateEffect(BlurEffectGuid, out hEffect);
|
int status = GdipCreateEffect(BlurEffectGuid, out hEffect);
|
||||||
GdipSetEffectParameters(hEffect, hBlurParams, paramsSize);
|
|
||||||
|
|
||||||
//IntPtr hBitmap = destinationBitmap.GetHbitmap();
|
// Set the blurParams to the effect
|
||||||
IntPtr hBitmap = GetPrivateField<IntPtr>(destinationBitmap, "nativeImage");
|
GdipSetEffectParameters(hEffect, hBlurParams, (uint)Marshal.SizeOf(blurParams));
|
||||||
|
|
||||||
|
// Somewhere it said we can use destinationBitmap.GetHbitmap(), this doesn't work!!
|
||||||
|
// Get the private nativeImage property from the Bitmap
|
||||||
|
IntPtr hBitmap = GetNativeImage(destinationBitmap);
|
||||||
|
|
||||||
|
// Create a RECT from the Rectangle
|
||||||
RECT rec = new RECT(area);
|
RECT rec = new RECT(area);
|
||||||
|
// Apply the effect to the bitmap in the specified area
|
||||||
GdipBitmapApplyEffect(hBitmap, hEffect, ref rec, false, IntPtr.Zero, 0);
|
GdipBitmapApplyEffect(hBitmap, hEffect, ref rec, false, IntPtr.Zero, 0);
|
||||||
GdipDeleteEffect(hEffect);
|
|
||||||
Marshal.FreeHGlobal(hBlurParams);
|
// Everything worked, return true
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
LOG.Error("Problem using GdipBitmapApplyEffect: ", ex);
|
||||||
return false;
|
return false;
|
||||||
|
} finally {
|
||||||
|
if (hEffect != null) {
|
||||||
|
// Delete the effect
|
||||||
|
GdipDeleteEffect(hEffect);
|
||||||
|
}
|
||||||
|
if (hBlurParams != IntPtr.Zero) {
|
||||||
|
// Free the memory
|
||||||
|
Marshal.FreeHGlobal(hBlurParams);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue