Speed up access to bitmap

Source: Internet
Author: User

Introduction

When working with bitmap pictures, it is sometimes necessary to get or set the pixel color method: GetPixel and SetPixel,

If these two methods are operated directly, it is very slow, here we can extract the data to operate, and then after the operation of the copy back can speed up access

Two methods

In fact, there are two ways to access the bitmap, one is the memory method, the other is the needle

1. Memory method

This defines a class lockbitmap, which copies the bitmap data, operates directly in memory, and copies it to bitmap after the operation is completed.

        public class Lockbitmap {Bitmap Source = null;            IntPtr iptr = IntPtr.Zero;            BitmapData BitmapData = null;            Public byte[] Pixels {get; set;}            public int Depth {get; private set;}            public int Width {get; private set;}            public int Height {get; private set;}            Public Lockbitmap (Bitmap source) {This.source = source; }//<summary>//Lock bitmap data//</summary> public void Lo                    Ckbits () {try {//Get width and height of bitmap Width = source.                    Width; Height = source.                    Height;                    Get total locked pixels count int pixelcount = Width * Height;      Create Rectangle to lock Rectangle rect = new Rectangle (0, 0, Width, Height);              Get source bitmap pixel format size Depth = System.Drawing.Bitmap.GetPixelFormatSize (s Ource.                    PixelFormat);  Check if BPP (Bits Per Pixel) is 8, or if (Depth! = 8 && Depth! = && Depth ! = +) {throw new ArgumentException ("Only 8," and "Images is Supporte                    D. ");} Lock bitmap and return bitmap data BitmapData = source. LockBits (rect, imagelockmode.readwrite, source.                    PixelFormat);                    Create byte array to copy pixel values int step = DEPTH/8;                    Pixels = new Byte[pixelcount * Step];                    Iptr = Bitmapdata.scan0;                Copy data from pointer to array marshal.copy (IPTR, Pixels, 0, pixels.length); } catch (ExCeption ex) {throw ex;            }}///<summary>//Unlock bitmap data//</summary>  public void Unlockbits () {try {//Copy data from byte array                    To Pointer marshal.copy (Pixels, 0, Iptr, pixels.length); Unlock Bitmap data source.                Unlockbits (BitmapData);                } catch (Exception ex) {throw ex; }}///<summary>//Get The color of the specified pixel//</summ            ary>//<param name= "x" ></param>///<param name= "y" ></param> <returns></returns> Public color GetPixel (int x, int y) {color CLR                = Color.Empty; GeT color components count int ccount = DEPTH/8;                Get Start index of the specified pixel int i = ((Y * Width) + x) * CCOUNT;                if (i > Pixels.length-ccount) throw new IndexOutOfRangeException ();                    if (Depth = =)//For the BPP get Red, Green, Blue and Alpha {byte b = pixels[i];                    byte g = pixels[i + 1];                    byte R = pixels[i + 2]; byte A = pixels[i + 3];                A CLR = Color.FromArgb (A, R, G, b); if (Depth = =)//For the BPP get Red, Green and Blue {byte b = Pixel                    S[i];                    byte g = pixels[i + 1];                    byte R = pixels[i + 2];                CLR = Color.FromArgb (R, G, b); } if (Depth = = 8)//for 8 BPP Get color value (Red, Green and Blue values ARE the same) {byte c = pixels[i];                CLR = Color.FromArgb (c, C, c);            } return CLR;            }///<summary>//Set The color of the specified pixel///</summary> <param name= "x" ></param>//<param name= "y" ></param>//<para  M name= "color" ></param> public void SetPixel (int x, int y, color color) {//                Get Color Components count int ccount = DEPTH/8;                Get Start index of the specified pixel int i = ((Y * Width) + x) * CCOUNT; if (Depth = =)//For BPP set Red, Green, Blue and Alpha {pixels[i] = color.                    B Pixels[i + 1] = color.                    G Pixels[i + 2] = color.                    R Pixels[i + 3] = color.                A    }            if (Depth = =)//For the BPP set Red, Green and Blue {pixels[i] = Color.b                    ; Pixels[i + 1] = color.                    G Pixels[i + 2] = color.                R                if (Depth = = 8)//for 8 BPP Set color value (Red, Green and Blue values is the same) {Pixels[i] = color.                B }            }        }

Use: Lock bitmap First, then manipulate the color object through pixels, finally release the lock, update the data to bitmap

            string file = @ "C:\test.jpg";            Bitmap bmp = New Bitmap (image.fromfile (file));                        Lockbitmap lockbmp = new Lockbitmap (BMP);            Lock bitmap, Access color lockbmp through pixel            . LockBits ();            Gets the color of colour, color            = lockbmp. GetPixel (ten);            Unlock bitmap lockbmp from memory            . Unlockbits ();

2. Pointer method

This method accesses faster than the memory method, directly through the pointer to the memory operation, do not need to copy, but in C # directly through the pointer to the memory is not safe, so you need to add the unsafe keyword in the code, in the build option to allow unsafe code hook, to compile through

Defined here as the Pointerbitmap class

            public class Pointbitmap {Bitmap Source = null;                IntPtr iptr = IntPtr.Zero;                BitmapData BitmapData = null;                public int Depth {get; private set;}                public int Width {get; private set;}                public int Height {get; private set;}                Public Pointbitmap (Bitmap source) {This.source = source;                        } public void LockBits () {try { Get width and height of bitmap width = source.                        Width; Height = source.                        Height;                        Get total locked pixels count int pixelcount = Width * Height;                        Create Rectangle to lock Rectangle rect = new Rectangle (0, 0, Width, Height); Get source bitmap pixel foRmat size Depth = System.Drawing.Bitmap.GetPixelFormatSize (source.                        PixelFormat); Check if BPP (Bits Per Pixel) is 8, or if (Depth! = 8 && Depth! =) && D Epth! = +) {throw new ArgumentException ("Only 8," and "BPP images                        is supported. "); Lock bitmap and return bitmap data BitmapData = source. LockBits (rect, imagelockmode.readwrite, source.                        PixelFormat);                            Get the first address unsafe {iptr = Bitmapdata.scan0;                    Two-dimensional image loop}}                    catch (Exception ex) {throw ex;        }        } public void Unlockbits () {try { Source.                    Unlockbits (BitmapData);                    } catch (Exception ex) {throw ex;                    }} public Color GetPixel (int x, int y) {unsafe                        {byte* ptr = (byte*) iptr;                        ptr = ptr + bitmapdata.stride * y;                        PTR + = Depth * X/8;                        Color C = color.empty;                            if (Depth = =) {int a = ptr[3];                            int r = ptr[2];                            int g = ptr[1];                            int b = ptr[0];                        c = Color.FromArgb (A, R, G, b);     } else if (Depth = = 24)                   {int r = ptr[2];                            int g = ptr[1];                            int b = ptr[0];                        c = Color.FromArgb (R, G, b);                            } else if (Depth = = 8) {int r = ptr[0];                        c = Color.FromArgb (R, R, R);                    } return C;                    }} public void SetPixel (int x, int y, Color c) {unsafe                        {byte* ptr = (byte*) iptr;                        ptr = ptr + bitmapdata.stride * y;                        PTR + = Depth * X/8;                            if (Depth = =) {Ptr[3] = C.A;                            PTR[2] = C.R;                            PTR[1] = C.G;   Ptr[0] = c.b;                     } else if (Depth = =) {pt                            R[2] = C.R;                            PTR[1] = C.G;                        Ptr[0] = c.b;                            } else if (Depth = = 8) {ptr[2] = C.R;                            PTR[1] = C.G;                        Ptr[0] = c.b; }                    }                }            }

The use of the method is not listed here, similar to the above Lockbitmap

Information

Http://www.codeproject.com/Tips/240428/Work-with-bitmap-faster-with-Csharp

Speed up access to bitmap

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.