zoukankan      html  css  js  c++  java
  • 【转】C#使用ESC指令控制POS打印机打印小票

       1 1.前言
       2  
       3 
       4 C#打印小票可以与普通打印机一样,调用PrintDocument实现。也可以发送标注你的ESC指令实现。由于 调用PrintDocument类时,无法操作使用串口或TCP/IP接口连接的pos打印机,并且无法发送控制指令实现pos打印机的切纸、走纸等动作。因此个人建议使用ESC指令进行打印会更通用。
       5 
       6 本类需要调用 ImageProcessor.cs
       7 
       8  
       9 
      10 2.POS机打印小票ReceiptHelper
      11 using System;
      12 
      13 using System.Collections.Generic;
      14 
      15 using System.Text;
      16 
      17 using System.Runtime.InteropServices;
      18 
      19 using System.Threading;
      20 
      21 using System.Drawing;
      22 
      23 using System.Management;
      24 
      25 using System.IO;
      26 
      27 using LaisonTech.MediaLib;
      28 
      29 using LaisonTech.CommonBLL;
      30 
      31 using Microsoft.Win32.SafeHandles;
      32 
      33  
      34 
      35 namespace LaisonTech.MediaLib
      36 
      37 {
      38 
      39  
      40 
      41 #region 结构体定义
      42 
      43  
      44 
      45     [StructLayout(LayoutKind.Sequential)]
      46 
      47     public struct OVERLAPPED
      48 
      49     {
      50 
      51         int Internal;
      52 
      53         int InternalHigh;
      54 
      55         int Offset;
      56 
      57         int OffSetHigh;
      58 
      59         int hEvent;
      60 
      61     };
      62 
      63  
      64 
      65     [StructLayout(LayoutKind.Sequential)]
      66 
      67     public struct PRINTER_DEFAULTS
      68 
      69     {
      70 
      71  
      72 
      73         public int pDatatype;
      74 
      75  
      76 
      77         public int pDevMode;
      78 
      79  
      80 
      81         public int DesiredAccess;
      82 
      83  
      84 
      85     }
      86 
      87  
      88 
      89     /// <summary>
      90 
      91     /// 对齐方式
      92 
      93     /// </summary>
      94 
      95     public enum eTextAlignMode
      96 
      97     {
      98 
      99         Left = 0,
     100 
     101         Middle = 1,
     102 
     103         Right = 2
     104 
     105     }
     106 
     107  
     108 
     109 #endregion
     110 
     111  
     112 
     113     /// <summary>
     114 
     115     /// 小票打印类
     116 
     117 /// 使用方法:
     118 
     119 /// 1 GetPrinterList获取已经安装的所有打印机列表.
     120 
     121 ///  Open 打开指定打印机
     122 
     123 /// 2 控制打印机动作、执行打印内容之前,必须先调用StartPrint,准备向打印机发送控制指令
     124 
     125 /// 3 调用SetLeft, SetBold, SetAlignMode, SetFontSize ... ...设置打印参数
     126 
     127 /// 4  PrintText 打印内容.注意:打印该行内容后会自动换行(本类会在该行内容末尾添加一个换行符)
     128 
     129 ///   PrintImageFile 或 PrintBitMap打印图片
     130 
     131 /// 5 控制指令和打印内容都发送完毕后,调用 EndPrint执行真正打印动作
     132 
     133     /// 6 退出程序前调用Close
     134 
     135     /// </summary>
     136 
     137     public class ReceiptHelper
     138 
     139     {
     140 
     141         #region 指令定义
     142 
     143        
     144 
     145         private static Byte[] Const_Init = new byte[] { 0x1B, 0x40,
     146 
     147             0x20, 0x20, 0x20, 0x0A,
     148 
     149             0x1B, 0x64,0x10};
     150 
     151  
     152 
     153         //设置左边距
     154 
     155         private const string Const_SetLeft = "1D 4C ";
     156 
     157  
     158 
     159  
     160 
     161         //设置粗体
     162 
     163         private const string Const_SetBold = "1B 45 ";
     164 
     165         private const String Const_Bold_YES = "01";
     166 
     167         private const String Const_Bold_NO = "00";
     168 
     169        
     170 
     171        
     172 
     173         //设置对齐方式
     174 
     175         private const string Const_SetAlign = "1B 61 ";
     176 
     177         private const String Const_Align_Left = "30";
     178 
     179         private const String Const_Align_Middle = "31";
     180 
     181         private const String Const_Align_Right = "32";
     182 
     183  
     184 
     185         //设置字体大小,与 SetBigFont 不能同时使用
     186 
     187         private const string Const_SetFontSize = "1D 21 ";
     188 
     189  
     190 
     191         //设置是否大字体,等同于 SetFontSize = 2
     192 
     193         //private const String Const_SetBigFontBold = "1B 21 38";
     194 
     195         //private const String Const_SetBigFontNotBold = "1B 21 30";
     196 
     197         //private const String Const_SetCancelBigFont = "1B 21 00";
     198 
     199  
     200 
     201         /// <summary>
     202 
     203         /// 打印并走纸
     204 
     205         /// </summary>
     206 
     207         private static Byte[] Const_Cmd_Print = new byte[] { 0x1B, 0x4A, 0x00 };
     208 
     209         //走纸
     210 
     211         private const string Const_FeedForward = "1B 4A ";
     212 
     213         private const string Const_FeedBack = "1B 6A ";
     214 
     215  
     216 
     217         //切纸
     218 
     219         private static Byte[]  Const_SetCut = new byte[] { 0x1D, 0x56, 0x30};
     220 
     221  
     222 
     223         //查询打印机状态
     224 
     225         private static Byte[] Const_QueryID = new byte[] { 0x1D, 0x67, 0x61};
     226 
     227  
     228 
     229         //回复帧以 ID 开头
     230 
     231         private static String Const_ResponseQueryID = "ID";
     232 
     233  
     234 
     235         /// <summary>
     236 
     237         /// 设置图标的指令
     238 
     239         /// </summary>
     240 
     241         private static Byte[] Const_SetImageCommand = new Byte[] { 0x1B, 0x2A, 0x21 };
     242 
     243  
     244 
     245 #endregion
     246 
     247        
     248 
     249         #region 常量定义
     250 
     251  
     252 
     253         /// <summary>
     254 
     255         /// 最大字体大小
     256 
     257         /// </summary>
     258 
     259         public const Int32 Const_MaxFontSize = 8;
     260 
     261         /// <summary>
     262 
     263         /// 最大走纸距离
     264 
     265         /// </summary>
     266 
     267         public const Int32 Const_MaxFeedLength = 5000;
     268 
     269  
     270 
     271         /// <summary>
     272 
     273         /// 最大高宽
     274 
     275         /// </summary>
     276 
     277         public const Int32 Const_MaxImageLength = 480;
     278 
     279        
     280 
     281         /// <summary>
     282 
     283         /// 每次通信最多打印的行数
     284 
     285         /// </summary>
     286 
     287         public const Int32 Const_OncePrintRowCount = 24;
     288 
     289  
     290 
     291         public const Int32 Const_BrightnessGate = 100;
     292 
     293  
     294 
     295         /// <summary>
     296 
     297         /// 无效句柄
     298 
     299         /// </summary>
     300 
     301         public const Int32 Const_InvalidHandle = -1;
     302 
     303         #endregion
     304 
     305  
     306 
     307         #region 私有成员
     308 
     309  
     310 
     311         /// <summary>
     312 
     313         /// 打印机句柄
     314 
     315         /// </summary>
     316 
     317         private int m_Handle = -1;
     318 
     319  
     320 
     321         /// <summary>
     322 
     323         /// 是否已经初始化
     324 
     325         /// </summary>
     326 
     327         private Boolean m_Inited = false;
     328 
     329  
     330 
     331  
     332 
     333         #endregion
     334 
     335        
     336 
     337         #region 私有函数
     338 
     339                
     340 
     341         [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
     342 
     343         public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter,
     344 
     345             out Int32 hPrinter, IntPtr pd);
     346 
     347  
     348 
     349         [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
     350 
     351         public static extern bool StartDocPrinter(Int32 hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
     352 
     353  
     354 
     355         [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
     356 
     357         public static extern bool EndDocPrinter(Int32 hPrinter);
     358 
     359  
     360 
     361         [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
     362 
     363         public static extern bool StartPagePrinter(Int32 hPrinter);
     364 
     365  
     366 
     367         [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
     368 
     369         public static extern bool EndPagePrinter(Int32 hPrinter);
     370 
     371  
     372 
     373         [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
     374 
     375         public static extern bool WritePrinter(Int32 hPrinter, Byte[] pBytes, Int32 dwCount, out Int32 dwWritten);
     376 
     377       
     378 
     379         [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
     380 
     381         public static extern bool ClosePrinter(Int32 hPrinter);
     382 
     383        
     384 
     385  
     386 
     387         /// <summary>
     388 
     389         /// 发送指令
     390 
     391         /// </summary>
     392 
     393         /// <param name="cmd"></param>
     394 
     395         /// <returns></returns>
     396 
     397         private Boolean SendCommand(Byte[] cmd)
     398 
     399         {
     400 
     401             if (m_Handle == Const_InvalidHandle || cmd == null || cmd.Length < 2)
     402 
     403             {
     404 
     405                 return false;
     406 
     407             }
     408 
     409  
     410 
     411             int writelen = 0;
     412 
     413             Boolean bl = WritePrinter(m_Handle, cmd, cmd.Length, out writelen);
     414 
     415  
     416 
     417             if (!bl) return false;
     418 
     419             return (writelen >= cmd.Length);
     420 
     421         }
     422 
     423        
     424 
     425         /// <summary>
     426 
     427         /// 发送文本格式的指令
     428 
     429         /// </summary>
     430 
     431         /// <param name="cmd"></param>
     432 
     433         /// <returns></returns>
     434 
     435         private Boolean SendCommand(String hexstrcmd)
     436 
     437         {
     438 
     439             if (m_Handle == Const_InvalidHandle || hexstrcmd == null || hexstrcmd.Length < 4)
     440 
     441             {
     442 
     443                 return false;
     444 
     445             }
     446 
     447            
     448 
     449             byte[] mybyte = null;
     450 
     451             Boolean bl = DataFormatProcessor.HexStringToBytes(hexstrcmd, out mybyte);
     452 
     453             bl = SendCommand(mybyte);
     454 
     455             return bl;
     456 
     457         }
     458 
     459  
     460 
     461    
     462 
     463         #endregion
     464 
     465  
     466 
     467         #region 内部处理 - 打印图片
     468 
     469  
     470 
     471         /// <summary>
     472 
     473         /// 把图片转换为指令字节,图片最大高宽不能超过480
     474 
     475         /// </summary>
     476 
     477         /// <param name="image"></param>
     478 
     479         /// <param name="bmpbytes"></param>
     480 
     481         /// <returns></returns>
     482 
     483         public static Boolean LoadImage(Bitmap image,
     484 
     485             ref Byte[] bitarray,ref Int32 datawidth,ref Int32 dataheight)
     486 
     487         {
     488 
     489             Int32 newwidth = 0;
     490 
     491             Int32 newheight = 0;
     492 
     493             Bitmap destimage = image;
     494 
     495             Boolean bl = false;
     496 
     497  
     498 
     499             //如果高度超过范围,或宽度超过范围,需要进行缩小
     500 
     501             if (image.Width > Const_MaxImageLength || image.Height > Const_MaxImageLength)
     502 
     503             {
     504 
     505                 //按照高度和宽度,较大的那一边,进行缩放
     506 
     507                 if (image.Width > image.Height)
     508 
     509                 {
     510 
     511                     newwidth = Const_MaxImageLength;
     512 
     513                     newheight = (Int32)(image.Height * newwidth / (float)image.Width);
     514 
     515                 }
     516 
     517                 else
     518 
     519                 {
     520 
     521                     newheight = Const_MaxImageLength;
     522 
     523                     newwidth = (Int32)(newheight * image.Width / (float)image.Height);
     524 
     525                 }
     526 
     527  
     528 
     529                 bl = ImageProcessor.ResizeImage(image, newwidth, newheight, ref destimage);
     530 
     531             }
     532 
     533  
     534 
     535             //把数据转换为字节数组
     536 
     537             bl = GetBitArray(image, ref bitarray, ref datawidth, ref dataheight);
     538 
     539             return bl;
     540 
     541         }
     542 
     543  
     544 
     545         /// <summary>
     546 
     547         /// 把图片转换为指令字节,图片最大高宽不能超过480
     548 
     549         /// 如果图片的高度不是24的整数倍,则修改为24的整数倍
     550 
     551         /// </summary>
     552 
     553         /// <param name="image"></param>
     554 
     555         /// <param name="bmpbytes"></param>
     556 
     557         /// <returns></returns>
     558 
     559         public static Boolean LoadImageFromFile(String imagefilename, ref Byte[] bmpbytes,
     560 
     561             ref Int32 width, ref Int32 height)
     562 
     563         {
     564 
     565             Bitmap img = ImageProcessor.LoadBitImage(imagefilename);
     566 
     567             if (img == null)
     568 
     569             {
     570 
     571                 return false;
     572 
     573             }
     574 
     575  
     576 
     577             Boolean bl = LoadImage(img, ref bmpbytes, ref width, ref height);
     578 
     579             return bl;
     580 
     581         }
     582 
     583        
     584 
     585         /// <summary>
     586 
     587         /// 把图片转换为位图数组,每个字节的每个比特位,对应当前像素 是否需要打印
     588 
     589         /// </summary>
     590 
     591         /// <param name="img"></param>
     592 
     593         /// <param name="allbitary"></param>
     594 
     595         /// <returns></returns>
     596 
     597         public static Boolean GetBitArray(Bitmap img,
     598 
     599             ref Byte[] allbitary, ref Int32 width, ref Int32 height)
     600 
     601         {
     602 
     603             if (img == null)
     604 
     605             {
     606 
     607                 return false;
     608 
     609             }
     610 
     611  
     612 
     613             //ESC指令格式规定:
     614 
     615             //1 打印图片时,每条指令最多只打印24行;不足24行的,也要用全0填充满数据字节
     616 
     617             //2 打印24行数据时,按照光栅模式纵向获取数据
     618 
     619             //  即先获取所有x=0的点(第0列)转换为3个字节;
     620 
     621             //  再获取所有x=1的点转换为3个字节;...直到获取到最右侧一列的点
     622 
     623             //3 打印完当前24行数据后,再获取后续24行的数据内容,直到所有的数据获取完毕
     624 
     625  
     626 
     627             //获取亮度数组
     628 
     629             Boolean[] briary = null;
     630 
     631             Boolean bl = ImageProcessor.ToBooleanArray(img, Const_BrightnessGate, ref briary);
     632 
     633             if (!bl)
     634 
     635             {
     636 
     637                 return false;
     638 
     639             }
     640 
     641  
     642 
     643             height = img.Height;//如果图像高度不是24整数倍,设置为24的整数倍       
     644 
     645             if (height % Const_OncePrintRowCount != 0)
     646 
     647             {
     648 
     649                 height = height + Const_OncePrintRowCount - height % Const_OncePrintRowCount;
     650 
     651             }
     652 
     653  
     654 
     655             width = img.Width;//如果图像宽度不是8的整数倍,设置为8的整数倍
     656 
     657             if (width % 8 != 0)
     658 
     659             {
     660 
     661                 width = width + 8 - width % 8;
     662 
     663             }
     664 
     665  
     666 
     667             Int32 bytelen = height * width / 8;//每个像素对应1个比特位,因此总字节数=像素位数/8
     668 
     669  
     670 
     671             allbitary = new Byte[bytelen];
     672 
     673  
     674 
     675             Int32 byteidxInCol = 0;//当前列里首个像素,在目标字节数组里的下标
     676 
     677             Int32 byteidx = 0;//当前像素在目标数组里的字节下标
     678 
     679             Int32 bitidx = 0;//当前像素在目标数组里当前字节里的比特位下标
     680 
     681             Int32 pixidxInCol = 0;//当前像素在当前列里的第几个位置
     682 
     683  
     684 
     685             Int32 pixidx = 0;//当前像素在原始图片里的下标
     686 
     687            
     688 
     689             Int32 rowidx = 0; //当前 处理的像素点所在行,不能超过 图像高度
     690 
     691             Int32 curprocrows = 0;//当前需要处理的行数量
     692 
     693             while (rowidx < height)
     694 
     695             {
     696 
     697                 //按照纵向次序,把当前列的24个数据,转换为3个字节
     698 
     699                 for (Int32 colidx = 0; colidx < img.Width; ++colidx)
     700 
     701                 {
     702 
     703                     //如果当前还剩余超过24行没处理,处理24行
     704 
     705                     if (rowidx + Const_OncePrintRowCount <= img.Height)
     706 
     707                     {
     708 
     709                         curprocrows = Const_OncePrintRowCount;
     710 
     711                     }
     712 
     713                     else
     714 
     715                     {
     716 
     717                         //已经不足24行,只处理剩余行数
     718 
     719                         curprocrows = img.Height - rowidx;
     720 
     721                     }
     722 
     723  
     724 
     725                     pixidxInCol = 0; //本列里从像素0开始处理
     726 
     727                     for (Int32 y = rowidx; y < rowidx + curprocrows; ++y)
     728 
     729                     {
     730 
     731                         //原始图片里像素位置
     732 
     733                         pixidx = y * img.Width + colidx;
     734 
     735  
     736 
     737                         //获取当前像素的亮度值.如果当前像素是黑点,需要把数组里的对应比特位设置为1
     738 
     739                         if (briary[pixidx])
     740 
     741                         {
     742 
     743                             bitidx = 7 - pixidxInCol % 8;//最高比特位对应首个像素.最低比特位对应末个像素
     744 
     745                             byteidx = byteidxInCol + pixidxInCol / 8; //由于最后一段可能不足24行,因此不能使用byteidx++
     746 
     747                            
     748 
     749                             DataFormatProcessor.SetBitValue(bitidx, true, ref allbitary[byteidx]);
     750 
     751                         }
     752 
     753                         pixidxInCol++;
     754 
     755                     }
     756 
     757                     byteidxInCol += 3;//每列固定24个像素,3个字节
     758 
     759                 }
     760 
     761  
     762 
     763                 rowidx += Const_OncePrintRowCount;
     764 
     765             }
     766 
     767            
     768 
     769             return true;
     770 
     771         }
     772 
     773  
     774 
     775         #endregion
     776 
     777  
     778 
     779         #region 公开函数
     780 
     781  
     782 
     783         private static ReceiptHelper m_instance = new ReceiptHelper();
     784 
     785  
     786 
     787         /// <summary>
     788 
     789         /// 当前使用的打印机名称
     790 
     791         /// </summary>
     792 
     793         public String PrinterName
     794 
     795         {
     796 
     797             get;private set;
     798 
     799         }
     800 
     801  
     802 
     803         /// <summary>
     804 
     805         /// 单件模式
     806 
     807         /// </summary>
     808 
     809         /// <returns></returns>
     810 
     811         public static ReceiptHelper GetInstance()
     812 
     813         {
     814 
     815             return m_instance;
     816 
     817         }
     818 
     819  
     820 
     821         /// <summary>
     822 
     823         /// 获取本机安装的所有打印机
     824 
     825         /// </summary>
     826 
     827         /// <returns></returns>
     828 
     829         public static List<String> GetPrinterList()
     830 
     831         {
     832 
     833             List<String> ret = new List<String>();
     834 
     835             if (PrinterSettings.InstalledPrinters.Count < 1)
     836 
     837             {
     838 
     839                 return ret;
     840 
     841             }
     842 
     843  
     844 
     845             foreach (String printername in PrinterSettings.InstalledPrinters)
     846 
     847             {
     848 
     849                 ret.Add(printername);
     850 
     851             }
     852 
     853             return ret;
     854 
     855         }
     856 
     857  
     858 
     859         /// <summary>
     860 
     861         /// 打开打印机
     862 
     863         /// </summary>
     864 
     865         /// <param name="printername"></param>
     866 
     867         /// <returns></returns>
     868 
     869         public Boolean Open(String printername)
     870 
     871         {
     872 
     873             if (m_Inited)
     874 
     875             {
     876 
     877                 return true;
     878 
     879             }
     880 
     881             Boolean bl = OpenPrinter(printername.Normalize(), out m_Handle, IntPtr.Zero); 
     882 
     883             
     884 
     885             m_Inited = (bl && m_Handle != 0); 
     886 
     887             return true;
     888 
     889         }
     890 
     891  
     892 
     893         /// <summary>
     894 
     895         /// 开始打印,在打印之前必须调用此函数
     896 
     897         /// </summary>
     898 
     899         /// <returns></returns>
     900 
     901         public Boolean StartPrint()
     902 
     903         {
     904 
     905             if (!m_Inited)
     906 
     907             {
     908 
     909                 return false;
     910 
     911             }
     912 
     913             DOCINFOA di = new DOCINFOA();
     914 
     915             di.pDocName = "My C#.NET RAW Document";
     916 
     917             di.pDataType = "RAW";
     918 
     919             //Start a document.
     920 
     921             Boolean bl = StartDocPrinter(m_Handle, 1, di);
     922 
     923             if (!bl)
     924 
     925             {
     926 
     927                 return false;
     928 
     929             }
     930 
     931             // Start a page.
     932 
     933             bl = StartPagePrinter(m_Handle);
     934 
     935             return bl;
     936 
     937         }
     938 
     939  
     940 
     941         /// <summary>
     942 
     943         /// 结束打印,在打印结束之后必须调用此函数
     944 
     945         /// </summary>
     946 
     947         /// <returns></returns>
     948 
     949         public Boolean EndPrint()
     950 
     951         {
     952 
     953             if (!m_Inited)
     954 
     955             {
     956 
     957                 return false;
     958 
     959             }
     960 
     961             Boolean bl = EndPagePrinter(m_Handle);
     962 
     963             bl = EndDocPrinter(m_Handle);
     964 
     965             return bl;
     966 
     967         }
     968 
     969        
     970 
     971         /// <summary>
     972 
     973         /// 销毁
     974 
     975         /// </summary>
     976 
     977         /// <returns></returns>
     978 
     979         public Boolean Close()
     980 
     981         {
     982 
     983             if (!m_Inited)
     984 
     985             {
     986 
     987                 return true;
     988 
     989             }
     990 
     991             m_Inited = false;
     992 
     993  
     994 
     995             //关闭设备句柄
     996 
     997             ClosePrinter(m_Handle);
     998 
     999             m_Handle = -1;
    1000 
    1001             return true;
    1002 
    1003         }
    1004 
    1005        
    1006 
    1007         /// <summary>
    1008 
    1009         /// 打印文本.在调用本函数之前必须先调用正确的 设置字体、左边距
    1010 
    1011         /// </summary>
    1012 
    1013         /// <param name="content"></param>
    1014 
    1015         /// <returns></returns>
    1016 
    1017         public Boolean PrintText(String content)
    1018 
    1019         {
    1020 
    1021             if (!m_Inited)
    1022 
    1023             {
    1024 
    1025                 return false;
    1026 
    1027             }
    1028 
    1029  
    1030 
    1031             byte[] bytes = null;
    1032 
    1033             if (content.Length < 1)
    1034 
    1035             {
    1036 
    1037                 content =  "  ";
    1038 
    1039             }
    1040 
    1041            
    1042 
    1043             if (content[content.Length - 1] != (char)0x0D &&
    1044 
    1045                 content[content.Length - 1] != (char)0x0A)
    1046 
    1047             {
    1048 
    1049                 content = content + (char)0x0A;
    1050 
    1051             }
    1052 
    1053            
    1054 
    1055             bytes = DataFormatProcessor.StringToBytes(content);
    1056 
    1057             bool bl = SendCommand(bytes);
    1058 
    1059             return bl;
    1060 
    1061         }
    1062 
    1063  
    1064 
    1065         /// <summary>
    1066 
    1067         /// 设置对齐方式
    1068 
    1069         /// </summary>
    1070 
    1071         /// <param name="left"></param>
    1072 
    1073         /// <returns></returns>
    1074 
    1075         public bool SetAlignMode(eTextAlignMode alignmode)
    1076 
    1077         {
    1078 
    1079             if (!m_Inited)
    1080 
    1081             {
    1082 
    1083                 return false;
    1084 
    1085             }
    1086 
    1087  
    1088 
    1089             String code = String.Empty;
    1090 
    1091             switch (alignmode)
    1092 
    1093             {
    1094 
    1095                 case eTextAlignMode.Left:
    1096 
    1097                     code = Const_Align_Left;
    1098 
    1099                     break;
    1100 
    1101                 case eTextAlignMode.Middle:
    1102 
    1103                     code = Const_Align_Middle;
    1104 
    1105                     break;
    1106 
    1107                 case eTextAlignMode.Right:
    1108 
    1109                     code = Const_Align_Right;
    1110 
    1111                     break;
    1112 
    1113                 default:
    1114 
    1115                     code = Const_Align_Left;
    1116 
    1117                     break;
    1118 
    1119             }
    1120 
    1121  
    1122 
    1123             //注意:先低字节后高字节
    1124 
    1125             string str = Const_SetAlign + code;
    1126 
    1127             bool bl = SendCommand(str);
    1128 
    1129             return bl;
    1130 
    1131         }
    1132 
    1133        
    1134 
    1135         /// <summary>
    1136 
    1137         /// 设置左边距
    1138 
    1139         /// </summary>
    1140 
    1141         /// <param name="left"></param>
    1142 
    1143         /// <returns></returns>
    1144 
    1145         public bool SetLeft(int left)
    1146 
    1147         {
    1148 
    1149             if (!m_Inited)
    1150 
    1151             {
    1152 
    1153                 return false;
    1154 
    1155             }
    1156 
    1157  
    1158 
    1159             //注意:先低字节后高字节
    1160 
    1161             String hexstr = left.ToString("X4");
    1162 
    1163             string str = Const_SetLeft + hexstr.Substring(2, 2) + hexstr.Substring(0, 2);
    1164 
    1165             bool bl = SendCommand(str);
    1166 
    1167             return bl;
    1168 
    1169         }
    1170 
    1171  
    1172 
    1173         /// <summary>
    1174 
    1175         /// 设置粗体
    1176 
    1177         /// </summary>
    1178 
    1179         /// <param name="bold"></param>
    1180 
    1181         /// <returns></returns>
    1182 
    1183         public Boolean SetBold(Boolean bold)
    1184 
    1185         {
    1186 
    1187             if (!m_Inited)
    1188 
    1189             {
    1190 
    1191                 return false;
    1192 
    1193             }
    1194 
    1195  
    1196 
    1197             //注意:先低字节后高字节
    1198 
    1199             String str = String.Empty;
    1200 
    1201             if (bold)
    1202 
    1203             {
    1204 
    1205                 str = Const_SetBold + Const_Bold_YES;
    1206 
    1207             }
    1208 
    1209             else
    1210 
    1211             {
    1212 
    1213                 str = Const_SetBold + Const_Bold_NO;
    1214 
    1215             }
    1216 
    1217             bool bl = SendCommand(str);
    1218 
    1219             return bl;
    1220 
    1221         }
    1222 
    1223  
    1224 
    1225         /// <summary>
    1226 
    1227         /// 切纸
    1228 
    1229         /// </summary>
    1230 
    1231         /// <returns></returns>
    1232 
    1233         public bool Cut()
    1234 
    1235         {
    1236 
    1237             if (!m_Inited)
    1238 
    1239             {
    1240 
    1241                 return false;
    1242 
    1243             }
    1244 
    1245             bool bl = SendCommand(Const_SetCut);
    1246 
    1247             return bl;
    1248 
    1249         }
    1250 
    1251  
    1252 
    1253  
    1254 
    1255         /// <summary>
    1256 
    1257         /// 打印图片
    1258 
    1259         /// </summary>
    1260 
    1261         /// <param name="bitmap"></param>
    1262 
    1263         /// <returns></returns>
    1264 
    1265         public bool PrintImageFile(String imgfilename)
    1266 
    1267         {
    1268 
    1269             if (!m_Inited)
    1270 
    1271             {
    1272 
    1273                 return false;
    1274 
    1275             }
    1276 
    1277             Bitmap img = ImageProcessor.LoadBitImage(imgfilename);
    1278 
    1279             if (img == null)
    1280 
    1281             {
    1282 
    1283                 return false;
    1284 
    1285             }
    1286 
    1287  
    1288 
    1289             Boolean bl = PrintBitmap(img);
    1290 
    1291             return bl;
    1292 
    1293         }
    1294 
    1295        
    1296 
    1297         /// <summary>
    1298 
    1299         /// 打印图片
    1300 
    1301         /// </summary>
    1302 
    1303         /// <param name="bitmap"></param>
    1304 
    1305         /// <returns></returns>
    1306 
    1307         public bool PrintBitmap(Bitmap bitmap)
    1308 
    1309         {
    1310 
    1311             if (!m_Inited)
    1312 
    1313             {
    1314 
    1315                 return false;
    1316 
    1317             }
    1318 
    1319  
    1320 
    1321             if (bitmap == null ||
    1322 
    1323                 bitmap.Width > Const_MaxImageLength ||
    1324 
    1325                 bitmap.Height > Const_MaxImageLength)
    1326 
    1327             {
    1328 
    1329                 return false;
    1330 
    1331             }
    1332 
    1333  
    1334 
    1335             Byte[] bitary = null;
    1336 
    1337             Int32 width = 0;
    1338 
    1339             Int32 height = 0;
    1340 
    1341             Boolean bl = GetBitArray(bitmap, ref bitary, ref width, ref height);
    1342 
    1343  
    1344 
    1345             bl = PrintBitmapBytes(bitary, bitmap.Width, bitmap.Height);
    1346 
    1347             return bl;
    1348 
    1349         }
    1350 
    1351  
    1352 
    1353         /// <summary>
    1354 
    1355         /// 打印图片
    1356 
    1357         /// </summary>
    1358 
    1359         /// <param name="bitmap"></param>
    1360 
    1361         /// <returns></returns>
    1362 
    1363         public bool PrintBitmapBytes(Byte[] imgbitarray, Int32 width, Int32 height)
    1364 
    1365         {
    1366 
    1367             if (!m_Inited)
    1368 
    1369             {
    1370 
    1371                 return false;
    1372 
    1373             }
    1374 
    1375             Int32 bytes = width * height / 8;
    1376 
    1377             //检查是否尺寸符合要求
    1378 
    1379             if (width > Const_MaxImageLength || height > Const_MaxFeedLength ||
    1380 
    1381                 width < 1 || height < 1 ||
    1382 
    1383                 imgbitarray == null)
    1384 
    1385             {
    1386 
    1387                 return false;
    1388 
    1389             }
    1390 
    1391             
    1392 
    1393             //每次获取24行的数据进行发送,这24行的字节数
    1394 
    1395             Int32 blockbytes = width * Const_OncePrintRowCount / 8;
    1396 
    1397             if (blockbytes < 1)
    1398 
    1399             {
    1400 
    1401                 return false;
    1402 
    1403             }
    1404 
    1405  
    1406 
    1407             Boolean bl = false;
    1408 
    1409  
    1410 
    1411             //一共需要发送的块数量
    1412 
    1413             Int32 blocks = imgbitarray.Length / blockbytes;
    1414 
    1415  
    1416 
    1417             //每次发送的数据字节数 = 1B 2A 21 2字节长度 + 数据内容
    1418 
    1419             Byte[] cmdbytes = new Byte[5 + blockbytes];
    1420 
    1421             //指令
    1422 
    1423             Array.Copy(Const_SetImageCommand, cmdbytes, 3);
    1424 
    1425             //数据长度,即 每行的点数
    1426 
    1427             DataFormatProcessor.Int16ToBytes(width, ref cmdbytes, 3);
    1428 
    1429             //数据内容
    1430 
    1431             for (Int32 blockidx = 0; blockidx < blocks; ++blockidx)
    1432 
    1433             {
    1434 
    1435                 Array.Copy(imgbitarray, blockidx * blockbytes, cmdbytes, 5, blockbytes);
    1436 
    1437                 //发送当前指令
    1438 
    1439                 bl = SendCommand(cmdbytes);
    1440 
    1441                 if (!bl) return false;
    1442 
    1443                 //休眠20毫秒
    1444 
    1445                 Thread.Sleep(20);
    1446 
    1447                 //发送 打印指令
    1448 
    1449                 bl = SendCommand(Const_Cmd_Print);
    1450 
    1451                 if (!bl) return false;
    1452 
    1453             }
    1454 
    1455  
    1456 
    1457             return bl;
    1458 
    1459         }
    1460 
    1461  
    1462 
    1463         /// <summary>
    1464 
    1465         /// 走纸
    1466 
    1467         /// </summary>
    1468 
    1469         /// <param name="length"></param>
    1470 
    1471         /// <returns></returns>
    1472 
    1473         public bool Feed(int length)
    1474 
    1475         {
    1476 
    1477             if (!m_Inited)
    1478 
    1479             {
    1480 
    1481                 return false;
    1482 
    1483             }
    1484 
    1485             if (length < 1)
    1486 
    1487                 length = 1;
    1488 
    1489             if (length > Const_MaxFeedLength)
    1490 
    1491             {
    1492 
    1493                 length = Const_MaxFeedLength;
    1494 
    1495             }
    1496 
    1497             string len = length.ToString("X2");
    1498 
    1499             len = Const_FeedForward + len;
    1500 
    1501             bool bl = SendCommand(len);
    1502 
    1503             return bl;
    1504 
    1505         }
    1506 
    1507  
    1508 
    1509         /// <summary>
    1510 
    1511         /// 回退走纸
    1512 
    1513         /// </summary>
    1514 
    1515         /// <param name="length"></param>
    1516 
    1517         /// <returns></returns>
    1518 
    1519         public bool FeedBack(int length)
    1520 
    1521         {
    1522 
    1523             if (!m_Inited)
    1524 
    1525             {
    1526 
    1527                 return false;
    1528 
    1529             }
    1530 
    1531             if (length < 1)
    1532 
    1533                 length = 1;
    1534 
    1535             if (length > Const_MaxFeedLength)
    1536 
    1537             {
    1538 
    1539                 length = Const_MaxFeedLength;
    1540 
    1541             }
    1542 
    1543             string len = length.ToString("X2");
    1544 
    1545             len = Const_FeedBack + len;
    1546 
    1547             bool bl = SendCommand(len);
    1548 
    1549             return bl;
    1550 
    1551         }
    1552 
    1553        
    1554 
    1555         /// <summary>
    1556 
    1557         /// 设置字体大小.本函数不可与SetBigFont同时使用
    1558 
    1559         /// </summary>
    1560 
    1561         /// <param name="sizerate">大小倍率,取值范围 1 - 8</param>
    1562 
    1563         /// <returns></returns>
    1564 
    1565         public bool SetFontSize(Int32 sizerate)
    1566 
    1567         {
    1568 
    1569             if (!m_Inited)
    1570 
    1571             {
    1572 
    1573                 return false;
    1574 
    1575             }
    1576 
    1577            
    1578 
    1579             if (sizerate < 1)
    1580 
    1581             {
    1582 
    1583                 sizerate = 1;
    1584 
    1585             }
    1586 
    1587  
    1588 
    1589             if (sizerate > Const_MaxFontSize)
    1590 
    1591             {
    1592 
    1593                 sizerate = Const_MaxFontSize;
    1594 
    1595             }
    1596 
    1597             sizerate--;
    1598 
    1599             String sizecodestr = Const_SetFontSize + sizerate.ToString("X1") + sizerate.ToString("X1");
    1600 
    1601             bool bl = SendCommand(sizecodestr);
    1602 
    1603             return bl;
    1604 
    1605         }
    1606 
    1607  
    1608 
    1609         #endregion
    1610 
    1611  
    1612 
    1613         
    1614 
    1615  
    1616 
    1617     }
    1618 
    1619 }
    1620 
    1621  
    1622 
    1623 3.图像处理 ImageProcessor
    1624 using System;
    1625 
    1626 using System.Collections.Generic;
    1627 
    1628 using System.Linq;
    1629 
    1630 using System.Text;
    1631 
    1632 using System.Drawing;
    1633 
    1634 using LaisonTech.CommonBLL;
    1635 
    1636 using System.Drawing.Imaging;
    1637 
    1638 using System.IO;
    1639 
    1640 using System.Drawing.Drawing2D;
    1641 
    1642 using System.Windows.Forms;
    1643 
    1644 using AForge.Imaging.Filters;
    1645 
    1646  
    1647 
    1648 namespace LaisonTech.MediaLib
    1649 
    1650 {
    1651 
    1652     /// <summary>
    1653 
    1654     /// 图片格式
    1655 
    1656     /// </summary>
    1657 
    1658     public enum ePictureFileFormat
    1659 
    1660     {
    1661 
    1662         Bmp = 0,
    1663 
    1664         Gif = 1,
    1665 
    1666         Icon = 2,
    1667 
    1668         Jpeg = 3,
    1669 
    1670         Png = 4,
    1671 
    1672     }
    1673 
    1674  
    1675 
    1676     /// <summary>
    1677 
    1678     /// 转为灰度图像的方式
    1679 
    1680     /// </summary>
    1681 
    1682     public enum eGrayMode
    1683 
    1684     {
    1685 
    1686         /// <summary>
    1687 
    1688         /// 算数平均
    1689 
    1690         /// </summary>
    1691 
    1692         ArithmeticAverage = 0,
    1693 
    1694         /// <summary>
    1695 
    1696         /// 加权平均
    1697 
    1698         /// </summary>
    1699 
    1700         WeightedAverage = 1,
    1701 
    1702     }
    1703 
    1704  
    1705 
    1706     /// <summary>
    1707 
    1708     /// 比较2个图片的指定区域范围,像素的相同类型
    1709 
    1710     /// </summary>
    1711 
    1712     public enum eAreaDifferentType
    1713 
    1714     {
    1715 
    1716         /// <summary>
    1717 
    1718         /// 所有像素都相同
    1719 
    1720         /// </summary>
    1721 
    1722         AllSame = 0,
    1723 
    1724         /// <summary>
    1725 
    1726         /// 所有像素都不同
    1727 
    1728         /// </summary>
    1729 
    1730         AllDifferent = 1,
    1731 
    1732         /// <summary>
    1733 
    1734         /// 部分相同部分不同
    1735 
    1736         /// </summary>
    1737 
    1738         Partial = 2,
    1739 
    1740     }
    1741 
    1742  
    1743 
    1744     /// <summary>
    1745 
    1746     /// 图片文件处理
    1747 
    1748     /// </summary>
    1749 
    1750     public class ImageProcessor
    1751 
    1752     {
    1753 
    1754         #region 常量定义
    1755 
    1756  
    1757 
    1758         public const Byte Const_BrightnessWhite = 255;
    1759 
    1760         public const Byte Const_BrightnessBlack = 0;
    1761 
    1762  
    1763 
    1764  
    1765 
    1766         /// <summary>
    1767 
    1768         /// 比较结果的图片里,亮度相同部分的填充颜色
    1769 
    1770         /// </summary>
    1771 
    1772         public static Color Const_SameBrightnessColor = Color.Black;
    1773 
    1774         /// <summary>
    1775 
    1776         /// 比较结果的图片里,亮度相同部分的填充颜色
    1777 
    1778         /// </summary>
    1779 
    1780         public static Color Const_DifferentBrightnessColor = Color.White;
    1781 
    1782  
    1783 
    1784         public const Byte Const_BlackBrightness = 0;
    1785 
    1786         public const Byte Const_WhiteBrightness = 255;
    1787 
    1788         public const Int32 Const_MaxBrightness = 255;
    1789 
    1790  
    1791 
    1792         public const Int32 Const_MinBrightness = -255;
    1793 
    1794  
    1795 
    1796         /// <summary>
    1797 
    1798         /// 亮度的中间值
    1799 
    1800         /// </summary>
    1801 
    1802         public const Int32 Const_MiddleBrightness = 128;
    1803 
    1804         #endregion
    1805 
    1806  
    1807 
    1808         #region 屏幕截图,打印
    1809 
    1810  
    1811 
    1812         /// <summary>
    1813 
    1814         /// 获取屏幕分辨率
    1815 
    1816         /// </summary>
    1817 
    1818         /// <param name="width"></param>
    1819 
    1820         /// <param name="height"></param>
    1821 
    1822         public static void GetScreenSize(ref Int32 width, ref Int32 height)
    1823 
    1824         {
    1825 
    1826             height = Screen.PrimaryScreen.Bounds.Height;
    1827 
    1828             width = Screen.PrimaryScreen.Bounds.Width;
    1829 
    1830         }
    1831 
    1832  
    1833 
    1834         /// <summary>
    1835 
    1836         ///截图指定控件上显示的内容
    1837 
    1838         /// </summary>
    1839 
    1840         /// <param name="ctrl"></param>
    1841 
    1842         /// <returns></returns>
    1843 
    1844         public static Image CaptureControlImage(Control ctrl)
    1845 
    1846         {
    1847 
    1848             if (ctrl == null)
    1849 
    1850             {
    1851 
    1852                 return null;
    1853 
    1854             }
    1855 
    1856  
    1857 
    1858             Control parent = ctrl;
    1859 
    1860             if (ctrl.Parent != null)
    1861 
    1862             {
    1863 
    1864                 parent = ctrl.Parent;
    1865 
    1866             }
    1867 
    1868             Point screenPoint = parent.PointToScreen(ctrl.Location);
    1869 
    1870  
    1871 
    1872             Image ret = new Bitmap(ctrl.Width, ctrl.Height);
    1873 
    1874             Graphics g = Graphics.FromImage(ret);
    1875 
    1876             g.CopyFromScreen(screenPoint.X, screenPoint.Y,
    1877 
    1878                 0, 0, ctrl.Size);
    1879 
    1880             g.DrawImage(ret, 0, 0);
    1881 
    1882  
    1883 
    1884             return ret;
    1885 
    1886         }
    1887 
    1888  
    1889 
    1890  
    1891 
    1892         #endregion
    1893 
    1894  
    1895 
    1896         #region 装载图片
    1897 
    1898  
    1899 
    1900         /// <summary>
    1901 
    1902         /// 装载图像文件
    1903 
    1904         /// </summary>
    1905 
    1906         /// <param name="filename"></param>
    1907 
    1908         /// <returns></returns>
    1909 
    1910         public static Image LoadImage(String filename)
    1911 
    1912         {
    1913 
    1914             //Boolean bl = FileProcessor.FileExist(filename);
    1915 
    1916             //if (!bl)
    1917 
    1918             //{
    1919 
    1920             //    return null;
    1921 
    1922             //}
    1923 
    1924             //Bitmap image = (Bitmap)Bitmap.FromFile(filename);
    1925 
    1926             //return image;
    1927 
    1928  
    1929 
    1930             //以上方法会导致图片文件被锁定,无法删除移动
    1931 
    1932  
    1933 
    1934             Byte[] photodata = null;
    1935 
    1936             Boolean bl = FileProcessor.FileExist(filename);
    1937 
    1938             if (!bl)
    1939 
    1940             {
    1941 
    1942                 return null;
    1943 
    1944             }
    1945 
    1946  
    1947 
    1948             bl = FileProcessor.ReadFileBytes(filename, out photodata);
    1949 
    1950             if (!bl)
    1951 
    1952             {
    1953 
    1954                 return null;
    1955 
    1956             }
    1957 
    1958  
    1959 
    1960             MemoryStream ms = null;
    1961 
    1962             Image myImage = null;
    1963 
    1964             try
    1965 
    1966             {
    1967 
    1968                 ms = new MemoryStream(photodata);
    1969 
    1970                 myImage = Bitmap.FromStream(ms);
    1971 
    1972                 ms.Close();
    1973 
    1974             }
    1975 
    1976             catch (System.Exception ex)
    1977 
    1978             {
    1979 
    1980                 Console.WriteLine("LoadImage error:" + ex.Message);
    1981 
    1982                 myImage = null;
    1983 
    1984             }
    1985 
    1986             return myImage;
    1987 
    1988         }
    1989 
    1990  
    1991 
    1992         /// <summary>
    1993 
    1994         /// 装载图像文件
    1995 
    1996         /// </summary>
    1997 
    1998         /// <param name="filename"></param>
    1999 
    2000         /// <returns></returns>
    2001 
    2002         public static Bitmap LoadBitImage(String filename)
    2003 
    2004         {
    2005 
    2006             Bitmap ret = (Bitmap)LoadImage(filename);
    2007 
    2008             return ret;
    2009 
    2010         }
    2011 
    2012  
    2013 
    2014         /// <summary>
    2015 
    2016         /// 保存图片到指定路径
    2017 
    2018         /// </summary>
    2019 
    2020         /// <param name="img"></param>
    2021 
    2022         /// <param name="filename"></param>
    2023 
    2024         /// <returns></returns>
    2025 
    2026         public static Boolean SaveImage(Image img, String filename)
    2027 
    2028         {
    2029 
    2030             FileProcessor.DeleteFile(filename);
    2031 
    2032             if (img == null)
    2033 
    2034             {
    2035 
    2036                 return false;
    2037 
    2038             }
    2039 
    2040             //获取保存图片的路径,如果路径不存在,新建
    2041 
    2042             String folder = FileProcessor.GetDirectoryName(filename);
    2043 
    2044             if (!FileProcessor.DirectoryExist(folder))
    2045 
    2046             {
    2047 
    2048                 FileProcessor.CreateDirectory(folder);
    2049 
    2050             }
    2051 
    2052             img.Save(filename);
    2053 
    2054             Boolean bl = FileProcessor.FileExist(filename);
    2055 
    2056             return bl;
    2057 
    2058         }
    2059 
    2060  
    2061 
    2062         #endregion
    2063 
    2064        
    2065 
    2066         #region 转换图片格式
    2067 
    2068        
    2069 
    2070         /// <summary>
    2071 
    2072         /// 转换图片格式
    2073 
    2074         /// </summary>
    2075 
    2076         /// <param name="bmpfilename"></param>
    2077 
    2078         /// <param name="jpgfilename"></param>
    2079 
    2080         /// <returns></returns>
    2081 
    2082         public static Boolean BmpToJpg(String bmpfilename, String jpgfilename)
    2083 
    2084         {
    2085 
    2086             Boolean bl = ChangeFileFormat(bmpfilename, jpgfilename, ePictureFileFormat.Jpeg);
    2087 
    2088             return bl;
    2089 
    2090         }
    2091 
    2092  
    2093 
    2094         /// <summary>
    2095 
    2096         /// 转换图片格式
    2097 
    2098         /// </summary>
    2099 
    2100         /// <param name="srcfilename"></param>
    2101 
    2102         /// <param name="destfilename"></param>
    2103 
    2104         /// <param name="destformat"></param>
    2105 
    2106         /// <returns></returns>
    2107 
    2108         public static Boolean ChangeFileFormat(String srcfilename, String destfilename, ePictureFileFormat destformat)
    2109 
    2110         {
    2111 
    2112             Boolean bl = FileProcessor.FileExist(srcfilename);
    2113 
    2114             if (!bl)
    2115 
    2116             {
    2117 
    2118                 return false;
    2119 
    2120             }
    2121 
    2122             Image image = Image.FromFile(srcfilename);
    2123 
    2124  
    2125 
    2126             ImageFormat IFMT = null;
    2127 
    2128             switch (destformat)
    2129 
    2130             {
    2131 
    2132                 case ePictureFileFormat.Bmp:
    2133 
    2134                     IFMT = ImageFormat.Bmp;
    2135 
    2136                     break;
    2137 
    2138                 case ePictureFileFormat.Gif:
    2139 
    2140                     IFMT = ImageFormat.Gif;
    2141 
    2142                     break;
    2143 
    2144                 case ePictureFileFormat.Icon:
    2145 
    2146                     IFMT = ImageFormat.Icon;
    2147 
    2148                     break;
    2149 
    2150                 case ePictureFileFormat.Jpeg:
    2151 
    2152                     IFMT = ImageFormat.Jpeg;
    2153 
    2154                     break;
    2155 
    2156                 case ePictureFileFormat.Png:
    2157 
    2158                     IFMT = ImageFormat.Png;
    2159 
    2160                     break;
    2161 
    2162                 default:
    2163 
    2164                     IFMT = ImageFormat.Jpeg;
    2165 
    2166                     break;
    2167 
    2168             }
    2169 
    2170             image.Save(destfilename, IFMT);
    2171 
    2172             image.Dispose();
    2173 
    2174  
    2175 
    2176             bl = FileProcessor.FileExist(destfilename);
    2177 
    2178             if (!bl)
    2179 
    2180             {
    2181 
    2182                 return false;
    2183 
    2184             }
    2185 
    2186  
    2187 
    2188             Int32 filelen = FileProcessor.GetFileLength(destfilename);
    2189 
    2190             return (filelen > 0);
    2191 
    2192         }
    2193 
    2194  
    2195 
    2196         /// <summary>
    2197 
    2198         /// 变成黑白图
    2199 
    2200         /// </summary>
    2201 
    2202         /// <param name="srcbitmap">原始图</param>
    2203 
    2204         /// <param name="mode">模式。0:加权平均  1:算数平均</param>
    2205 
    2206         /// <returns></returns>
    2207 
    2208         public static Bitmap ToGray(Bitmap bitmap, eGrayMode mode = eGrayMode.ArithmeticAverage)
    2209 
    2210         {
    2211 
    2212             if (bitmap == null)
    2213 
    2214             {
    2215 
    2216                 return null;
    2217 
    2218             }
    2219 
    2220  
    2221 
    2222             int width = bitmap.Width;
    2223 
    2224             int height = bitmap.Height;
    2225 
    2226             byte newColor = 0;
    2227 
    2228             try
    2229 
    2230             {
    2231 
    2232                 BitmapData srcData = bitmap.LockBits(new Rectangle(0, 0, width, height),
    2233 
    2234                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    2235 
    2236                 unsafe
    2237 
    2238                 {
    2239 
    2240                     byte* curpix = (byte*)srcData.Scan0.ToPointer();
    2241 
    2242                     if (mode == eGrayMode.ArithmeticAverage)// 算数平均
    2243 
    2244                     {
    2245 
    2246                         for (int y = 0; y < height; y++)
    2247 
    2248                         {
    2249 
    2250                             for (int x = 0; x < width; x++)
    2251 
    2252                             {
    2253 
    2254                                 newColor = (byte)((float)(curpix[0] + curpix[1] + curpix[2]) / 3.0f);
    2255 
    2256                                 curpix[0] = newColor;
    2257 
    2258                                 curpix[1] = newColor;
    2259 
    2260                                 curpix[2] = newColor;
    2261 
    2262                                 curpix += 3;
    2263 
    2264                             }
    2265 
    2266                             curpix += srcData.Stride - width * 3;
    2267 
    2268                         }
    2269 
    2270                     }
    2271 
    2272                     else
    2273 
    2274                     {
    2275 
    2276                         // 加权平均
    2277 
    2278                         for (int y = 0; y < height; y++)
    2279 
    2280                         {
    2281 
    2282                             for (int x = 0; x < width; x++)
    2283 
    2284                             {
    2285 
    2286                                 newColor = (byte)((float)curpix[0] * 0.114f + (float)curpix[1] * 0.587f + (float)curpix[2] * 0.299f);
    2287 
    2288                                 curpix[0] = newColor;
    2289 
    2290                                 curpix[1] = newColor;
    2291 
    2292                                 curpix[2] = newColor;
    2293 
    2294                                 curpix += 3;
    2295 
    2296                             }
    2297 
    2298                             curpix += srcData.Stride - width * 3;
    2299 
    2300                         }
    2301 
    2302                     }
    2303 
    2304                     bitmap.UnlockBits(srcData);
    2305 
    2306                 }
    2307 
    2308             }
    2309 
    2310             catch
    2311 
    2312             {
    2313 
    2314                 bitmap = null;
    2315 
    2316             }
    2317 
    2318  
    2319 
    2320             return bitmap;
    2321 
    2322         }
    2323 
    2324  
    2325 
    2326         /// <summary>
    2327 
    2328         /// 获取一幅图片对应的所有像素亮度数组
    2329 
    2330         /// </summary>
    2331 
    2332         /// <param name="bitmap">原始图</param>
    2333 
    2334         /// <param name="brightnessary">亮度值数组</param>
    2335 
    2336         /// <param name="mode">模式。0:加权平均  1:算数平均</param>
    2337 
    2338         /// <returns></returns>
    2339 
    2340         public static Boolean GetImageBrightness(Bitmap bitmap, ref Byte[] brightnessary,
    2341 
    2342             eGrayMode mode = eGrayMode.WeightedAverage)
    2343 
    2344         {
    2345 
    2346             if (bitmap == null)
    2347 
    2348             {
    2349 
    2350                 return false;
    2351 
    2352             }
    2353 
    2354  
    2355 
    2356             int width = bitmap.Width;
    2357 
    2358             int height = bitmap.Height;
    2359 
    2360             if (width < 1 || height < 1)
    2361 
    2362             {
    2363 
    2364                 return false;
    2365 
    2366             }
    2367 
    2368             
    2369 
    2370             brightnessary = new Byte[width * height];
    2371 
    2372             Boolean bl = false;
    2373 
    2374             Int32 rowredundancy = 0;//每一行像素,对应的数组长度 与 实际像素点数的差值
    2375 
    2376             Int32 pixidx = 0;//像素下标
    2377 
    2378             try
    2379 
    2380             {
    2381 
    2382                 BitmapData srcData = bitmap.LockBits(new Rectangle(0, 0, width, height),
    2383 
    2384                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    2385 
    2386                 rowredundancy = srcData.Stride - width * 3;//每行末尾还有这么多的冗余字节
    2387 
    2388  
    2389 
    2390                 unsafe
    2391 
    2392                 {
    2393 
    2394                     byte* curpix = (byte*)srcData.Scan0.ToPointer();
    2395 
    2396                     if (mode == eGrayMode.ArithmeticAverage)// 算数平均
    2397 
    2398                     {
    2399 
    2400                         for (int y = 0; y < height; y++)
    2401 
    2402                         {
    2403 
    2404                             for (int x = 0; x < width; x++)
    2405 
    2406                             {
    2407 
    2408                                 brightnessary[pixidx] = (byte)((float)(curpix[0] + curpix[1] + curpix[2]) / 3.0f);
    2409 
    2410                                 ++pixidx;
    2411 
    2412                                 curpix += 3;
    2413 
    2414                             }
    2415 
    2416                             curpix += rowredundancy;
    2417 
    2418                         }
    2419 
    2420                     }
    2421 
    2422                     else
    2423 
    2424                     {
    2425 
    2426                         // 加权平均
    2427 
    2428                         for (int y = 0; y < height; y++)
    2429 
    2430                         {
    2431 
    2432                             for (int x = 0; x < width; x++)
    2433 
    2434                             {
    2435 
    2436                                 brightnessary[pixidx] = (byte)((float)curpix[0] * 0.114f + (float)curpix[1] * 0.587f + (float)curpix[2] * 0.299f);
    2437 
    2438                                 ++pixidx;
    2439 
    2440                                 curpix += 3;
    2441 
    2442                             }
    2443 
    2444                             curpix += rowredundancy;
    2445 
    2446                         }
    2447 
    2448                     }
    2449 
    2450                     bitmap.UnlockBits(srcData);
    2451 
    2452                 }
    2453 
    2454                 bl = true;
    2455 
    2456             }
    2457 
    2458             catch(Exception ex)
    2459 
    2460             {
    2461 
    2462                 bl = false;
    2463 
    2464                 Console.WriteLine("Get brightness ary error:" + ex.Message);
    2465 
    2466             }
    2467 
    2468  
    2469 
    2470             return bl;
    2471 
    2472         }
    2473 
    2474  
    2475 
    2476         /// <summary>
    2477 
    2478         /// 变成黑白图,每个元素都是一个像素的亮度
    2479 
    2480         /// </summary>
    2481 
    2482         /// <param name=" bitmap ">原始图</param>
    2483 
    2484         /// <param name=" graybitmap ">黑白图</param>
    2485 
    2486         /// <param name=" brightnessbytes ">黑白所有像素点亮度</param>
    2487 
    2488         /// <param name="mode">模式。0:加权平均  1:算数平均</param>
    2489 
    2490         /// <returns></returns>
    2491 
    2492         public static Boolean ToGray(Bitmap bitmap, ref Bitmap graybitmap, ref Byte[] brightnessbytes,
    2493 
    2494             eGrayMode mode = eGrayMode.WeightedAverage)
    2495 
    2496         {
    2497 
    2498             if (bitmap == null)
    2499 
    2500             {
    2501 
    2502                 return false;
    2503 
    2504             }
    2505 
    2506  
    2507 
    2508             brightnessbytes = new Byte[bitmap.Width * bitmap.Height];
    2509 
    2510  
    2511 
    2512             int width = bitmap.Width;
    2513 
    2514             int height = bitmap.Height;
    2515 
    2516             //Clone 可能引发 GDI+异常
    2517 
    2518             graybitmap = new Bitmap(bitmap);
    2519 
    2520          
    2521 
    2522             byte newColor = 0;
    2523 
    2524             Int32 bytesidx = 0;
    2525 
    2526             Boolean bl = false;
    2527 
    2528             try
    2529 
    2530             {
    2531 
    2532                 BitmapData srcData = graybitmap.LockBits(new Rectangle(0, 0, width, height),
    2533 
    2534                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    2535 
    2536                 unsafe
    2537 
    2538                 {
    2539 
    2540                     byte* curpix = (byte*)srcData.Scan0.ToPointer();
    2541 
    2542                     if (mode == eGrayMode.ArithmeticAverage)// 算数平均
    2543 
    2544                     {
    2545 
    2546                         for (int y = 0; y < height; y++)
    2547 
    2548                         {
    2549 
    2550                             for (int x = 0; x < width; x++)
    2551 
    2552                             {
    2553 
    2554                                 newColor = (byte)((float)(curpix[0] + curpix[1] + curpix[2]) / 3.0f);
    2555 
    2556                                
    2557 
    2558                                 brightnessbytes[bytesidx] = newColor;
    2559 
    2560                                 ++bytesidx;
    2561 
    2562  
    2563 
    2564                                 curpix[0] = newColor;
    2565 
    2566                                 curpix[1] = newColor;
    2567 
    2568                                 curpix[2] = newColor;
    2569 
    2570                                 curpix += 3;
    2571 
    2572                             }
    2573 
    2574                             curpix += srcData.Stride - width * 3;
    2575 
    2576                         }
    2577 
    2578                     }
    2579 
    2580                     else
    2581 
    2582                     {
    2583 
    2584                         // 加权平均
    2585 
    2586                         for (int y = 0; y < height; y++)
    2587 
    2588                         {
    2589 
    2590                             for (int x = 0; x < width; x++)
    2591 
    2592                             {
    2593 
    2594                                 newColor = (byte)((float)curpix[0] * 0.114f + (float)curpix[1] * 0.587f + (float)curpix[2] * 0.299f);
    2595 
    2596  
    2597 
    2598                                 brightnessbytes[bytesidx] = newColor;
    2599 
    2600                                 ++bytesidx;
    2601 
    2602                                
    2603 
    2604                                 curpix[0] = newColor;
    2605 
    2606                                 curpix[1] = newColor;
    2607 
    2608                                 curpix[2] = newColor;
    2609 
    2610                                 curpix += 3;
    2611 
    2612                             }
    2613 
    2614                             curpix += srcData.Stride - width * 3;
    2615 
    2616                         }
    2617 
    2618                     }
    2619 
    2620                     graybitmap.UnlockBits(srcData);
    2621 
    2622                 }
    2623 
    2624  
    2625 
    2626                 bl = true;
    2627 
    2628             }
    2629 
    2630             catch(Exception ex)
    2631 
    2632             {
    2633 
    2634                 graybitmap = null;
    2635 
    2636                 Console.WriteLine("ToGray error:" + ex.Message);
    2637 
    2638                 bl = false;
    2639 
    2640             }
    2641 
    2642  
    2643 
    2644             return bl;
    2645 
    2646         }
    2647 
    2648  
    2649 
    2650        
    2651 
    2652         /// <summary>
    2653 
    2654         /// 把图片转换为非黑即白的二色图.
    2655 
    2656         /// </summary>
    2657 
    2658         /// <param name="bitmap">原始图</param>
    2659 
    2660         /// <param name="brightnessGate">亮度门限.超过此亮度认为白点,否则认为黑点</param>
    2661 
    2662         /// <param name="bitary">每个像素点是否为黑点的数组</param>
    2663 
    2664         /// <param name="trueAsblack">true-每个元素黑点为true,白点为false; false-每个元素白点为true,黑点为false</param>
    2665 
    2666         /// <returns></returns>
    2667 
    2668         public static Boolean ToBooleanArray(Bitmap bitmap, Byte brightnessGate, ref Boolean[] bitary, Boolean trueAsblack = true)
    2669 
    2670         {
    2671 
    2672             if (bitmap == null)
    2673 
    2674             {
    2675 
    2676                 return false;
    2677 
    2678             }
    2679 
    2680  
    2681 
    2682             bitary = new Boolean[bitmap.Width * bitmap.Height];
    2683 
    2684  
    2685 
    2686             int width = bitmap.Width;
    2687 
    2688             int height = bitmap.Height;
    2689 
    2690  
    2691 
    2692             byte curcolor = 0;
    2693 
    2694             Int32 pixidx = 0;
    2695 
    2696             Boolean bl = false;
    2697 
    2698             try
    2699 
    2700             {
    2701 
    2702                 BitmapData srcData = bitmap.LockBits(new Rectangle(0, 0, width, height),
    2703 
    2704                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    2705 
    2706                 unsafe
    2707 
    2708                 {
    2709 
    2710                     byte* curpix = (byte*)srcData.Scan0.ToPointer();
    2711 
    2712  
    2713 
    2714                     for (int y = 0; y < height; y++)
    2715 
    2716                     {
    2717 
    2718                         for (int x = 0; x < width; x++)
    2719 
    2720                         {
    2721 
    2722                             curcolor = (byte)((float)(curpix[0] + curpix[1] + curpix[2]) / 3.0f);
    2723 
    2724  
    2725 
    2726                             if (trueAsblack)//true为黑点
    2727 
    2728                             {
    2729 
    2730                                 bitary[pixidx] = (curcolor < brightnessGate);
    2731 
    2732                             }
    2733 
    2734                             else
    2735 
    2736                             {
    2737 
    2738                                 //true为白点
    2739 
    2740                                 bitary[pixidx] = (curcolor > brightnessGate);
    2741 
    2742                             }
    2743 
    2744                             ++pixidx;                            
    2745 
    2746                             curpix += 3;
    2747 
    2748                         }
    2749 
    2750                         curpix += srcData.Stride - width * 3;
    2751 
    2752                     }
    2753 
    2754                     bitmap.UnlockBits(srcData);
    2755 
    2756                 }
    2757 
    2758  
    2759 
    2760                 bl = true;
    2761 
    2762             }
    2763 
    2764             catch (Exception ex)
    2765 
    2766             {
    2767 
    2768                 Console.WriteLine("ToGray error:" + ex.Message);
    2769 
    2770                 bl = false;
    2771 
    2772             }
    2773 
    2774  
    2775 
    2776             return bl;
    2777 
    2778         }
    2779 
    2780  
    2781 
    2782         /// <summary>
    2783 
    2784         /// 亮度差数组变成bool数组.true表示亮度不同,false表示亮度相同
    2785 
    2786         /// </summary>
    2787 
    2788         /// <param name="bridiffary">亮度差数组</param>
    2789 
    2790         /// <param name="brightnessGate">亮度门限.超过此亮度认为白点,否则认为黑点</param>
    2791 
    2792         /// <returns></returns>
    2793 
    2794         public static Boolean BrightnessToBoolean(Byte[] bridiffary, Byte brightnessGate, ref Boolean[] boolary)
    2795 
    2796         {
    2797 
    2798             if (bridiffary == null || bridiffary.Length < 4)
    2799 
    2800             {
    2801 
    2802                 return false;
    2803 
    2804             }
    2805 
    2806  
    2807 
    2808             boolary = new Boolean[bridiffary.Length];
    2809 
    2810  
    2811 
    2812             for (Int32 idx = 0; idx < bridiffary.Length; ++idx)
    2813 
    2814             {
    2815 
    2816                 boolary[idx] = (bridiffary[idx] > brightnessGate);
    2817 
    2818             }
    2819 
    2820  
    2821 
    2822             return true;
    2823 
    2824         }
    2825 
    2826  
    2827 
    2828         #endregion
    2829 
    2830  
    2831 
    2832         #region 图片调整
    2833 
    2834        
    2835 
    2836         /// <summary>
    2837 
    2838         /// 调整亮度
    2839 
    2840         /// </summary>
    2841 
    2842         /// <param name="bitmap">原始图</param>
    2843 
    2844         /// <param name="degree">亮度,取值范围-255 - 255</param>
    2845 
    2846         /// <returns></returns>
    2847 
    2848         public static Bitmap SetBrightness(Bitmap srcbitmap, int brightnessOffset)
    2849 
    2850         {
    2851 
    2852             if (srcbitmap == null)
    2853 
    2854             {
    2855 
    2856                 return null;
    2857 
    2858             }
    2859 
    2860  
    2861 
    2862             CommonCompute.SetInt32Range(ref brightnessOffset, Const_MinBrightness, Const_MaxBrightness);
    2863 
    2864             int width = srcbitmap.Width;
    2865 
    2866             int height = srcbitmap.Height;
    2867 
    2868  
    2869 
    2870             Bitmap bitmap = (Bitmap)srcbitmap.Clone();
    2871 
    2872  
    2873 
    2874             try
    2875 
    2876             {
    2877 
    2878                 BitmapData data = bitmap.LockBits(new Rectangle(0, 0, width, height),
    2879 
    2880                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    2881 
    2882  
    2883 
    2884                 unsafe
    2885 
    2886                 {
    2887 
    2888                     byte* curpix = (byte*)data.Scan0.ToPointer();
    2889 
    2890                     Int32 curcolor = 0;
    2891 
    2892                     for (int y = 0; y < height; y++)
    2893 
    2894                     {
    2895 
    2896                         for (int x = 0; x < width; x++)
    2897 
    2898                         {
    2899 
    2900                             curcolor = curpix[0] + brightnessOffset;
    2901 
    2902                             CommonCompute.SetInt32Range(ref curcolor, 0, Const_MaxBrightness);
    2903 
    2904                             curpix[0] = (byte)curcolor;
    2905 
    2906  
    2907 
    2908                             curcolor = curpix[1] + brightnessOffset;
    2909 
    2910                             CommonCompute.SetInt32Range(ref curcolor, 0, Const_MaxBrightness);
    2911 
    2912                             curpix[1] = (byte)curcolor;
    2913 
    2914  
    2915 
    2916                             curcolor = curpix[2] + brightnessOffset;
    2917 
    2918                             CommonCompute.SetInt32Range(ref curcolor, 0, Const_MaxBrightness);
    2919 
    2920                             curpix[2] = (byte)curcolor;
    2921 
    2922  
    2923 
    2924                             curpix += 3;
    2925 
    2926                         }
    2927 
    2928                         curpix += data.Stride - width * 3;
    2929 
    2930                     }
    2931 
    2932                 }
    2933 
    2934  
    2935 
    2936                 bitmap.UnlockBits(data);
    2937 
    2938             }
    2939 
    2940             catch
    2941 
    2942             {
    2943 
    2944                 bitmap = null;
    2945 
    2946             }
    2947 
    2948  
    2949 
    2950             return bitmap;
    2951 
    2952         }
    2953 
    2954  
    2955 
    2956         /// <summary>
    2957 
    2958         /// 调整图像对比度
    2959 
    2960         /// </summary>
    2961 
    2962         /// <param name="bitmap">原始图</param>
    2963 
    2964         /// <param name="degree">对比度 0 - 100</param>
    2965 
    2966         /// <returns></returns>
    2967 
    2968         public static Bitmap SetContrast(Bitmap srcbitmap, int contrast)
    2969 
    2970         {
    2971 
    2972             if (srcbitmap == null)
    2973 
    2974             {
    2975 
    2976                 return null;
    2977 
    2978             }
    2979 
    2980  
    2981 
    2982             //对比度取值范围,0-100
    2983 
    2984             CommonCompute.SetInt32Range(ref contrast, 0, 100);
    2985 
    2986  
    2987 
    2988             Int32 curcolor = 0;
    2989 
    2990             Bitmap bitmap = (Bitmap)srcbitmap.Clone();
    2991 
    2992             int width = bitmap.Width;
    2993 
    2994             int height = bitmap.Height;
    2995 
    2996  
    2997 
    2998             //调整对比度基本思路:0时,所有像素点的亮度都设置为中间值128
    2999 
    3000             //100 时,把亮度大于128的像素,亮度设置为255;小于128的设置为0
    3001 
    3002             //即:50时,保持不变;小于50,所有点的亮度向中间值128偏移;大于50,所有点亮度值向两端偏移
    3003 
    3004  
    3005 
    3006             //如果当前像素点的亮度是130, 对比度为50时,结果仍然要是130,此时rate为1.0
    3007 
    3008             //对比度为100时,结果要变成255,此时rate >= 128
    3009 
    3010             //对比度为0时,结果要变成128,此时rate = 0
    3011 
    3012             //因此可知对比度与rate的对应关系
    3013 
    3014             //对比度:  0  50  100
    3015 
    3016             //rate  :  0  1   127              
    3017 
    3018             double rate = 0;
    3019 
    3020             if (contrast == 50)
    3021 
    3022             {
    3023 
    3024                 rate = 1;
    3025 
    3026             }
    3027 
    3028             else if (contrast < 50)
    3029 
    3030             {
    3031 
    3032                 rate = contrast / 50.0;//小于50的,对比度比率必须是纯小数,0-1 之间
    3033 
    3034             }
    3035 
    3036             else
    3037 
    3038             {
    3039 
    3040                 rate = 1 + Const_MiddleBrightness * ((contrast - 50.0) / 50.0);//大于50的,比率必须是1到128之间的值
    3041 
    3042             }
    3043 
    3044  
    3045 
    3046             try
    3047 
    3048             {
    3049 
    3050  
    3051 
    3052                 BitmapData data = bitmap.LockBits(new Rectangle(0, 0, width, height),
    3053 
    3054                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    3055 
    3056                 unsafe
    3057 
    3058                 {
    3059 
    3060                     byte* curpix = (byte*)data.Scan0.ToPointer();
    3061 
    3062  
    3063 
    3064                     for (int y = 0; y < height; y++)
    3065 
    3066                     {
    3067 
    3068                         for (int x = 0; x < width; x++)
    3069 
    3070                         {
    3071 
    3072                             for (int i = 0; i < 3; i++) //R,G,B 3个通道
    3073 
    3074                             {
    3075 
    3076                                 //对于 刚好亮度等于中间值的点,需要把亮度调高或调低1
    3077 
    3078                                 //否则将无法实现对该点 提高对比度
    3079 
    3080                                 if (curpix[i] == Const_MiddleBrightness)
    3081 
    3082                                 {
    3083 
    3084                                     curpix[i] = (byte)(curpix[i] + 1);
    3085 
    3086                                 }
    3087 
    3088  
    3089 
    3090                                 //调整该像素对比度
    3091 
    3092                                 curcolor = (Int32)(Const_MiddleBrightness + (curpix[i] - Const_MiddleBrightness) * rate);
    3093 
    3094                                 CommonCompute.SetInt32Range(ref curcolor, Const_MinBrightness, Const_MaxBrightness);
    3095 
    3096                                 curpix[i] = (byte)curcolor;
    3097 
    3098                                 ++curpix;
    3099 
    3100                             }
    3101 
    3102                         }
    3103 
    3104  
    3105 
    3106                         curpix += data.Stride - width * 3;
    3107 
    3108                     }
    3109 
    3110                 }
    3111 
    3112                 bitmap.UnlockBits(data);
    3113 
    3114             }
    3115 
    3116             catch
    3117 
    3118             {
    3119 
    3120                 bitmap = null;
    3121 
    3122             }
    3123 
    3124  
    3125 
    3126             return bitmap;
    3127 
    3128         }
    3129 
    3130  
    3131 
    3132         /// <summary>
    3133 
    3134         /// 任意角度旋转
    3135 
    3136         /// </summary>
    3137 
    3138         /// <param name="srcbitmap">原始图Bitmap</param>
    3139 
    3140         /// <param name="angle">旋转角度</param>
    3141 
    3142         /// <param name="bkColor">背景色</param>
    3143 
    3144         /// <returns>输出Bitmap</returns>
    3145 
    3146         public static Bitmap Rotate(Bitmap srcbitmap, float angle, Color bkColor)
    3147 
    3148         {
    3149 
    3150             int w = srcbitmap.Width + 2;
    3151 
    3152             int h = srcbitmap.Height + 2;
    3153 
    3154  
    3155 
    3156             PixelFormat pf;
    3157 
    3158  
    3159 
    3160             if (bkColor == Color.Transparent)
    3161 
    3162             {
    3163 
    3164                 pf = PixelFormat.Format32bppArgb;
    3165 
    3166             }
    3167 
    3168             else
    3169 
    3170             {
    3171 
    3172                 pf = srcbitmap.PixelFormat;
    3173 
    3174             }
    3175 
    3176  
    3177 
    3178             Bitmap tmp = new Bitmap(w, h, pf);
    3179 
    3180             Graphics g = Graphics.FromImage(tmp);
    3181 
    3182             g.Clear(bkColor);
    3183 
    3184             g.DrawImageUnscaled(srcbitmap, 1, 1);
    3185 
    3186             g.Dispose();
    3187 
    3188  
    3189 
    3190             GraphicsPath path = new GraphicsPath();
    3191 
    3192             path.AddRectangle(new RectangleF(0f, 0f, w, h));
    3193 
    3194             Matrix mtrx = new Matrix();
    3195 
    3196             mtrx.Rotate(angle);
    3197 
    3198             RectangleF rct = path.GetBounds(mtrx);
    3199 
    3200  
    3201 
    3202             Bitmap dst = new Bitmap((int)rct.Width, (int)rct.Height, pf);
    3203 
    3204             g = Graphics.FromImage(dst);
    3205 
    3206             g.Clear(bkColor);
    3207 
    3208             g.TranslateTransform(-rct.X, -rct.Y);
    3209 
    3210             g.RotateTransform(angle);
    3211 
    3212             g.InterpolationMode = InterpolationMode.HighQualityBilinear;
    3213 
    3214             g.DrawImageUnscaled(tmp, 0, 0);
    3215 
    3216             g.Dispose();
    3217 
    3218  
    3219 
    3220             tmp.Dispose();
    3221 
    3222  
    3223 
    3224             return dst;
    3225 
    3226         }
    3227 
    3228  
    3229 
    3230         /// <summary>
    3231 
    3232         /// Gamma校正
    3233 
    3234         /// </summary>
    3235 
    3236         /// <param name="srcbitmap">输入Bitmap</param>
    3237 
    3238         /// <param name="val">[0 <-明- 1 -暗-> 2]</param>
    3239 
    3240         /// <returns>输出Bitmap</returns>
    3241 
    3242         public static Bitmap SetGamma(Bitmap srcbitmap, float val)
    3243 
    3244         {
    3245 
    3246             if (srcbitmap == null)
    3247 
    3248             {
    3249 
    3250                 return null;
    3251 
    3252             }
    3253 
    3254  
    3255 
    3256             // 1表示无变化,就不做
    3257 
    3258             if (val == 1.0000f) return srcbitmap;
    3259 
    3260  
    3261 
    3262             try
    3263 
    3264             {
    3265 
    3266                 Bitmap b = new Bitmap(srcbitmap.Width, srcbitmap.Height);
    3267 
    3268                 Graphics g = Graphics.FromImage(b);
    3269 
    3270                 ImageAttributes attr = new ImageAttributes();
    3271 
    3272  
    3273 
    3274                 attr.SetGamma(val, ColorAdjustType.Bitmap);
    3275 
    3276                 g.DrawImage(srcbitmap, new Rectangle(0, 0, srcbitmap.Width, srcbitmap.Height), 0, 0, srcbitmap.Width, srcbitmap.Height, GraphicsUnit.Pixel, attr);
    3277 
    3278                 g.Dispose();
    3279 
    3280                 return b;
    3281 
    3282             }
    3283 
    3284             catch
    3285 
    3286             {
    3287 
    3288                 return null;
    3289 
    3290             }
    3291 
    3292         }
    3293 
    3294  
    3295 
    3296         /// <summary>         
    3297 
    3298         /// 重新设置图片尺寸     
    3299 
    3300         /// </summary> 
    3301 
    3302         /// <param name="srcbitmap">original Bitmap</param>         
    3303 
    3304         /// <param name="newW">new width</param>         
    3305 
    3306         /// <param name="newH">new height</param>         
    3307 
    3308         /// <returns>worked bitmap</returns> 
    3309 
    3310         public static Boolean ResizeImage(Bitmap srcimg, int newW, int newH, ref Bitmap destimage)
    3311 
    3312         {
    3313 
    3314             if (srcimg == null)
    3315 
    3316             {
    3317 
    3318                 return false;
    3319 
    3320             }
    3321 
    3322  
    3323 
    3324             destimage = new Bitmap(newW, newH);
    3325 
    3326             Graphics graph = Graphics.FromImage(destimage);
    3327 
    3328             Boolean bl = true;
    3329 
    3330             try
    3331 
    3332             {
    3333 
    3334                 graph.InterpolationMode = InterpolationMode.HighQualityBicubic;
    3335 
    3336                 graph.DrawImage(srcimg, new Rectangle(0, 0, newW, newH),
    3337 
    3338                     new Rectangle(0, 0, srcimg.Width, srcimg.Height),
    3339 
    3340                     GraphicsUnit.Pixel);
    3341 
    3342  
    3343 
    3344                 graph.Dispose();
    3345 
    3346             }
    3347 
    3348             catch (Exception ex)
    3349 
    3350             {
    3351 
    3352                 Console.WriteLine("ResizeImage error" + ex.Message);
    3353 
    3354                 bl = false;
    3355 
    3356             }
    3357 
    3358             return bl;
    3359 
    3360         }
    3361 
    3362  
    3363 
    3364  
    3365 
    3366         /// <summary>
    3367 
    3368         /// 去除噪点
    3369 
    3370         /// </summary>
    3371 
    3372         /// <param name="noisypointsize">噪点的尺寸</param>
    3373 
    3374         /// <param name="bitmap">待处理的图片信息</param>
    3375 
    3376         /// <returns></returns>
    3377 
    3378         public static Boolean RemoveNoisypoint(Int32 noisypointsize, ref Bitmap bitmap)
    3379 
    3380         {
    3381 
    3382             if (bitmap == null || noisypointsize < 1 ||
    3383 
    3384                 noisypointsize * 2 >= bitmap.Width || noisypointsize * 2 >= bitmap.Height)
    3385 
    3386             {
    3387 
    3388                 return false;
    3389 
    3390             }
    3391 
    3392  
    3393 
    3394             // 创建过滤器
    3395 
    3396             BlobsFiltering blobfilter =
    3397 
    3398                 new BlobsFiltering();
    3399 
    3400             // 设置过滤条件(对象长、宽至少为70)
    3401 
    3402             blobfilter.CoupledSizeFiltering = true;
    3403 
    3404             blobfilter.MinWidth = noisypointsize;
    3405 
    3406             blobfilter.MinHeight = noisypointsize;
    3407 
    3408             blobfilter.ApplyInPlace(bitmap);
    3409 
    3410  
    3411 
    3412             return true;
    3413 
    3414         }
    3415 
    3416  
    3417 
    3418         /// <summary>
    3419 
    3420         /// 把图片里指定区域的内容复制到另一个图片里
    3421 
    3422         /// </summary>
    3423 
    3424         /// <param name="srcimg"></param>
    3425 
    3426         /// <param name="x"></param>
    3427 
    3428         /// <param name="y"></param>
    3429 
    3430         /// <param name="width"></param>
    3431 
    3432         /// <param name="height"></param>
    3433 
    3434         /// <param name="destimg"></param>
    3435 
    3436         /// <returns></returns>
    3437 
    3438         public static Boolean CutImage(Bitmap srcimg, Int32 x, Int32 y, Int32 width, Int32 height, ref Bitmap destimg)
    3439 
    3440         {
    3441 
    3442             if (srcimg == null || x < 0 || y < 0 || width < 1 || height < 1 ||
    3443 
    3444                 x + width > srcimg.Width || y + height > srcimg.Height)
    3445 
    3446             {
    3447 
    3448                 return false;
    3449 
    3450             }
    3451 
    3452  
    3453 
    3454             destimg = new Bitmap(width, height, PixelFormat.Format32bppArgb);
    3455 
    3456             Graphics graph = Graphics.FromImage(destimg);
    3457 
    3458             graph.InterpolationMode = InterpolationMode.HighQualityBicubic;
    3459 
    3460             graph.DrawImage(srcimg, new Rectangle(0, 0, width, height),
    3461 
    3462                     new Rectangle(x, y, width, height), GraphicsUnit.Pixel);
    3463 
    3464             graph.Dispose();
    3465 
    3466             return true;
    3467 
    3468         }
    3469 
    3470  
    3471 
    3472         #endregion
    3473 
    3474  
    3475 
    3476         #region 亮度处理
    3477 
    3478  
    3479 
    3480  
    3481 
    3482  
    3483 
    3484         /// <summary>
    3485 
    3486         /// 获取指定坐标处的亮度值
    3487 
    3488         /// </summary>
    3489 
    3490         /// <param name="bitmap"></param>
    3491 
    3492         /// <param name="x"></param>
    3493 
    3494         /// <param name="y"></param>
    3495 
    3496         /// <returns></returns>
    3497 
    3498         public static Boolean GetPixBrightness(Bitmap bitmap, Int32 x, Int32 y, eGrayMode mode, ref Byte brightness)
    3499 
    3500         {
    3501 
    3502             if (bitmap == null)
    3503 
    3504             {
    3505 
    3506                 return false;
    3507 
    3508             }
    3509 
    3510  
    3511 
    3512             if (x < 0 || x >= bitmap.Width ||
    3513 
    3514                 y < 0 || y >= bitmap.Height)
    3515 
    3516             {
    3517 
    3518                 return false;
    3519 
    3520             }
    3521 
    3522  
    3523 
    3524             Color curColor = bitmap.GetPixel(x, y);
    3525 
    3526             //利用公式计算灰度值(加权平均法)
    3527 
    3528             if (mode == eGrayMode.ArithmeticAverage)
    3529 
    3530             {
    3531 
    3532                 brightness = (Byte)(curColor.R * 0.299f + curColor.G * 0.587f + curColor.B * 0.114f);
    3533 
    3534             }
    3535 
    3536             else
    3537 
    3538             {
    3539 
    3540                 brightness = (Byte)((curColor.R + curColor.G + curColor.B) / 3.0f);
    3541 
    3542             }
    3543 
    3544             return true;
    3545 
    3546         }
    3547 
    3548  
    3549 
    3550         /// <summary>
    3551 
    3552         /// 获取指定坐标处的亮度值
    3553 
    3554         /// </summary>
    3555 
    3556         /// <param name="bitmap"></param>
    3557 
    3558         /// <param name="x"></param>
    3559 
    3560         /// <param name="y"></param>
    3561 
    3562         /// <returns></returns>
    3563 
    3564         public static Boolean GetPixBrightness(Byte[] bribytes, Int32 width,Int32 height,
    3565 
    3566             Int32 x, Int32 y, ref Byte brightness)
    3567 
    3568         {
    3569 
    3570             if (bribytes == null || width < 1 || height < 1 ||
    3571 
    3572                 x < 0 || x >= width ||
    3573 
    3574                 y < 0 || y >= height ||
    3575 
    3576                 bribytes.Length != width * height)
    3577 
    3578             {
    3579 
    3580                 return false;
    3581 
    3582             }
    3583 
    3584  
    3585 
    3586             brightness = bribytes[y * width + x];
    3587 
    3588           
    3589 
    3590             return true;
    3591 
    3592         }
    3593 
    3594        
    3595 
    3596         /// <summary>
    3597 
    3598         /// 获取指定坐标处的亮度值
    3599 
    3600         /// </summary>
    3601 
    3602         /// <param name="bitmap"></param>
    3603 
    3604         /// <param name="x"></param>
    3605 
    3606         /// <param name="y"></param>
    3607 
    3608         /// <returns></returns>
    3609 
    3610         public static Boolean GetPixBrightnessByRate(Byte[] bribytes, Int32 width, Int32 height,
    3611 
    3612             double  xRate, double yRate, ref Byte brightness)
    3613 
    3614         {
    3615 
    3616             int x = (int)(width * xRate);
    3617 
    3618             int y =  (int)(height * yRate);
    3619 
    3620  
    3621 
    3622             if (bribytes == null || width < 1 || height < 1 ||
    3623 
    3624                 x < 0 || x >= width ||
    3625 
    3626                 y < 0 || y >= height ||
    3627 
    3628                 bribytes.Length != width * height)
    3629 
    3630             {
    3631 
    3632                 return false;
    3633 
    3634             }
    3635 
    3636  
    3637 
    3638             brightness = bribytes[y * width + x];
    3639 
    3640             return true;
    3641 
    3642         }
    3643 
    3644  
    3645 
    3646         /// <summary>
    3647 
    3648         /// 获取指定坐标处的颜色
    3649 
    3650         /// </summary>
    3651 
    3652         /// <param name="bitmap"></param>
    3653 
    3654         /// <param name="x"></param>
    3655 
    3656         /// <param name="y"></param>
    3657 
    3658         /// <returns></returns>
    3659 
    3660         public static Boolean GetPixColor(Bitmap bitmap, Int32 x, Int32 y, ref Color curColor)
    3661 
    3662         {
    3663 
    3664             if (bitmap == null)
    3665 
    3666             {
    3667 
    3668                 return false;
    3669 
    3670             }
    3671 
    3672  
    3673 
    3674             if (x < 0 || x >= bitmap.Width ||
    3675 
    3676                 y < 0 || y >= bitmap.Height)
    3677 
    3678             {
    3679 
    3680                 return false;
    3681 
    3682             }
    3683 
    3684  
    3685 
    3686             curColor = bitmap.GetPixel(x, y);
    3687 
    3688             return true;
    3689 
    3690         }
    3691 
    3692        
    3693 
    3694         /// <summary>
    3695 
    3696         /// 获取指定坐标处的颜色
    3697 
    3698         /// </summary>
    3699 
    3700         /// <param name="bitmap"></param>
    3701 
    3702         /// <param name="x"></param>
    3703 
    3704         /// <param name="y"></param>
    3705 
    3706         /// <returns></returns>
    3707 
    3708         public static Boolean GetPixColorByRate(Bitmap bitmap, double xRate, double yRate, ref Color curColor)
    3709 
    3710         {
    3711 
    3712             if (bitmap == null)
    3713 
    3714             {
    3715 
    3716                 return false;
    3717 
    3718             }
    3719 
    3720  
    3721 
    3722             int width = bitmap.Width;
    3723 
    3724             int height = bitmap.Height;
    3725 
    3726             int X = (int)(width * xRate);
    3727 
    3728             int Y = (int)(height * yRate);
    3729 
    3730  
    3731 
    3732             Boolean bl = GetPixColor(bitmap, X, Y, ref curColor);
    3733 
    3734             return bl;
    3735 
    3736         }
    3737 
    3738  
    3739 
    3740         /// <summary>
    3741 
    3742         /// 把颜色转换为亮度值
    3743 
    3744         /// </summary>
    3745 
    3746         /// <param name="bitmap"></param>
    3747 
    3748         /// <param name="x"></param>
    3749 
    3750         /// <param name="y"></param>
    3751 
    3752         /// <returns></returns>
    3753 
    3754         public static Boolean GetBrightnessByColor(Color curColor, eGrayMode mode, ref Byte brightness)
    3755 
    3756         {
    3757 
    3758             if (curColor == null)
    3759 
    3760             {
    3761 
    3762                 return false;
    3763 
    3764             }
    3765 
    3766              
    3767 
    3768             //利用公式计算灰度值(加权平均法)
    3769 
    3770             if (mode == eGrayMode.ArithmeticAverage)
    3771 
    3772             {
    3773 
    3774                 brightness = (Byte)(curColor.R * 0.299f + curColor.G * 0.587f + curColor.B * 0.114f);
    3775 
    3776             }
    3777 
    3778             else
    3779 
    3780             {
    3781 
    3782                 brightness = (Byte)((curColor.R + curColor.G + curColor.B) / 3.0f);
    3783 
    3784             }
    3785 
    3786             return true;
    3787 
    3788         }
    3789 
    3790  
    3791 
    3792         #endregion
    3793 
    3794  
    3795 
    3796         #region 图片比较
    3797 
    3798  
    3799 
    3800         /// <summary>
    3801 
    3802         /// 根据2个图片的亮度值,比较图片的差异部分
    3803 
    3804         /// </summary>
    3805 
    3806         /// <param name="brightnessDiff"></param>
    3807 
    3808         /// <param name="compareret"></param>
    3809 
    3810         /// <returns></returns>
    3811 
    3812         public static Boolean CompareImageBrightness(Byte brightnessDiff,
    3813 
    3814             Byte[] brightness1, Byte[] brightness2,
    3815 
    3816             ref Boolean[] diffPixArray)
    3817 
    3818         {
    3819 
    3820  
    3821 
    3822             if (brightness1 == null || brightness2 == null ||
    3823 
    3824                 brightness1.Length < 1 || brightness2.Length < 1 ||
    3825 
    3826                 brightness1.Length != brightness2.Length)
    3827 
    3828             {
    3829 
    3830                 return false;
    3831 
    3832             }
    3833 
    3834  
    3835 
    3836             Int32 arylen = brightness1.Length;
    3837 
    3838             diffPixArray = new Boolean[brightness1.Length];
    3839 
    3840             Byte bri1 = 0;
    3841 
    3842             Byte bri2 = 0;
    3843 
    3844  
    3845 
    3846             for (Int32 byteidx = 0; byteidx < arylen; ++byteidx)
    3847 
    3848             {
    3849 
    3850                 bri1 = brightness1[byteidx];
    3851 
    3852                 bri2 = brightness2[byteidx];
    3853 
    3854  
    3855 
    3856                 //亮度差超过指定范围
    3857 
    3858                 if (bri1 >= bri2 + brightnessDiff ||
    3859 
    3860                      bri2 >= bri1 + brightnessDiff)
    3861 
    3862                 {
    3863 
    3864                     diffPixArray[byteidx] = true;
    3865 
    3866                 }
    3867 
    3868             }
    3869 
    3870  
    3871 
    3872             return true;
    3873 
    3874         }
    3875 
    3876  
    3877 
    3878         /// <summary>
    3879 
    3880         /// 把2个图片的尺寸设置为一样大
    3881 
    3882         /// </summary>
    3883 
    3884         /// <param name="image1"></param>
    3885 
    3886         /// <param name="image2"></param>
    3887 
    3888         /// <returns></returns>
    3889 
    3890         public static Boolean ResizeImageToSame(ref Bitmap image1, ref Bitmap image2)
    3891 
    3892         {
    3893 
    3894             if (image1 == null || image2 == null ||
    3895 
    3896                 image1.Width == 0 || image1.Height == 0 ||
    3897 
    3898                 image2.Width == 0 || image2.Height == 0)
    3899 
    3900             {
    3901 
    3902                 return false;
    3903 
    3904             }
    3905 
    3906  
    3907 
    3908             //如果2个图片尺寸不一样,把大的尺寸压缩小了再比较
    3909 
    3910             Boolean bl = false;
    3911 
    3912             Bitmap tmpimg = null;
    3913 
    3914             if (image1.Width > image2.Width && image1.Height < image2.Height)
    3915 
    3916             {
    3917 
    3918                 return false;
    3919 
    3920             }
    3921 
    3922             if (image1.Width < image2.Width && image1.Height > image2.Height)
    3923 
    3924             {
    3925 
    3926                 return false;
    3927 
    3928             }
    3929 
    3930  
    3931 
    3932             //image1 比较大,把image2放大到 与1一样大
    3933 
    3934             if (image1.Width > image2.Width && image1.Height > image2.Height)
    3935 
    3936             {
    3937 
    3938                 bl = ResizeImage(image2, image1.Width, image1.Height, ref tmpimg);
    3939 
    3940                 image2 = tmpimg;
    3941 
    3942             }
    3943 
    3944            
    3945 
    3946             //image 2比较大,把image1放大到 与2一样大
    3947 
    3948             if (image1.Width < image2.Width && image1.Height < image2.Height)
    3949 
    3950             {
    3951 
    3952                 bl = ResizeImage(image1, image2.Width, image2.Height, ref tmpimg);
    3953 
    3954                 image1 = tmpimg;
    3955 
    3956             }
    3957 
    3958  
    3959 
    3960             return true;
    3961 
    3962         }
    3963 
    3964         
    3965 
    3966         /// <summary>
    3967 
    3968         /// 根据2个图片的像素颜色值,比较图片的差异部分
    3969 
    3970         /// </summary>
    3971 
    3972         /// <param name="compareparam"></param>
    3973 
    3974         /// <param name="compareret"></param>
    3975 
    3976         /// <returns></returns>
    3977 
    3978         public static Boolean CompareImage(ImageCompareParameter compareparam,
    3979 
    3980             ref ImageCompareResult compareret)
    3981 
    3982         {
    3983 
    3984             Bitmap image1 = compareparam.Image1;
    3985 
    3986             Bitmap image2 = compareparam.Image2;
    3987 
    3988  
    3989 
    3990             Int32 briDiff = compareparam.BrightnessDiff;
    3991 
    3992             Color diffColor = compareparam.DifferentAreaFillColor;
    3993 
    3994             Color samecolor = compareparam.SameAreaFillColor;
    3995 
    3996             //是否需要填充相同或不同部分的像素的颜色
    3997 
    3998             Boolean filldiffcolor = (diffColor != Color.Transparent);
    3999 
    4000             Boolean fillsamecolor = (samecolor != Color.Transparent);
    4001 
    4002  
    4003 
    4004             //如果图片尺寸不一样,修改为一样大
    4005 
    4006             Boolean bl = ResizeImageToSame(ref image1, ref image2);
    4007 
    4008             if (!bl)
    4009 
    4010             {
    4011 
    4012                 return false;
    4013 
    4014             }
    4015 
    4016  
    4017 
    4018             Bitmap imagediff = (Bitmap)image1.Clone();
    4019 
    4020  
    4021 
    4022             //不同区域的左上下右位置
    4023 
    4024             Int32 areaLeft = imagediff.Width;
    4025 
    4026             Int32 areaTop = imagediff.Height;
    4027 
    4028             Int32 areaRight = -1;
    4029 
    4030             Int32 areaBottom = -1;
    4031 
    4032  
    4033 
    4034             int width = image1.Width;
    4035 
    4036             int height = image1.Height;
    4037 
    4038  
    4039 
    4040             long allpixcnt = height * width;//所有像素点数量
    4041 
    4042             long diffpixcnt = 0;//不同像素点数量
    4043 
    4044             long samepixcnt = 0;//相同像素点数量
    4045 
    4046  
    4047 
    4048             //3张图片的各像素亮度数组
    4049 
    4050             Int32 briaryidx = 0;
    4051 
    4052             Byte[] briary1 = new Byte[allpixcnt];
    4053 
    4054             Byte[] briary2 = new Byte[allpixcnt];
    4055 
    4056             Byte[] briaryret = new Byte[allpixcnt];
    4057 
    4058  
    4059 
    4060             Byte diffB = diffColor.B;
    4061 
    4062             Byte diffG = diffColor.G;
    4063 
    4064             Byte diffR = diffColor.R;
    4065 
    4066             Byte sameB = samecolor.B;
    4067 
    4068             Byte sameG = samecolor.G;
    4069 
    4070             Byte sameR = samecolor.R;
    4071 
    4072  
    4073 
    4074             Byte samebri = 0;
    4075 
    4076             Byte diffbri = 0;
    4077 
    4078             GetBrightnessByColor(diffColor, eGrayMode.WeightedAverage, ref samebri);
    4079 
    4080             GetBrightnessByColor(diffColor, eGrayMode.WeightedAverage, ref diffbri);
    4081 
    4082  
    4083 
    4084             try
    4085 
    4086             {
    4087 
    4088  
    4089 
    4090                 BitmapData data1 = image1.LockBits(new Rectangle(0, 0, width, height),
    4091 
    4092                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    4093 
    4094  
    4095 
    4096                 BitmapData data2 = image2.LockBits(new Rectangle(0, 0, width, height),
    4097 
    4098                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    4099 
    4100  
    4101 
    4102                 BitmapData datadiff = imagediff.LockBits(new Rectangle(0, 0, width, height),
    4103 
    4104                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    4105 
    4106  
    4107 
    4108                 byte bri1 = 0;
    4109 
    4110                 byte bri2 = 0;
    4111 
    4112  
    4113 
    4114                 //每个像素是否相同.1相同,0不同
    4115 
    4116                 compareret.PixIsDifferent = new Boolean[width * height];
    4117 
    4118  
    4119 
    4120                 //当前像素是否不同
    4121 
    4122                 Boolean curpixIsdiff = false;
    4123 
    4124                 unsafe
    4125 
    4126                 {
    4127 
    4128                     byte* curpix1 = (byte*)data1.Scan0.ToPointer();
    4129 
    4130                     byte* curpix2 = (byte*)data2.Scan0.ToPointer();
    4131 
    4132                     byte* curpixdiff = (byte*)datadiff.Scan0.ToPointer();
    4133 
    4134  
    4135 
    4136                     for (int y = 0; y < height; y++)
    4137 
    4138                     {
    4139 
    4140                         for (int x = 0; x < width; x++)
    4141 
    4142                         {
    4143 
    4144                             //利用公式计算灰度值(加权平均法)
    4145 
    4146                             //按BGR的顺序存储
    4147 
    4148                             bri1 = (Byte)(curpix1[0] * 0.114f + curpix1[1] * 0.587f + curpix1[2] * 0.299f);
    4149 
    4150                             bri2 = (Byte)(curpix2[0] * 0.114f + curpix2[1] * 0.587f + curpix2[2] * 0.299f);
    4151 
    4152  
    4153 
    4154                             //以1作为基准,比较1和2之间的差距,如果超过阀值,认为当前像素有差异
    4155 
    4156                             //否则认为当前像素没有差异
    4157 
    4158                             curpixIsdiff = false;
    4159 
    4160                             if (bri1 >= bri2 + briDiff ||
    4161 
    4162                                 bri2 >= bri1 + briDiff)
    4163 
    4164                             {
    4165 
    4166                                 curpixIsdiff = true;
    4167 
    4168                             }
    4169 
    4170  
    4171 
    4172                             briary1[briaryidx] = bri1;
    4173 
    4174                             briary2[briaryidx] = bri2;
    4175 
    4176  
    4177 
    4178                             if (curpixIsdiff) //如果有差异,设置图像1里的当前像素为 不同颜色
    4179 
    4180                             {
    4181 
    4182                                 if (filldiffcolor)
    4183 
    4184                                 {
    4185 
    4186                                     curpixdiff[0] = diffB;
    4187 
    4188                                     curpixdiff[1] = diffG;
    4189 
    4190                                     curpixdiff[2] = diffR;
    4191 
    4192                                 }
    4193 
    4194                                 ++diffpixcnt;
    4195 
    4196  
    4197 
    4198                                 if (x < areaLeft) //记忆最左边的像素位置
    4199 
    4200                                 {
    4201 
    4202                                     areaLeft = x;
    4203 
    4204                                 }
    4205 
    4206                                 if (x > areaRight) //记忆最右边的像素位置
    4207 
    4208                                 {
    4209 
    4210                                     areaRight = x;
    4211 
    4212                                 }
    4213 
    4214                                 if (y < areaTop) //记忆最上边的像素位置
    4215 
    4216                                 {
    4217 
    4218                                     areaTop = y;
    4219 
    4220                                 }
    4221 
    4222                                 if (y > areaBottom) //记忆最下边的像素位置
    4223 
    4224                                 {
    4225 
    4226                                     areaBottom = y;
    4227 
    4228                                 }
    4229 
    4230  
    4231 
    4232                                 //记忆当前像素的比较结果的亮度
    4233 
    4234                                 briaryret[briaryidx] = diffbri;
    4235 
    4236                             }
    4237 
    4238                             else //没有差异,设置结果里的当前像素为 相同颜色
    4239 
    4240                             {
    4241 
    4242                                 if (fillsamecolor)
    4243 
    4244                                 {
    4245 
    4246                                     curpixdiff[0] = sameB;
    4247 
    4248                                     curpixdiff[1] = sameG;
    4249 
    4250                                     curpixdiff[2] = sameR;
    4251 
    4252                                 }
    4253 
    4254                                 ++samepixcnt;
    4255 
    4256  
    4257 
    4258                                 //记忆当前像素的比较结果的亮度
    4259 
    4260                                 briaryret[briaryidx] = samebri;
    4261 
    4262                             }
    4263 
    4264  
    4265 
    4266                             // 比较结果的亮度数组下标
    4267 
    4268                             ++briaryidx;
    4269 
    4270  
    4271 
    4272                             //像素是否不同的标志
    4273 
    4274                             compareret.PixIsDifferent[y * width + x] = curpixIsdiff;
    4275 
    4276  
    4277 
    4278                             curpix1 += 3;
    4279 
    4280                             curpix2 += 3;
    4281 
    4282                             curpixdiff += 3;
    4283 
    4284                         }
    4285 
    4286                         curpix1 += data1.Stride - width * 3;
    4287 
    4288                         curpix2 += data1.Stride - width * 3;
    4289 
    4290                         curpixdiff += datadiff.Stride - width * 3;
    4291 
    4292                     }
    4293 
    4294                 }
    4295 
    4296  
    4297 
    4298                 image1.UnlockBits(data1);
    4299 
    4300                 image2.UnlockBits(data2);
    4301 
    4302                 imagediff.UnlockBits(datadiff);
    4303 
    4304  
    4305 
    4306                 compareret.RateDifferent = diffpixcnt / (double)allpixcnt;
    4307 
    4308                 compareret.RateSame = samepixcnt / (double)allpixcnt;
    4309 
    4310  
    4311 
    4312                 compareret.CompareResultImage = imagediff;
    4313 
    4314                 compareret.BrightnessDiff = briDiff;
    4315 
    4316  
    4317 
    4318                 compareret.BrightnessBytesImage1 = briary1;
    4319 
    4320                 compareret.BrightnessBytesImage2 = briary2;
    4321 
    4322                 compareret.BrightnessBytesResult = briaryret;
    4323 
    4324  
    4325 
    4326                 //保存区域范围
    4327 
    4328                 //compareret.DiffAreaTop = areaTop;
    4329 
    4330                 //compareret.DiffAreaLeft = areaLeft;
    4331 
    4332                 //compareret.DiffAreaRight = areaRight;
    4333 
    4334                 //compareret.DiffAreaBottom = areaBottom;
    4335 
    4336                 //compareret.CalculateAreaRate();
    4337 
    4338  
    4339 
    4340                 bl = true;
    4341 
    4342             }
    4343 
    4344             catch (Exception ex)
    4345 
    4346             {
    4347 
    4348                 Console.WriteLine("CompareImage error:" + ex.Message);
    4349 
    4350                 bl = false;
    4351 
    4352             }
    4353 
    4354  
    4355 
    4356             return bl;
    4357 
    4358         }
    4359 
    4360  
    4361 
    4362  
    4363 
    4364         /// <summary>
    4365 
    4366         /// 2张图片亮度值相减,得到新图片以及亮度值
    4367 
    4368         /// </summary>
    4369 
    4370         /// <param name="image1"></param>
    4371 
    4372         /// <param name="image2"></param>
    4373 
    4374         /// <param name="retimage"></param>
    4375 
    4376         /// <param name="brightnessary"></param>
    4377 
    4378         /// <returns></returns>
    4379 
    4380         public static Boolean SubtractImageBrightness(Bitmap image1, Bitmap image2,
    4381 
    4382             ref Bitmap imagediff, ref Byte[] brightnessary)
    4383 
    4384         {
    4385 
    4386             if (image1 == null || image2 == null)
    4387 
    4388             {
    4389 
    4390                 return false;
    4391 
    4392             }
    4393 
    4394  
    4395 
    4396             Boolean bl = ResizeImageToSame(ref image1, ref image2);
    4397 
    4398             if (!bl)
    4399 
    4400             {
    4401 
    4402                 return false;
    4403 
    4404             }
    4405 
    4406            
    4407 
    4408             int width = image1.Width;
    4409 
    4410             int height = image1.Height;
    4411 
    4412  
    4413 
    4414             long allpixcnt = height * width;//所有像素点数量             
    4415 
    4416  
    4417 
    4418             brightnessary = new Byte[allpixcnt];
    4419 
    4420             imagediff = new Bitmap(image1);
    4421 
    4422             Int32 pixidx = 0;//当前像素下标
    4423 
    4424             byte bri1 = 0;
    4425 
    4426             byte bri2 = 0;
    4427 
    4428             BitmapData data1 = null;
    4429 
    4430             BitmapData data2 = null;
    4431 
    4432             BitmapData datadiff = null;
    4433 
    4434             //每行末尾还有这么多的冗余字节
    4435 
    4436             Int32 rowredundancy = 0;
    4437 
    4438  
    4439 
    4440             try
    4441 
    4442             {
    4443 
    4444                 data1 = image1.LockBits(new Rectangle(0, 0, width, height),
    4445 
    4446                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    4447 
    4448  
    4449 
    4450                 data2 = image2.LockBits(new Rectangle(0, 0, width, height),
    4451 
    4452                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    4453 
    4454  
    4455 
    4456                 datadiff = imagediff.LockBits(new Rectangle(0, 0, width, height),
    4457 
    4458                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    4459 
    4460  
    4461 
    4462                 rowredundancy = datadiff.Stride - width * 3;//每行末尾还有这么多的冗余字节
    4463 
    4464                 Byte bridiff = 0;
    4465 
    4466                 unsafe
    4467 
    4468                 {
    4469 
    4470                     byte* curpix1 = (byte*)data1.Scan0.ToPointer();
    4471 
    4472                     byte* curpix2 = (byte*)data2.Scan0.ToPointer();
    4473 
    4474                     byte* cmpretpix = (byte*)datadiff.Scan0.ToPointer();
    4475 
    4476  
    4477 
    4478                     for (int y = 0; y < height; y++)
    4479 
    4480                     {
    4481 
    4482                         for (int x = 0; x < width; x++)
    4483 
    4484                         {
    4485 
    4486                             bri1 = (byte)((float)(curpix1[0] + curpix1[1] + curpix1[2]) / 3.0f);
    4487 
    4488                             bri2 = (byte)((float)(curpix2[0] + curpix2[1] + curpix2[2]) / 3.0f);
    4489 
    4490  
    4491 
    4492                             bridiff = (bri1 > bri2) ? (Byte)(bri1 - bri2) : (Byte)(bri2 - bri1); //计算当前像素点的亮度值
    4493 
    4494                             brightnessary[pixidx] = bridiff;//保存亮度值
    4495 
    4496                             ++pixidx;
    4497 
    4498  
    4499 
    4500                             cmpretpix[0] = bridiff;//把亮度值设置到结果图像里
    4501 
    4502                             cmpretpix[1] = bridiff;
    4503 
    4504                             cmpretpix[2] = bridiff;
    4505 
    4506                            
    4507 
    4508                             curpix1 += 3;
    4509 
    4510                             curpix2 += 3;
    4511 
    4512                             cmpretpix += 3;
    4513 
    4514                         }
    4515 
    4516                         curpix1 += rowredundancy;
    4517 
    4518                         curpix2 += rowredundancy;
    4519 
    4520                         cmpretpix += rowredundancy;
    4521 
    4522                     }
    4523 
    4524                 }
    4525 
    4526  
    4527 
    4528                 image1.UnlockBits(data1);
    4529 
    4530                 image2.UnlockBits(data2);
    4531 
    4532                 imagediff.UnlockBits(datadiff);
    4533 
    4534                 bl = true;
    4535 
    4536             }
    4537 
    4538             catch (Exception ex)
    4539 
    4540             {
    4541 
    4542                 Console.WriteLine("CompareImage error:" + ex.Message);
    4543 
    4544                 bl = false;
    4545 
    4546             }
    4547 
    4548  
    4549 
    4550             return bl;
    4551 
    4552         }
    4553 
    4554  
    4555 
    4556         /// <summary>
    4557 
    4558         /// 根据2个图片的亮度值,比较图片的差异部分,并对比较结果的图片执行去噪点处理
    4559 
    4560         /// </summary>
    4561 
    4562         /// <param name="image1"></param>
    4563 
    4564         /// <param name="image2"></param>
    4565 
    4566         /// <param name="bridiff">亮度容差</param>
    4567 
    4568         /// <param name="noisypointsize">噪点边长</param>
    4569 
    4570         /// <param name="imagediff">比较结果的图片</param>
    4571 
    4572         /// <param name="diffary">每个像素是否相同</param>
    4573 
    4574         /// <returns></returns>
    4575 
    4576         public static Boolean CompareImageByBrightness(Bitmap image1, Bitmap image2,
    4577 
    4578             Int32 briDiff, Int32 noisypointsize,
    4579 
    4580             ref Bitmap imagediff, ref Boolean[] diffary)
    4581 
    4582         {
    4583 
    4584             if (image1 == null || image2 == null)
    4585 
    4586             {
    4587 
    4588                 return false;
    4589 
    4590             }
    4591 
    4592  
    4593 
    4594             Boolean bl = ResizeImageToSame(ref image1, ref image2);
    4595 
    4596             if (!bl)
    4597 
    4598             {
    4599 
    4600                 return false;
    4601 
    4602             }
    4603 
    4604  
    4605 
    4606             if (briDiff < 1 || briDiff > 255)
    4607 
    4608             {
    4609 
    4610                 return false;
    4611 
    4612             }
    4613 
    4614  
    4615 
    4616             if (noisypointsize < 1 || noisypointsize * 2 > image1.Height)
    4617 
    4618             {
    4619 
    4620                 return false;
    4621 
    4622             }
    4623 
    4624            
    4625 
    4626             int width = image1.Width;
    4627 
    4628             int height = image1.Height;
    4629 
    4630  
    4631 
    4632             long allpixcnt = height * width;//所有像素点数量
    4633 
    4634             
    4635 
    4636             imagediff = new Bitmap(image1);
    4637 
    4638            
    4639 
    4640             //每个像素是否相同.1相同,0不同
    4641 
    4642             diffary = new Boolean[width * height];
    4643 
    4644  
    4645 
    4646             Int32 pixidx = 0;//当前像素下标
    4647 
    4648             byte bri1 = 0;
    4649 
    4650             byte bri2 = 0;
    4651 
    4652             BitmapData data1 = null;
    4653 
    4654             BitmapData data2 = null;
    4655 
    4656             BitmapData datadiff = null;
    4657 
    4658             //每行末尾还有这么多的冗余字节
    4659 
    4660             Int32 rowredundancy = 0;
    4661 
    4662  
    4663 
    4664             try
    4665 
    4666             {
    4667 
    4668                 data1 = image1.LockBits(new Rectangle(0, 0, width, height),
    4669 
    4670                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    4671 
    4672  
    4673 
    4674                 data2 = image2.LockBits(new Rectangle(0, 0, width, height),
    4675 
    4676                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    4677 
    4678  
    4679 
    4680                 datadiff = imagediff.LockBits(new Rectangle(0, 0, width, height),
    4681 
    4682                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    4683 
    4684  
    4685 
    4686                 rowredundancy = datadiff.Stride - width * 3;//每行末尾还有这么多的冗余字节
    4687 
    4688  
    4689 
    4690                 unsafe
    4691 
    4692                 {
    4693 
    4694                     byte* curpix1 = (byte*)data1.Scan0.ToPointer();
    4695 
    4696                     byte* curpix2 = (byte*)data2.Scan0.ToPointer();
    4697 
    4698                     byte* cmpretpix = (byte*)datadiff.Scan0.ToPointer();
    4699 
    4700  
    4701 
    4702                     for (int y = 0; y < height; y++)
    4703 
    4704                     {
    4705 
    4706                         for (int x = 0; x < width; x++)
    4707 
    4708                         {
    4709 
    4710                             bri1 = (byte)((float)(curpix1[0] + curpix1[1] + curpix1[2]) / 3.0f);
    4711 
    4712                             bri2 = (byte)((float)(curpix2[0] + curpix2[1] + curpix2[2]) / 3.0f);
    4713 
    4714  
    4715 
    4716                             //比较2个像素亮度值之差,如果有差异,设置图像1里的当前像素为 不同颜色
    4717 
    4718                             if (bri1 >= bri2 + briDiff ||
    4719 
    4720                               bri2 >= bri1 + briDiff)
    4721 
    4722                             {
    4723 
    4724                                 diffary[pixidx] = true;
    4725 
    4726                                 cmpretpix[0] = Const_WhiteBrightness;
    4727 
    4728                                 cmpretpix[1] = Const_WhiteBrightness;
    4729 
    4730                                 cmpretpix[2] = Const_WhiteBrightness;
    4731 
    4732                             }
    4733 
    4734                             else
    4735 
    4736                             {
    4737 
    4738                                 diffary[pixidx] = false;
    4739 
    4740                                 cmpretpix[0] = Const_BlackBrightness;
    4741 
    4742                                 cmpretpix[1] = Const_BlackBrightness;
    4743 
    4744                                 cmpretpix[2] = Const_BlackBrightness;
    4745 
    4746                             }
    4747 
    4748  
    4749 
    4750                             ++pixidx;
    4751 
    4752                             curpix1 += 3;
    4753 
    4754                             curpix2 += 3;
    4755 
    4756                             cmpretpix += 3;
    4757 
    4758                         }
    4759 
    4760                         curpix1 += rowredundancy;
    4761 
    4762                         curpix2 += rowredundancy;
    4763 
    4764                         cmpretpix += rowredundancy;
    4765 
    4766                     }
    4767 
    4768                 }
    4769 
    4770  
    4771 
    4772                 image1.UnlockBits(data1);
    4773 
    4774                 image2.UnlockBits(data2);
    4775 
    4776                 imagediff.UnlockBits(datadiff);
    4777 
    4778                 bl = true;
    4779 
    4780             }
    4781 
    4782             catch (Exception ex)
    4783 
    4784             {
    4785 
    4786                 Console.WriteLine("CompareImage error:" + ex.Message);
    4787 
    4788                 bl = false;
    4789 
    4790             }
    4791 
    4792  
    4793 
    4794             //现在对图像执行去噪点处理
    4795 
    4796             RemoveNoisypoint(noisypointsize, ref imagediff);
    4797 
    4798  
    4799 
    4800             //获取去除噪点后各像素亮度
    4801 
    4802             Byte pixbri = 0;//当前像素亮度
    4803 
    4804             pixidx = 0;
    4805 
    4806             try
    4807 
    4808             {
    4809 
    4810                 datadiff = imagediff.LockBits(new Rectangle(0, 0, width, height),
    4811 
    4812                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    4813 
    4814                 unsafe
    4815 
    4816                 {
    4817 
    4818                     byte* cmpretpix = (byte*)datadiff.Scan0.ToPointer();
    4819 
    4820  
    4821 
    4822                     for (int y = 0; y < height; y++)
    4823 
    4824                     {
    4825 
    4826                         for (int x = 0; x < width; x++)
    4827 
    4828                         {
    4829 
    4830                             pixbri = (byte)((float)(cmpretpix[0] + cmpretpix[1] + cmpretpix[2]) / 3.0f);
    4831 
    4832  
    4833 
    4834                             //去除噪点后,已经变得非黑即白.如果是黑色,表示相同,白色,表示不同
    4835 
    4836                             diffary[pixidx] = (pixbri > briDiff);
    4837 
    4838                             ++pixidx;
    4839 
    4840                             cmpretpix += 3;
    4841 
    4842                         }
    4843 
    4844                         cmpretpix += rowredundancy;
    4845 
    4846                     }
    4847 
    4848                 }
    4849 
    4850  
    4851 
    4852                 imagediff.UnlockBits(datadiff);
    4853 
    4854                 bl = true;
    4855 
    4856             }
    4857 
    4858             catch (Exception ex)
    4859 
    4860             {
    4861 
    4862                 Console.WriteLine("CompareImage error:" + ex.Message);
    4863 
    4864                 bl = false;
    4865 
    4866             }
    4867 
    4868             return bl;
    4869 
    4870         }
    4871 
    4872  
    4873 
    4874         /// 根据2个图片的亮度值,比较图片的差异部分
    4875 
    4876         /// </summary>
    4877 
    4878         /// <param name="compareparam"></param>
    4879 
    4880         /// <param name="compareret"></param>
    4881 
    4882         /// <returns></returns>
    4883 
    4884         public static Boolean CompareImageByBrightness(ImageCompareParameter compareparam,
    4885 
    4886             ref ImageCompareResult compareret)
    4887 
    4888         {
    4889 
    4890             Bitmap image1 = compareparam.Image1;
    4891 
    4892             Bitmap image2 = compareparam.Image2;
    4893 
    4894  
    4895 
    4896             Byte[] imagebri1 = compareparam.BrightnessBytesImage1;
    4897 
    4898             Byte[] imagebri2 = compareparam.BrightnessBytesImage2;
    4899 
    4900  
    4901 
    4902             Int32 briDiff = compareparam.BrightnessDiff;
    4903 
    4904             Color diffColor = compareparam.DifferentAreaFillColor;
    4905 
    4906             Color samecolor = compareparam.SameAreaFillColor;
    4907 
    4908             //是否需要填充相同或不同部分的像素的颜色
    4909 
    4910             Boolean filldiffcolor = (diffColor != Color.Transparent);
    4911 
    4912             Boolean fillsamecolor = (samecolor != Color.Transparent);
    4913 
    4914  
    4915 
    4916             Boolean bl = false;
    4917 
    4918  
    4919 
    4920             Bitmap imagediff = new Bitmap(image1);
    4921 
    4922  
    4923 
    4924             //不同区域的左上下右位置
    4925 
    4926             Int32 areaLeft = imagediff.Width;
    4927 
    4928             Int32 areaTop = imagediff.Height;
    4929 
    4930             Int32 areaRight = -1;
    4931 
    4932             Int32 areaBottom = -1;
    4933 
    4934  
    4935 
    4936             int width = image1.Width;
    4937 
    4938             int height = image1.Height;
    4939 
    4940  
    4941 
    4942             long allpixcnt = height * width;//所有像素点数量
    4943 
    4944             long diffpixcnt = 0;//不同像素点数量
    4945 
    4946             long samepixcnt = 0;//相同像素点数量
    4947 
    4948            
    4949 
    4950             if (imagebri1 == null || imagebri2 == null ||
    4951 
    4952                 imagebri2.Length != imagebri2.Length ||
    4953 
    4954                 imagebri2.Length != allpixcnt)
    4955 
    4956             {
    4957 
    4958                 return false;
    4959 
    4960             }
    4961 
    4962  
    4963 
    4964             //3张图片的各像素亮度数组
    4965 
    4966             Int32 briaryidx = 0;
    4967 
    4968             Byte[] briaryret = new Byte[allpixcnt];
    4969 
    4970  
    4971 
    4972             Byte diffB = diffColor.B;
    4973 
    4974             Byte diffG = diffColor.G;
    4975 
    4976             Byte diffR = diffColor.R;
    4977 
    4978             Byte sameB = samecolor.B;
    4979 
    4980             Byte sameG = samecolor.G;
    4981 
    4982             Byte sameR = samecolor.R;
    4983 
    4984  
    4985 
    4986             Byte samebri = 0;
    4987 
    4988             Byte diffbri = 0;
    4989 
    4990             GetBrightnessByColor(diffColor, eGrayMode.WeightedAverage, ref samebri);
    4991 
    4992             GetBrightnessByColor(diffColor, eGrayMode.WeightedAverage, ref diffbri);
    4993 
    4994  
    4995 
    4996             Int32 currowfirstx = 0;//当前行的首个像素的下标
    4997 
    4998             try
    4999 
    5000             {
    5001 
    5002  
    5003 
    5004                 BitmapData data1 = image1.LockBits(new Rectangle(0, 0, width, height),
    5005 
    5006                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    5007 
    5008  
    5009 
    5010                 BitmapData data2 = image2.LockBits(new Rectangle(0, 0, width, height),
    5011 
    5012                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    5013 
    5014  
    5015 
    5016                 BitmapData datadiff = imagediff.LockBits(new Rectangle(0, 0, width, height),
    5017 
    5018                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    5019 
    5020  
    5021 
    5022                 byte bri1 = 0;
    5023 
    5024                 byte bri2 = 0;
    5025 
    5026  
    5027 
    5028                 //每个像素是否相同.1相同,0不同
    5029 
    5030                 compareret.PixIsDifferent = new Boolean[width * height];
    5031 
    5032  
    5033 
    5034                 //当前像素是否不同
    5035 
    5036                 Boolean curpixIsdiff = false;
    5037 
    5038                 unsafe
    5039 
    5040                 {
    5041 
    5042                     byte* curpix1 = (byte*)data1.Scan0.ToPointer();
    5043 
    5044                     byte* curpix2 = (byte*)data2.Scan0.ToPointer();
    5045 
    5046                     byte* cmpretpix = (byte*)datadiff.Scan0.ToPointer();
    5047 
    5048  
    5049 
    5050                     for (int y = 0; y < height; y++)
    5051 
    5052                     {
    5053 
    5054                         currowfirstx = y * width;
    5055 
    5056                         for (int x = 0; x < width; x++)
    5057 
    5058                         {
    5059 
    5060                             bri1 = imagebri1[currowfirstx + x];
    5061 
    5062                             bri2 = imagebri2[currowfirstx + x];
    5063 
    5064  
    5065 
    5066                             //以1作为基准,比较1和2之间的差距,如果超过阀值,认为当前像素有差异
    5067 
    5068                             //否则认为当前像素没有差异
    5069 
    5070                             curpixIsdiff = false;
    5071 
    5072                             if (bri1 >= bri2 + briDiff ||
    5073 
    5074                                 bri2 >= bri1 + briDiff)
    5075 
    5076                             {
    5077 
    5078                                 curpixIsdiff = true;
    5079 
    5080                             }
    5081 
    5082  
    5083 
    5084                             if (curpixIsdiff) //如果有差异,设置图像1里的当前像素为 不同颜色
    5085 
    5086                             {
    5087 
    5088                                 if (filldiffcolor)
    5089 
    5090                                 {
    5091 
    5092                                     cmpretpix[0] = diffB;
    5093 
    5094                                     cmpretpix[1] = diffG;
    5095 
    5096                                     cmpretpix[2] = diffR;
    5097 
    5098                                 }
    5099 
    5100                                 ++diffpixcnt;
    5101 
    5102  
    5103 
    5104                                 if (x < areaLeft) //记忆最左边的像素位置
    5105 
    5106                                 {
    5107 
    5108                                     areaLeft = x;
    5109 
    5110                                 }
    5111 
    5112                                 if (x > areaRight) //记忆最右边的像素位置
    5113 
    5114                                 {
    5115 
    5116                                     areaRight = x;
    5117 
    5118                                 }
    5119 
    5120                                 if (y < areaTop) //记忆最上边的像素位置
    5121 
    5122                                 {
    5123 
    5124                                     areaTop = y;
    5125 
    5126                                 }
    5127 
    5128                                 if (y > areaBottom) //记忆最下边的像素位置
    5129 
    5130                                 {
    5131 
    5132                                     areaBottom = y;
    5133 
    5134                                 }
    5135 
    5136  
    5137 
    5138                                 //记忆当前像素的比较结果的亮度
    5139 
    5140                                 briaryret[briaryidx] = diffbri;
    5141 
    5142                             }
    5143 
    5144                             else //没有差异,设置结果里的当前像素为 相同颜色
    5145 
    5146                             {
    5147 
    5148                                 if (fillsamecolor)
    5149 
    5150                                 {
    5151 
    5152                                     cmpretpix[0] = sameB;
    5153 
    5154                                     cmpretpix[1] = sameG;
    5155 
    5156                                     cmpretpix[2] = sameR;
    5157 
    5158                                 }
    5159 
    5160                                 ++samepixcnt;
    5161 
    5162  
    5163 
    5164                                 //记忆当前像素的比较结果的亮度
    5165 
    5166                                 briaryret[briaryidx] = samebri;
    5167 
    5168                             }
    5169 
    5170  
    5171 
    5172                             // 比较结果的亮度数组下标
    5173 
    5174                             ++briaryidx;
    5175 
    5176  
    5177 
    5178                             //像素是否不同的标志
    5179 
    5180                             compareret.PixIsDifferent[currowfirstx + x] = curpixIsdiff;
    5181 
    5182  
    5183 
    5184                             curpix1 += 3;
    5185 
    5186                             curpix2 += 3;
    5187 
    5188                             cmpretpix += 3;
    5189 
    5190                         }
    5191 
    5192                         curpix1 += data1.Stride - width * 3;
    5193 
    5194                         curpix2 += data1.Stride - width * 3;
    5195 
    5196                         cmpretpix += datadiff.Stride - width * 3;
    5197 
    5198                     }
    5199 
    5200                 }
    5201 
    5202  
    5203 
    5204                 image1.UnlockBits(data1);
    5205 
    5206                 image2.UnlockBits(data2);
    5207 
    5208                 imagediff.UnlockBits(datadiff);
    5209 
    5210  
    5211 
    5212                 compareret.RateDifferent = diffpixcnt / (double)allpixcnt;
    5213 
    5214                 compareret.RateSame = samepixcnt / (double)allpixcnt;
    5215 
    5216  
    5217 
    5218                 compareret.CompareResultImage = imagediff;
    5219 
    5220                 compareret.BrightnessDiff = briDiff;
    5221 
    5222                 compareret.BrightnessBytesResult = briaryret;
    5223 
    5224  
    5225 
    5226                 bl = true;
    5227 
    5228             }
    5229 
    5230             catch (Exception ex)
    5231 
    5232             {
    5233 
    5234                 Console.WriteLine("CompareImage error:" + ex.Message);
    5235 
    5236                 bl = false;
    5237 
    5238             }
    5239 
    5240  
    5241 
    5242             return bl;
    5243 
    5244         }
    5245 
    5246  
    5247 
    5248         /// <summary>
    5249 
    5250         /// 获取一个区域的实际坐标
    5251 
    5252         /// </summary>
    5253 
    5254         /// <param name="area"></param>
    5255 
    5256         /// <param name="width"></param>
    5257 
    5258         /// <param name="height"></param>
    5259 
    5260         /// <param name="x1"></param>
    5261 
    5262         /// <param name="y1"></param>
    5263 
    5264         /// <param name="x2"></param>
    5265 
    5266         /// <param name="y2"></param>
    5267 
    5268         public static void GetAreaPositionInImage(ImageAreaInfo area,
    5269 
    5270             Int32 width, Int32 height,
    5271 
    5272             ref Int32 x1, ref Int32 y1, ref Int32 x2, ref Int32 y2)
    5273 
    5274         {
    5275 
    5276             if (area.PositionType == ePositionType.ByPix)
    5277 
    5278             {
    5279 
    5280                 x1 = (Int32)area.X1;
    5281 
    5282                 y1 = (Int32)area.Y1;
    5283 
    5284                 x2 = (Int32)area.X2;
    5285 
    5286                 y2 = (Int32)area.Y2;
    5287 
    5288             }
    5289 
    5290             else
    5291 
    5292             {
    5293 
    5294                 x1 = (Int32)(area.X1 * (double)width);
    5295 
    5296                 y1 = (Int32)(area.Y1 * (double)height);
    5297 
    5298                 x2 = (Int32)(area.X2 * (double)width);
    5299 
    5300                 y2 = (Int32)(area.Y2 * (double)height);
    5301 
    5302             }
    5303 
    5304         }
    5305 
    5306  
    5307 
    5308         /// <summary>
    5309 
    5310         /// 检查指定区域的图像是否与方案里的指定值一样(都是相同或者不同)
    5311 
    5312         /// </summary>
    5313 
    5314         /// <param name="briDiffary">每个元素对应2张图片的每个像素亮度相同还是不同.true不同,false相同</param>
    5315 
    5316         /// <param name="area"></param>
    5317 
    5318         /// <returns></returns>
    5319 
    5320         public static Boolean ValidateImageArea(Boolean[] briDiffary, ImageAreaInfo area, Int32 width, Int32 height)
    5321 
    5322         {
    5323 
    5324             if (briDiffary == null || briDiffary.Length < 4 || area == null ||
    5325 
    5326                 width < 1 || height < 1 || width * height != briDiffary.Length)
    5327 
    5328             {
    5329 
    5330                 return false;
    5331 
    5332             }
    5333 
    5334  
    5335 
    5336             Int32 x1 = 0;
    5337 
    5338             Int32 x2 = 0;
    5339 
    5340             Int32 y1 = 0;
    5341 
    5342             Int32 y2 = 0;
    5343 
    5344  
    5345 
    5346             //获取该区域在图像里的实际坐标范围
    5347 
    5348             GetAreaPositionInImage(area, width, height,
    5349 
    5350                 ref x1, ref y1, ref x2, ref y2);
    5351 
    5352  
    5353 
    5354             //获取该区域里的像素匹配类型
    5355 
    5356             eAreaDifferentType difftype = eAreaDifferentType.Partial;
    5357 
    5358             Boolean bl = GetImageAreaDifferentType(briDiffary, width, height,
    5359 
    5360                 x1, y1, x2, y2, ref difftype);
    5361 
    5362             if (!bl)
    5363 
    5364             {
    5365 
    5366                 return false;
    5367 
    5368             }
    5369 
    5370  
    5371 
    5372             //如果是期待所有像素都是相同,要求必须每个像素都相同.任何一个不同,就认为失败
    5373 
    5374             if (area.ExpectDispMode == eDrawType.ExpectHide &&
    5375 
    5376                 difftype != eAreaDifferentType.AllSame)
    5377 
    5378             {
    5379 
    5380                 return false;
    5381 
    5382             }
    5383 
    5384  
    5385 
    5386             //如果是期待像素不同,只要有1个像素不同就可以.所有像素都相同,认为失败
    5387 
    5388             if (area.ExpectDispMode == eDrawType.ExpectShow &&
    5389 
    5390                 difftype == eAreaDifferentType.AllSame)
    5391 
    5392             {
    5393 
    5394                 return false;
    5395 
    5396             }
    5397 
    5398             return true;
    5399 
    5400         }
    5401 
    5402  
    5403 
    5404         /// <summary>
    5405 
    5406         /// 检查指定区域的图像是否与方案里的指定值一样(都是相同或者不同)
    5407 
    5408         /// </summary>
    5409 
    5410         /// <param name="pixDiffary"></param>
    5411 
    5412         /// <param name="area"></param>
    5413 
    5414         /// <returns></returns>
    5415 
    5416         public static Boolean ValidateImageArea(Byte[] briDiffary, ImageAreaInfo area, Int32 width, Int32 height)
    5417 
    5418         {
    5419 
    5420  
    5421 
    5422             Boolean[] blary = new Boolean[briDiffary.Length];
    5423 
    5424             for (Int32 idx = 0; idx < briDiffary.Length; ++idx)
    5425 
    5426             {
    5427 
    5428                 blary[idx] = (briDiffary[idx] > 0);
    5429 
    5430             }
    5431 
    5432  
    5433 
    5434             Boolean bl = ValidateImageArea(blary, area, width, height);
    5435 
    5436             return bl;
    5437 
    5438         }
    5439 
    5440        
    5441 
    5442         /// <summary>
    5443 
    5444         /// 检查图片的比较结果里,某个区域是否与期待的一致
    5445 
    5446         /// </summary>
    5447 
    5448         /// <param name="compareret"></param>
    5449 
    5450         /// <param name="area"></param>
    5451 
    5452         /// <returns>true-与期待一致;false-不一致</returns>
    5453 
    5454         public static Boolean ValidateImageArea(ImageCompareResult compareret, ImageAreaInfo area)
    5455 
    5456         {
    5457 
    5458             Boolean[] pixDiffary = compareret.PixIsDifferent;
    5459 
    5460  
    5461 
    5462             Bitmap tmp = new Bitmap(compareret.CompareResultImage);
    5463 
    5464             Int32 width = tmp.Width;
    5465 
    5466             Int32 height = tmp.Height;
    5467 
    5468             Boolean bl = ValidateImageArea(compareret.PixIsDifferent, area, width, height);
    5469 
    5470  
    5471 
    5472             return bl;
    5473 
    5474         }
    5475 
    5476       
    5477 
    5478         /// <summary>
    5479 
    5480         /// 获取1个 比较结果里,指定的区域范围,是全都相同,还是不同
    5481 
    5482         /// 只有所有像素都是相同,才认为是整个区域相同
    5483 
    5484         /// 如果有1个像素不同,则认为整个区域不同
    5485 
    5486         /// </summary>
    5487 
    5488         /// <param name="pixDiffary"></param>
    5489 
    5490         /// <param name="width"></param>
    5491 
    5492         /// <param name="height"></param>
    5493 
    5494         /// <param name="startX"></param>
    5495 
    5496         /// <param name="startY"></param>
    5497 
    5498         /// <param name="endX"></param>
    5499 
    5500         /// <param name="endY"></param>
    5501 
    5502         /// <returns> </returns>
    5503 
    5504         public static Boolean GetImageAreaDifferentType(Boolean[] pixDiffary, Int32 width, Int32 height,
    5505 
    5506             Int32 x1, Int32 y1, Int32 x2, Int32 y2, ref eAreaDifferentType difftype)
    5507 
    5508         {
    5509 
    5510             Int32 areawidth = x2 - x1;
    5511 
    5512             Int32 areaheight = y2 - y1;
    5513 
    5514  
    5515 
    5516             if (pixDiffary == null || width < 1 || height < 1 ||
    5517 
    5518                 areawidth < 1 || areaheight < 1 ||
    5519 
    5520                 width < areawidth || height < areaheight ||
    5521 
    5522                 pixDiffary.Length < width * height)
    5523 
    5524             {
    5525 
    5526                 return false;
    5527 
    5528             }
    5529 
    5530  
    5531 
    5532             Boolean allissame = false; //假设所有像素相同
    5533 
    5534             Boolean allisdiff = false; //假设所有像素不同
    5535 
    5536  
    5537 
    5538             Int32 currowFirstPix = 0;
    5539 
    5540             for (Int32 y = y1; y <= y2; ++y)
    5541 
    5542             {
    5543 
    5544                 currowFirstPix = y * width;
    5545 
    5546                 for (Int32 x = x1; x <= x2; ++x)
    5547 
    5548                 {
    5549 
    5550                     if (pixDiffary[currowFirstPix + x]) //当前像素点不同
    5551 
    5552                     {
    5553 
    5554                         allisdiff = true;
    5555 
    5556                     }
    5557 
    5558                     else//当前像素相同
    5559 
    5560                     {
    5561 
    5562                         allissame = true;
    5563 
    5564                     }
    5565 
    5566  
    5567 
    5568                     //如果已经有部分相同部分不同,退出
    5569 
    5570                     if (allisdiff && allissame)
    5571 
    5572                     {
    5573 
    5574                         difftype = eAreaDifferentType.Partial;
    5575 
    5576                         return true;
    5577 
    5578                     }
    5579 
    5580                 }
    5581 
    5582             }
    5583 
    5584  
    5585 
    5586             //现在,所有像素都相同,或都不同
    5587 
    5588             if (allisdiff)
    5589 
    5590             {
    5591 
    5592                 difftype = eAreaDifferentType.AllDifferent;
    5593 
    5594             }
    5595 
    5596             else
    5597 
    5598             {
    5599 
    5600                 difftype = eAreaDifferentType.AllSame;
    5601 
    5602             }
    5603 
    5604             return true;
    5605 
    5606         }
    5607 
    5608  
    5609 
    5610         /// <summary>
    5611 
    5612         /// 根据亮度容差,把图片转换为非黑即白的图片
    5613 
    5614         /// </summary>
    5615 
    5616         /// <param name="briimg"></param>
    5617 
    5618         /// <param name="brigate"></param>
    5619 
    5620         /// <returns></returns>
    5621 
    5622         public static Boolean GetBlackWhiteImage(Bitmap briimg, Byte[] briDiffary, Int32 brigate, ref Bitmap blackwhiteimage)
    5623 
    5624         {
    5625 
    5626             if (briimg == null)
    5627 
    5628             {
    5629 
    5630                 return false;
    5631 
    5632             }
    5633 
    5634  
    5635 
    5636             int width = briimg.Width;
    5637 
    5638             int height = briimg.Height;
    5639 
    5640  
    5641 
    5642             long allpixcnt = height * width;//所有像素点数量            
    5643 
    5644  
    5645 
    5646             if (briDiffary == null || briDiffary.Length != allpixcnt)
    5647 
    5648             {
    5649 
    5650                 return false;
    5651 
    5652             }
    5653 
    5654  
    5655 
    5656             blackwhiteimage = new Bitmap(briimg);
    5657 
    5658             Int32 pixidx = 0;//当前像素下标
    5659 
    5660             BitmapData datasrc = null;
    5661 
    5662             BitmapData dataret = null;
    5663 
    5664  
    5665 
    5666             //每行末尾还有这么多的冗余字节
    5667 
    5668             Int32 rowredundancy = 0;
    5669 
    5670  
    5671 
    5672             Byte curpixBri = 0;//当前的亮度
    5673 
    5674             try
    5675 
    5676             {
    5677 
    5678                 datasrc = briimg.LockBits(new Rectangle(0, 0, width, height),
    5679 
    5680                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    5681 
    5682  
    5683 
    5684                 dataret = blackwhiteimage.LockBits(new Rectangle(0, 0, width, height),
    5685 
    5686                     ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    5687 
    5688  
    5689 
    5690                 rowredundancy = datasrc.Stride - width * 3;//每行末尾还有这么多的冗余字节
    5691 
    5692                 unsafe
    5693 
    5694                 {
    5695 
    5696                     byte* pixret = (byte*)dataret.Scan0.ToPointer();
    5697 
    5698  
    5699 
    5700                     for (int y = 0; y < height; y++)
    5701 
    5702                     {
    5703 
    5704                         for (int x = 0; x < width; x++)
    5705 
    5706                         {
    5707 
    5708                             //亮度差值大于门限的,认为是不同部分,用白色填充
    5709 
    5710                             curpixBri = (briDiffary[pixidx] > brigate) ? Const_BrightnessWhite : Const_BrightnessBlack;
    5711 
    5712                             pixret[0] = curpixBri;//把亮度值设置到结果图像里
    5713 
    5714                             pixret[1] = curpixBri;
    5715 
    5716                             pixret[2] = curpixBri;
    5717 
    5718                             ++pixidx;
    5719 
    5720                             pixret += 3;
    5721 
    5722                         }
    5723 
    5724                         pixret += rowredundancy;
    5725 
    5726                     }
    5727 
    5728                 }
    5729 
    5730  
    5731 
    5732                 briimg.UnlockBits(datasrc);
    5733 
    5734                 blackwhiteimage.UnlockBits(dataret);
    5735 
    5736             }
    5737 
    5738             catch (Exception ex)
    5739 
    5740             {
    5741 
    5742                 Console.WriteLine("GetBlackWhiteImage error:" + ex.Message);
    5743 
    5744                 return false;
    5745 
    5746             }
    5747 
    5748  
    5749 
    5750             return true;
    5751 
    5752         }
    5753 
    5754         #endregion
    5755 
    5756        
    5757 
    5758         #region 内部实现
    5759 
    5760  
    5761 
    5762  
    5763 
    5764         /// <summary>
    5765 
    5766         /// 比较2个数值之间的差是否大于指定值
    5767 
    5768         /// </summary>
    5769 
    5770         /// <param name="val1"></param>
    5771 
    5772         /// <param name="val2"></param>
    5773 
    5774         /// <param name="diff"></param>
    5775 
    5776         /// <returns>超过指定值返回true;否则返回false</returns>
    5777 
    5778         private static Boolean CheckDiffOver(Int32 val1, Int32 val2, Int32 diff)
    5779 
    5780         {
    5781 
    5782             if (diff < 1)
    5783 
    5784             {
    5785 
    5786                 return false;
    5787 
    5788             }
    5789 
    5790             if (val1 > val2 && val1 > val2 + diff)
    5791 
    5792             {
    5793 
    5794                 return true;
    5795 
    5796             }
    5797 
    5798             if (val2 > val1 && val2 > val1 + diff)
    5799 
    5800             {
    5801 
    5802                 return true;
    5803 
    5804             }
    5805 
    5806             return false;
    5807 
    5808         }
    5809 
    5810         #endregion
    5811 
    5812     }
    5813 
    5814 }
  • 相关阅读:
    我的Java设计模式-原型模式
    我的Java设计模式-观察者模式
    我的Java设计模式-建造者模式
    我的Java设计模式-单例模式
    我的Java设计模式-工厂方法模式
    菜鸟必备教程,ajax与xml交互传输数据。
    javascript Date format(js日期格式化)
    用script实现内容显示,并使用json传输数据
    使用jquer获取当前时间,并赋值到input上。
    利用js获取时间并输出值
  • 原文地址:https://www.cnblogs.com/anduinlothar/p/6247980.html
Copyright © 2011-2022 走看看