/**////<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 Spider.Common ...{ /**////<summary> /// determines the meaning of the transparencyKey argument to the Convert method ///</summary> publicenum 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> publicclass 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> publicunsafestatic Region Convert(Bitmap bitmap, Color transparencyKey, TransparencyMode mode) ...{ //sanity check if (bitmap ==null) thrownew 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; } } }