单色的背景上有一个自定义不规则图形,如何根据这个不规则图形的形状生成一个GraphicsPath或region.
请注意:一定要得到GraphicsPath或region.

解决方案 »

  1.   

    这是codeguru一个从bitmap到region的工具库http://www.codeguru.com/Csharp/Csharp/cs_misc/graphicsandimages/print.php/c4259/
      

  2.   

    核心代码是这个///<author>Arild Fines</author>
    ///<date>20.04.2002</date>
    using System;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;
    using System.Runtime.InteropServices;namespace BitmapToRegion
    {  /// <summary>
      /// determines the meaning of the transparencyKey argument to the Convert method
      /// </summary>
      public enum TransparencyMode
      {
        /// <summary>
        /// the color key is used to define the transparent region of the bitmap
        /// </summary>
        ColorKeyTransparent,
        /// <summary>
        /// the color key is used to define the area that should _not_ be transparent
        /// </summary>
        ColorKeyOpaque
      }  /// <summary>
      /// a class to convert a color-keyed bitmap into a region
      /// </summary>
      public class BitmapToRegion
      {
        /// <summary>
        /// ctor made private to avoid instantiation
        /// </summary>
        private BitmapToRegion()
        {}
        /// <summary>
        /// the meat of this class
        /// converts the bitmap to a region by scanning each line one by one
        /// this method will not affect the original bitmap in any way
        /// </summary>
        /// <param name="bitmap">The bitmap to convert</param>
        /// <param name="transparencyKey">The color which will indicate either transparency or opacity</param>
        /// <param name="mode">Whether the transparency key should indicate the transparent or the opaque region</param>
        public unsafe static Region Convert( Bitmap bitmap, Color transparencyKey,
          TransparencyMode mode )
        {
          //sanity check
          if ( bitmap == null )
            throw new ArgumentNullException( "Bitmap", "Bitmap cannot be null!" );      //flag = true means the color key represents the opaque color
          bool modeFlag = ( mode == TransparencyMode.ColorKeyOpaque );
          
          GraphicsUnit unit = GraphicsUnit.Pixel;
          RectangleF boundsF = bitmap.GetBounds( ref unit );
          Rectangle bounds = new Rectangle( (int)boundsF.Left, (int)boundsF.Top, 
            (int)boundsF.Width, (int)boundsF.Height );      uint key = (uint)((transparencyKey.A << 24) | (transparencyKey.R << 16) | 
            (transparencyKey.G << 8) | (transparencyKey.B << 0));
          //get access to the raw bits of the image
          BitmapData bitmapData = bitmap.LockBits( bounds, ImageLockMode.ReadOnly, 
            PixelFormat.Format32bppArgb );
          uint* pixelPtr = (uint*)bitmapData.Scan0.ToPointer();      //avoid property accessors in the for
          int yMax = (int)boundsF.Height;
          int xMax = (int)boundsF.Width;      //to store all the little rectangles in
          GraphicsPath path = new GraphicsPath();      for ( int y = 0; y < yMax; y++ )
          {
            //store the pointer so we can offset the stride directly from it later
            //to get to the next line
            byte* basePos = (byte*)pixelPtr;        for ( int x = 0; x < xMax; x++, pixelPtr++  )
            {    
              //is this transparent? if yes, just go on with the loop
              if ( modeFlag ^ ( *pixelPtr == key ) )
                continue;          //store where the scan starts
              int x0 = x;          //not transparent - scan until we find the next transparent byte
              while( x < xMax && !( modeFlag ^ ( *pixelPtr == key ) ) )
              {
                ++x;
                pixelPtr++;
              }          //add the rectangle we have found to the path
              path.AddRectangle( new Rectangle( x0, y, x-x0, 1 ) );
            }
            //jump to the next line
            pixelPtr = (uint*)(basePos + bitmapData.Stride);
          }      //now create the region from all the rectangles
          Region region = new Region( path );      //clean up
          path.Dispose();
          bitmap.UnlockBits( bitmapData );      return region;
        }   }
      
    }