C # calls the functions in gdi+1.1 to achieve the classic effects of Gaussian blur, Unsharp Mask, and so on.

Source: Internet
Author: User
Tags image filter

Http://www.cnblogs.com/Imageshop/archive/2012/12/13/2815712.html

In the gdi+1.1 version, Ms added many new features, of which the special effects class effect is a very attractive thing, unfortunately in the VS2010 image class, but did not encapsulate this class (I do not know if I did not find), this perhaps Ms also has its own considerations, After all, to use these functions, you must require that the system is Windows Vista and above, while XP has a higher market share at that time.
However, as an option, we are obliged to give these functions to those customers who have followed these latest systems.

In fact, these functions I have called the VB6 two years ago, the method of invocation is very simple and clear, now, in learning C #, you need to consider how to encapsulate them into C #. Although the implementation of the lower level of the algorithm (the Pixel processing implementation) was implemented very early, the ability to invoke the existing function directly is a very happy thing for many friends.

The first step in implementing this function is to find the declaration of these functions, which has a C-style declaration on MSDN and is not a problem for most of the C # language, refer to http://msdn.microsoft.com/en-us/library/ms533971 ( vs.85). aspx

For example, this

Gpstatus wingdipapi Gdipbitmapapplyeffect (gpbitmap* bitmap, Cgpeffect *effect, RECT *roi, BOOL useauxdata, VOID **auxData , INT *auxdatasize)


I write this:

      [DllImport ("Gdiplus.dll", SetLastError = true, ExactSpelling = True,charset = CharSet.Unicode)]        private static extern int Gdipbitmapapplyeffect (IntPtr bitmap, IntPtr effect, ref Rectangle Rectofinterest, BOOL Useauxdat A, IntPtr auxdata, int auxdatasize);


For the first parameter bitmap, you cannot declare a C # bitmap class, or you can declare it as a handleref type, VS is so dry, for the last few arguments, is used to return some data to the user, basically no one is interested in that data, So it does not matter if you do not declare a parameter of type out.

The problem is, the first parameter bitmap is a handle to the image object of GDI +, in C #, there is the bitmap class, in fact, we know that he is the package of GDI +, then his specific instance must also correspond to a GDI + object handle, but he encapsulated too much, does not provide us with this excuse, so we have two options, one is to directly invoke GDI + load the image of the function, get the corresponding handle, and then processing, and then call GDI + 's drawing API display, but this will undoubtedly increase the amount of work; See if I can sneak up on this handle. Hehe, I beginner C #, not yet this heat, but from an expert who stole a code, but it can:

  <summary>////Get the value of the private field of the object, thank Aaron Lee Murgatroyd///</summary>/<typeparam N Ame= the type of "TResult" > Field </typeparam>//<param name= "obj" > the object from which to get the field value </param>///<para M name= the name of the "FieldName" > Field .</param>///<returns> field values </returns>//<exception cref= "S Ystem. InvalidOperationException "> Cannot find the field .</exception>//internal static TResult Getprivatefield<tre            Sult> (This object obj, string fieldName) {if (obj = = null) return to default (TResult); Type Lttype = obj.            GetType (); FieldInfo lfifieldinfo = Lttype.getfield (Fieldname,system.reflection.bindingflags.getfield | System.Reflection.BindingFlags.Instance |            System.Reflection.BindingFlags.NonPublic);            if (lfifieldinfo! = null) return (TResult) lfifieldinfo.getvalue (obj); else throw new InvalidOperationException (string. FoRmat ("Instance field ' {0} ' could not being located in object of type ' {1} '.", FieldName, obj. GetType ().        FullName)); }


With this code, if you know the name of the encapsulated private field, you can get the value of that field (the principle I don't understand).
Well, how do we know the value of the GDI + handle in C # package, there is a way to believe that every C # ace around there will be a similar refleator such tools, directly to see the implementation of the image class.

Here's what you're pasting from the code:

 public static IntPtr Nativehandle (this Bitmap Bmp) {return bmp.getprivatefield<intptr> ("NA            Tiveimage ");                /* Using reflector to decompile System.Drawing.Dll you can see that the image class has the following private fields internal INTPTR nativeimage;                Private byte[] RawData;                Private Object UserData; Then there is a setnativeimage function internal void setnativeimage (INTPTR handle) {if                    (handle = = IntPtr.Zero) {throw new ArgumentException (SR.                    GetString ("NativeHandle0"), "handle");                } this.nativeimage = handle; Here's a look at FromFile and so on, which is actually calling some Gdip functions such as Gdiploadimagefromfile, and returning the GDIP image handle by calling Setnativeima GE assigns a value to the variable nativeimage, so if we can get this value, we can call VS2010 temporarily not encapsulated Gdip function to do the related processing, and because.             NET has definitely initialized over GDI +, we don't have to initialize him in the call Gdipstartup. */        }


Ok. Everything's Over,
Here is the function call, such as the effect of Gaussian blur, is the invocation of several functions, how simple AH.

 <summary>///For Gaussian blur of images, refer to: http://msdn.microsoft.com/en-us/library/ms534057 (v=vs.85). aspx//&lt ;/summary>//<param name= "Rect" > areas that need to be blurred, this value will be corrected for bounds and returned .</param>//<param name= "Radius" > Specify the radius of the Gaussian convolution core, the effective range [0,255], the larger the radius, the more blurred the image .</param>//<param name= "Expandedge" > Specifies whether to extend the bounds, set to True, A softer effect at the edges is achieved. </param> public static void Gaussianblur (this Bitmap Bmp, ref Rectangle Rect, float Radius = 10,            BOOL Expandedge = false) {int Result;            IntPtr Blureffect;            Blurparameters Blurpara; if (Radius <0) | |             (radius>255))            {throw new ArgumentOutOfRangeException ("radius must be within [0,255]");            } Blurpara.radius = Radius;            Blurpara.expandedges = Expandedge;            Result = Gdipcreateeffect (Blureffectguid, out blureffect); if (Result = = 0) {IntPtr Handle = MaRshal.                AllocHGlobal (Marshal.SizeOf (Blurpara));                Marshal.structuretoptr (Blurpara, Handle, true);                Gdipseteffectparameters (Blureffect, Handle, (UINT) marshal.sizeof (Blurpara));                Gdipbitmapapplyeffect (Bmp.nativehandle (), Blureffect, ref Rect, False, IntPtr.Zero, 0);                The Gdipbitmapcreateapplyeffect function can be used without altering the original image and writing the result of the blur to a new image gdipdeleteeffect (Blureffect);            Marshal.freehglobal (Handle); } else {throw new ExternalException ("Non-supported GDI + version must be gdi+1.1 and above, and the operating system requires win Vista and after Version. ");}}


Note that the first parameter of the function is this Bitmap Bmp, with this one, after you declare a BITMAP type variable, you can only hint if you have this item:



What principle, I have not learned which step, hehe.

In the instance code, I only provide Gaussian blur and unsharp Mask effect, other effects (color balance, brightness contrast, red-eye elimination, hue saturation, color scale, curve, etc.) we look up MSDN imitation also wrote, in fact, here the most important I think is Gaussian blur, because he is the basis of many algorithms, For example, the Unsharp mask is based on Gaussian blur, so he is slower than the Gaussian blur, as well as high-contrast retention, canny edge operators, selection feathering and so on.

Finally say a bit of image filter adjustment when the preview effect, the preview is sure to keep a copy of the original data, this I would prefer to directly with memory processing, it is best not to pass the class encapsulation mode, we look at the code may know what I mean.

A simple UI effect:



Code:
Http://files.cnblogs.com/Imageshop/GdipEffect.rar

It is important to optimize the algorithm because it is a characteristic of Gdip fuzzy, the larger the blur radius, the less time is used.

C # calls the functions in gdi+1.1 to achieve the classic effects of Gaussian blur, Unsharp Mask, and so on.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.