今天看啥
    热点:

      天发国际娱乐官网:  芬兰是第一批承认并与新中国建立外交关系的西方国家之一。

      C#加快Bitmap的访问速度,


      在对Bitmap图片操作的时候,有时需要用到获取或设置像素颜色方法:GetPixel 和 SetPixel,

      如果直接对这两个方法进行操作的话速度很慢,这里我们可以通过把数据提取出来操作,然后操作完在复制回去可以加快访问速度

      其实对Bitmap的访问还有两种方式,一种是内存法,一种是指针法

      1、内存法

        这里定义一个类LockBitmap,通过把Bitmap数据拷贝出来,在内存上直接操作,操作完成后在拷贝到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
                          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, 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;
                      }
                  }
              }

      使用:先锁定Bitmap,然后通过Pixels操作颜色对象,最后释放锁,把数据更新到Bitmap中

      string file = @"C:\test.jpg";
                  Bitmap bmp = new Bitmap(Image.FromFile(file));
                  
                  LockBitmap lockbmp = new LockBitmap(bmp);
                  //锁定Bitmap,通过Pixel访问颜色
                  lockbmp.LockBits();
      
                  //获取颜色
                  Color color = lockbmp.GetPixel(10, 10);
      
                  //从内存解锁Bitmap
                  lockbmp.UnlockBits();

      2、指针法

        这种方法访问速度比内存法更快,直接通过指针对内存进行操作,不需要进行拷贝,但是在C#中直接通过指针操作内存是不安全的,所以需要在代码中加入unsafe关键字,在生成选项中把允许不安全代码勾上,才能编译通过

        这里定义成PointerBitmap类

      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, 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);
      
                              //得到首地址
                              unsafe
                              {
                                  Iptr = bitmapData.Scan0;
                                  //二维图像循环
                                  
                              }
                          }
                          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 == 32)
                              {
                                  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 == 32)
                              {
                                  ptr[3] = c.A;
                                  ptr[2] = c.R;
                                  ptr[1] = c.G;
                                  ptr[0] = c.B;
                              }
                              else if (Depth == 24)
                              {
                                  ptr[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;
                              }
                          }
                      }
                  }

      使用方法这里就不列出来了,跟上面的LockBitmap类似

      以上图片由“图斗罗”提供

      www.1click-soft.comtruehttp://www.1click-soft.com/C_jc/1229120.htmlTechArticleC#加快Bitmap的访问速度, 在对Bitmap图片操作的时候,有时需要用到获取或设置像素颜色方法:GetPixel 和 SetPixel, 如果直接对这两个方法进行...

      相关文章

        暂无相关文章
      相关搜索:

      帮客评论

      视觉看点
      百度 360 搜狗