zoukankan      html  css  js  c++  java
  • 以Lockbits的方式访问bitmap

    用Bitmap.GetPixel和Bitmap.SetPixel访问像素点实在是太慢了,必须要用LockBits的方式访问内存才能改善,这里贴一个快速访问Bitmap每个像素点的包装类,是国外一个老外写的,感觉很好用。

        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 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
                    System.Drawing.Rectangle rect = new System.Drawing.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, 24, or 32
                    if (Depth != 8 && Depth != 24 && Depth != 32)
                    {
                        throw new ArgumentException("Only 8, 24 and 32 bpp images are supported.");
                    }
    
                    // 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
            /// </summary>
            /// <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 == 32) // For 32 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 == 24) // For 24 bpp get Red, Green and Blue
                {
                    byte b = Pixels[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>
            /// <param 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 == 32) // For 32 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 == 24) // For 24 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 are the same)
                {
                    Pixels[i] = color.B;
                }
            }
    
            public bool IsValidCoordinate(int x, int y)
            {
                return x >= 0 && x < this.Width && y > 0 && y < this.Height;
            }
        }
    
    还有一个时间测算的类,可以计算代码的时间差,跟Stopwatch差不多
        public class Benchmark
        {
            private static DateTime startDate = DateTime.MinValue;
            private static DateTime endDate = DateTime.MinValue;
    
            public static TimeSpan Span { get { return endDate.Subtract(startDate); } }
    
            public static void Start() { startDate = DateTime.Now; }
    
            public static void End() { endDate = DateTime.Now; }
    
            public static double GetSeconds()
            {
                if (endDate == DateTime.MinValue) return 0.0;
                else return Span.TotalSeconds;
            }
        }
  • 相关阅读:
    curl post
    mysql存储引擎
    梳理版本控制器:SVN和Git比较
    详细说明php的4中开源框架(TP,CI,Laravel,Yii)
    五种常见的 PHP 设计模式
    php+ajax实现跨域单点登录
    laravel
    Gitlab配置webhooks实现自动化部署
    linux CentOs7 安装gitlab
    身份证验证
  • 原文地址:https://www.cnblogs.com/xiashengwang/p/4225848.html
Copyright © 2011-2022 走看看