陈程的技术博客

  • 关于作者
全栈软件工程师
一个专注于技术研究创新的程序员
  1. 首页
  2. .NET
  3. 正文

检测图片是否是空白页,GetPixel高效处理

2020年8月26日 1068点热度 0人点赞 0条评论

处理判断图片是否空白页:

/// <summary>
       /// 检查图片是否空白图片
       /// </summary>
       /// <param name="img">Image</param>
       /// <returns>是否空白图片</returns>
       public static bool CheckTransparentImg(Bitmap bitMap)
       {
           try
           {
               bool blnIsTransparent = false;
               //图片总像素
               int intAll = bitMap.Height * bitMap.Width;
               int intBrightnessCount = 0;

               PointBitmap lockbmp = new PointBitmap(bitMap);
               lockbmp.LockBits();
               //按像素遍历
               for (int intY = 0; intY < bitMap.Height; intY++)
               {
                   for (int intX = 0; intX < bitMap.Width; intX++)
                   {
                       //获取颜色
                       Color color = lockbmp.GetPixel(intX, intY);
                       //Color color = bitMap.GetPixel(intX, intY);
                       float dBrightness = color.GetBrightness();

                       //亮度小于0.2认为不透明
                       if (dBrightness < 0.2)
                       {
                           intBrightnessCount++;
                       }
                   }
               }
               lockbmp.UnlockBits();
               //释放资源
               //bitMap.Dispose();
               //只需要把数量为200以下的,基本能把噪点去掉
               if (intBrightnessCount <= 200)
               {
                   blnIsTransparent = true;
               }

               return blnIsTransparent;
           }
           catch (Exception ex)
           {
               log4netHelper.Error("---报错方法--CheckTransparentImg");
               log4netHelper.Error(ex.Message);
               log4netHelper.Error(ex.StackTrace);
               log4netHelper.Error("---end---");
           }
           return false;
       }

非安全代码获取GetPixel,处理一张A4纸图片的效率大约是0.5S

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;
              }
          }
      }
  }

 

标签: C# winform
最后更新:2021年4月2日

博主

全栈工程师,侧重项目技术解决方案规划和开发

打赏 点赞
< 上一篇
下一篇 >

文章评论

取消回复

分类
  • .NET (65)
  • docker (3)
  • linux (12)
  • python (20)
  • web (14)
  • 小程序 (4)
  • 数据库 (2)
  • 未分类 (4)
  • 杂七杂八 (10)
标签聚合
DevExpress python nginx C# winform linux js centos
最新 热点 随机
最新 热点 随机
.NET开发手册标准参考 招募兼职前端开发 Centos安装dotnet6环境 VS上切换分支,vs编译运行出现bug,A fatal error was encountered彻底解决方案 用C#封装一个线程安全的缓存器,达到目标定时定量更新入库 C#通过特性的方式去校验指定数据是否为空
ListHelper帮助类,DataTable和List之间转换 centos系统执行python或者其他的错误集合 winfrom 解决PictureBox加载图片后不释放内存问题 一个对缓存操作的类DataCache Centos安装dotnet6环境 使用NW.js把B/S应用做成跨平台桌面应用

COPYRIGHT © 2021 陈程的技术博客. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS