.前言


C#打印小票可以与普通打印机一样,调用PrintDocument实现。也可以发送标注你的ESC指令实现。由于 调用PrintDocument类时,无法操作使用串口或TCP/IP接口连接的pos打印机,并且无法发送控制指令实现pos打印机的切纸、走纸等动作。因此个人建议使用ESC指令进行打印会更通用。

本类需要调用 ImageProcessor.cs


2.POS机打印小票ReceiptHelper

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;

using System.Threading;

using System.Drawing;

using System.Management;

using System.IO;

using LaisonTech.MediaLib;

using LaisonTech.CommonBLL;

using Microsoft.Win32.SafeHandles;


namespace LaisonTech.MediaLib

{


#region 结构体定义


   [StructLayout(LayoutKind.Sequential)]

   public struct OVERLAPPED

   {

       int Internal;

       int InternalHigh;

       int Offset;

       int OffSetHigh;

       int hEvent;

   };


   [StructLayout(LayoutKind.Sequential)]

   public struct PRINTER_DEFAULTS

   {


       public int pDatatype;


       public int pDevMode;


       public int DesiredAccess;


   }


   ///


   /// 对齐方式

   ///


   public enum eTextAlignMode

   {

       Left = 0,

       Middle = 1,

       Right = 2

   }


#endregion


   ///


   /// 小票打印类

/// 使用方法:

/// 1 GetPrinterList获取已经安装的所有打印机列表.

///  Open 打开指定打印机

/// 2 控制打印机动作、执行打印内容之前,必须先调用StartPrint,准备向打印机发送控制指令

/// 3 调用SetLeft, SetBold, SetAlignMode, SetFontSize ... ...设置打印参数

/// 4  PrintText 打印内容.注意:打印该行内容后会自动换行(本类会在该行内容末尾添加一个换行符)

///   PrintImageFile 或 PrintBitMap打印图片

/// 5 控制指令和打印内容都发送完毕后,调用 EndPrint执行真正打印动作

   /// 6 退出程序前调用Close

   ///


   public class ReceiptHelper

   {

       #region 指令定义

     

       private static Byte[] Const_Init = new byte[] { 0x1B, 0x40,

           0x20, 0x20, 0x20, 0x0A,

           0x1B, 0x64,0x10};


       //设置左边距

       private const string Const_SetLeft = "1D 4C ";



       //设置粗体

       private const string Const_SetBold = "1B 45 ";

       private const String Const_Bold_YES = "01";

       private const String Const_Bold_NO = "00";

     

     

       //设置对齐方式

       private const string Const_SetAlign = "1B 61 ";

       private const String Const_Align_Left = "30";

       private const String Const_Align_Middle = "31";

       private const String Const_Align_Right = "32";


       //设置字体大小,与 SetBigFont 不能同时使用

       private const string Const_SetFontSize = "1D 21 ";


       //设置是否大字体,等同于 SetFontSize = 2

       //private const String Const_SetBigFontBold = "1B 21 38";

       //private const String Const_SetBigFontNotBold = "1B 21 30";

       //private const String Const_SetCancelBigFont = "1B 21 00";


       ///


       /// 打印并走纸

       ///


       private static Byte[] Const_Cmd_Print = new byte[] { 0x1B, 0x4A, 0x00 };

       //走纸

       private const string Const_FeedForward = "1B 4A ";

       private const string Const_FeedBack = "1B 6A ";


       //切纸

       private static Byte[]  Const_SetCut = new byte[] { 0x1D, 0x56, 0x30};


       //查询打印机状态

       private static Byte[] Const_QueryID = new byte[] { 0x1D, 0x67, 0x61};


       //回复帧以 ID 开头

       private static String Const_ResponseQueryID = "ID";


       ///


       /// 设置图标的指令

       ///


       private static Byte[] Const_SetImageCommand = new Byte[] { 0x1B, 0x2A, 0x21 };


#endregion

     

       #region 常量定义


       ///


       /// 最大字体大小

       ///


       public const Int32 Const_MaxFontSize = 8;

       ///


       /// 最大走纸距离

       ///


       public const Int32 Const_MaxFeedLength = 5000;


       ///


       /// 最大高宽

       ///


       public const Int32 Const_MaxImageLength = 480;

     

       ///


       /// 每次通信最多打印的行数

       ///


       public const Int32 Const_OncePrintRowCount = 24;


       public const Int32 Const_BrightnessGate = 100;


       ///


       /// 无效句柄

       ///


       public const Int32 Const_InvalidHandle = -1;

       #endregion


       #region 私有成员


       ///


       /// 打印机句柄

       ///


       private int m_Handle = -1;


       ///


       /// 是否已经初始化

       ///


       private Boolean m_Inited = false;



       #endregion

     

       #region 私有函数

             

       [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter,

           out Int32 hPrinter, IntPtr pd);


       [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool StartDocPrinter(Int32 hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);


       [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool EndDocPrinter(Int32 hPrinter);


       [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool StartPagePrinter(Int32 hPrinter);


       [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool EndPagePrinter(Int32 hPrinter);


       [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool WritePrinter(Int32 hPrinter, Byte[] pBytes, Int32 dwCount, out Int32 dwWritten);

     

       [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool ClosePrinter(Int32 hPrinter);

     


       ///


       /// 发送指令

       ///


       ///

       ///

       private Boolean SendCommand(Byte[] cmd)

       {

           if (m_Handle == Const_InvalidHandle || cmd == null || cmd.Length < 2)

           {

               return false;

           }


           int writelen = 0;

           Boolean bl = WritePrinter(m_Handle, cmd, cmd.Length, out writelen);


           if (!bl) return false;

           return (writelen >= cmd.Length);

       }

     

       ///


       /// 发送文本格式的指令

       ///


       ///

       ///

       private Boolean SendCommand(String hexstrcmd)

       {

           if (m_Handle == Const_InvalidHandle || hexstrcmd == null || hexstrcmd.Length < 4)

           {

               return false;

           }

         

           byte[] mybyte = null;

           Boolean bl = DataFormatProcessor.HexStringToBytes(hexstrcmd, out mybyte);

           bl = SendCommand(mybyte);

           return bl;

       }


 

       #endregion


       #region 内部处理 - 打印图片


       ///


       /// 把图片转换为指令字节,图片最大高宽不能超过480

       ///


       ///

       ///

       ///

       public static Boolean LoadImage(Bitmap image,

           ref Byte[] bitarray,ref Int32 datawidth,ref Int32 dataheight)

       {

           Int32 newwidth = 0;

           Int32 newheight = 0;

           Bitmap destimage = image;

           Boolean bl = false;


           //如果高度超过范围,或宽度超过范围,需要进行缩小

           if (image.Width > Const_MaxImageLength || image.Height > Const_MaxImageLength)

           {

               //按照高度和宽度,较大的那一边,进行缩放

               if (image.Width > image.Height)

               {

                   newwidth = Const_MaxImageLength;

                   newheight = (Int32)(image.Height * newwidth / (float)image.Width);

               }

               else

               {

                   newheight = Const_MaxImageLength;

                   newwidth = (Int32)(newheight * image.Width / (float)image.Height);

               }


               bl = ImageProcessor.ResizeImage(image, newwidth, newheight, ref destimage);

           }


           //把数据转换为字节数组

           bl = GetBitArray(image, ref bitarray, ref datawidth, ref dataheight);

           return bl;

       }


       ///


       /// 把图片转换为指令字节,图片最大高宽不能超过480

       /// 如果图片的高度不是24的整数倍,则修改为24的整数倍

       ///


       ///

       ///

       ///

       public static Boolean LoadImageFromFile(String imagefilename, ref Byte[] bmpbytes,

           ref Int32 width, ref Int32 height)

       {

           Bitmap img = ImageProcessor.LoadBitImage(imagefilename);

           if (img == null)

           {

               return false;

           }


           Boolean bl = LoadImage(img, ref bmpbytes, ref width, ref height);

           return bl;

       }

     

       ///


       /// 把图片转换为位图数组,每个字节的每个比特位,对应当前像素 是否需要打印

       ///


       ///

       ///

       ///

       public static Boolean GetBitArray(Bitmap img,

           ref Byte[] allbitary, ref Int32 width, ref Int32 height)

       {

           if (img == null)

           {

               return false;

           }


           //ESC指令格式规定:

           //1 打印图片时,每条指令最多只打印24行;不足24行的,也要用全0填充满数据字节

           //2 打印24行数据时,按照光栅模式纵向获取数据

           //  即先获取所有x=0的点(第0列)转换为3个字节;

           //  再获取所有x=1的点转换为3个字节;...直到获取到最右侧一列的点

           //3 打印完当前24行数据后,再获取后续24行的数据内容,直到所有的数据获取完毕


           //获取亮度数组

           Boolean[] briary = null;

           Boolean bl = ImageProcessor.ToBooleanArray(img, Const_BrightnessGate, ref briary);

           if (!bl)

           {

               return false;

           }


           height = img.Height;//如果图像高度不是24整数倍,设置为24的整数倍      

           if (height % Const_OncePrintRowCount != 0)

           {

               height = height + Const_OncePrintRowCount - height % Const_OncePrintRowCount;

           }


           width = img.Width;//如果图像宽度不是8的整数倍,设置为8的整数倍

           if (width % 8 != 0)

           {

               width = width + 8 - width % 8;

           }


           Int32 bytelen = height * width / 8;//每个像素对应1个比特位,因此总字节数=像素位数/8


           allbitary = new Byte[bytelen];


           Int32 byteidxInCol = 0;//当前列里首个像素,在目标字节数组里的下标

           Int32 byteidx = 0;//当前像素在目标数组里的字节下标

           Int32 bitidx = 0;//当前像素在目标数组里当前字节里的比特位下标

           Int32 pixidxInCol = 0;//当前像素在当前列里的第几个位置


           Int32 pixidx = 0;//当前像素在原始图片里的下标

         

           Int32 rowidx = 0; //当前 处理的像素点所在行,不能超过 图像高度

           Int32 curprocrows = 0;//当前需要处理的行数量

           while (rowidx < height)

           {

               //按照纵向次序,把当前列的24个数据,转换为3个字节

               for (Int32 colidx = 0; colidx < img.Width; ++colidx)

               {

                   //如果当前还剩余超过24行没处理,处理24行

                   if (rowidx + Const_OncePrintRowCount <= img.Height)

                   {

                       curprocrows = Const_OncePrintRowCount;

                   }

                   else

                   {

                       //已经不足24行,只处理剩余行数

                       curprocrows = img.Height - rowidx;

                   }


                   pixidxInCol = 0; //本列里从像素0开始处理

                   for (Int32 y = rowidx; y < rowidx + curprocrows; ++y)

                   {

                       //原始图片里像素位置

                       pixidx = y * img.Width + colidx;


                       //获取当前像素的亮度值.如果当前像素是黑点,需要把数组里的对应比特位设置为1

                       if (briary[pixidx])

                       {

                           bitidx = 7 - pixidxInCol % 8;//最高比特位对应首个像素.最低比特位对应末个像素

                           byteidx = byteidxInCol + pixidxInCol / 8; //由于最后一段可能不足24行,因此不能使用byteidx++

                         

                           DataFormatProcessor.SetBitValue(bitidx, true, ref allbitary[byteidx]);

                       }

                       pixidxInCol++;

                   }

                   byteidxInCol += 3;//每列固定24个像素,3个字节

               }


               rowidx += Const_OncePrintRowCount;

           }

         

           return true;

       }


       #endregion


       #region 公开函数


       private static ReceiptHelper m_instance = new ReceiptHelper();


       ///


       /// 当前使用的打印机名称

       ///


       public String PrinterName

       {

           get;private set;

       }


       ///


       /// 单件模式

       ///


       ///

       public static ReceiptHelper GetInstance()

       {

           return m_instance;

       }


       ///


       /// 获取本机安装的所有打印机

       ///


       ///

       public static List GetPrinterList()

       {

           List ret = new List();

           if (PrinterSettings.InstalledPrinters.Count < 1)

           {

               return ret;

           }


           foreach (String printername in PrinterSettings.InstalledPrinters)

           {

               ret.Add(printername);

           }

           return ret;

       }


       ///


       /// 打开打印机

       ///


       ///

       ///

       public Boolean Open(String printername)

       {

           if (m_Inited)

           {

               return true;

           }

           Boolean bl = OpenPrinter(printername.Normalize(), out m_Handle, IntPtr.Zero);

           

           m_Inited = (bl && m_Handle != 0);

           return true;

       }


       ///


       /// 开始打印,在打印之前必须调用此函数

       ///


       ///

       public Boolean StartPrint()

       {

           if (!m_Inited)

           {

               return false;

           }

           DOCINFOA di = new DOCINFOA();

           di.pDocName = "My C#.NET RAW Document";

           di.pDataType = "RAW";

           //Start a document.

           Boolean bl = StartDocPrinter(m_Handle, 1, di);

           if (!bl)

           {

               return false;

           }

           // Start a page.

           bl = StartPagePrinter(m_Handle);

           return bl;

       }


       ///


       /// 结束打印,在打印结束之后必须调用此函数

       ///


       ///

       public Boolean EndPrint()

       {

           if (!m_Inited)

           {

               return false;

           }

           Boolean bl = EndPagePrinter(m_Handle);

           bl = EndDocPrinter(m_Handle);

           return bl;

       }

     

       ///


       /// 销毁

       ///


       ///

       public Boolean Close()

       {

           if (!m_Inited)

           {

               return true;

           }

           m_Inited = false;


           //关闭设备句柄

           ClosePrinter(m_Handle);

           m_Handle = -1;

           return true;

       }

     

       ///


       /// 打印文本.在调用本函数之前必须先调用正确的 设置字体、左边距

       ///


       ///

       ///

       public Boolean PrintText(String content)

       {

           if (!m_Inited)

           {

               return false;

           }


           byte[] bytes = null;

           if (content.Length < 1)

           {

               content =  "  ";

           }

         

           if (content[content.Length - 1] != (char)0x0D &&

               content[content.Length - 1] != (char)0x0A)

           {

               content = content + (char)0x0A;

           }

         

           bytes = DataFormatProcessor.StringToBytes(content);

           bool bl = SendCommand(bytes);

           return bl;

       }


       ///


       /// 设置对齐方式

       ///


       ///

       ///

       public bool SetAlignMode(eTextAlignMode alignmode)

       {

           if (!m_Inited)

           {

               return false;

           }


           String code = String.Empty;

           switch (alignmode)

           {

               case eTextAlignMode.Left:

                   code = Const_Align_Left;

                   break;

               case eTextAlignMode.Middle:

                   code = Const_Align_Middle;

                   break;

               case eTextAlignMode.Right:

                   code = Const_Align_Right;

                   break;

               default:

                   code = Const_Align_Left;

                   break;

           }


           //注意:先低字节后高字节

           string str = Const_SetAlign + code;

           bool bl = SendCommand(str);

           return bl;

       }

     

       ///


       /// 设置左边距

       ///


       ///

       ///

       public bool SetLeft(int left)

       {

           if (!m_Inited)

           {

               return false;

           }


           //注意:先低字节后高字节

           String hexstr = left.ToString("X4");

           string str = Const_SetLeft + hexstr.Substring(2, 2) + hexstr.Substring(0, 2);

           bool bl = SendCommand(str);

           return bl;

       }


       ///


       /// 设置粗体

       ///


       ///

       ///

       public Boolean SetBold(Boolean bold)

       {

           if (!m_Inited)

           {

               return false;

           }


           //注意:先低字节后高字节

           String str = String.Empty;

           if (bold)

           {

               str = Const_SetBold + Const_Bold_YES;

           }

           else

           {

               str = Const_SetBold + Const_Bold_NO;

           }

           bool bl = SendCommand(str);

           return bl;

       }


       ///


       /// 切纸

       ///


       ///

       public bool Cut()

       {

           if (!m_Inited)

           {

               return false;

           }

           bool bl = SendCommand(Const_SetCut);

           return bl;

       }



       ///


       /// 打印图片

       ///


       ///

       ///

       public bool PrintImageFile(String imgfilename)

       {

           if (!m_Inited)

           {

               return false;

           }

           Bitmap img = ImageProcessor.LoadBitImage(imgfilename);

           if (img == null)

           {

               return false;

           }


           Boolean bl = PrintBitmap(img);

           return bl;

       }

     

       ///


       /// 打印图片

       ///


       ///

       ///

       public bool PrintBitmap(Bitmap bitmap)

       {

           if (!m_Inited)

           {

               return false;

           }


           if (bitmap == null ||

               bitmap.Width > Const_MaxImageLength ||

               bitmap.Height > Const_MaxImageLength)

           {

               return false;

           }


           Byte[] bitary = null;

           Int32 width = 0;

           Int32 height = 0;

           Boolean bl = GetBitArray(bitmap, ref bitary, ref width, ref height);


           bl = PrintBitmapBytes(bitary, bitmap.Width, bitmap.Height);

           return bl;

       }


       ///


       /// 打印图片

       ///


       ///

       ///

       public bool PrintBitmapBytes(Byte[] imgbitarray, Int32 width, Int32 height)

       {

           if (!m_Inited)

           {

               return false;

           }

           Int32 bytes = width * height / 8;

           //检查是否尺寸符合要求

           if (width > Const_MaxImageLength || height > Const_MaxFeedLength ||

               width < 1 || height < 1 ||

               imgbitarray == null)

           {

               return false;

           }

           

           //每次获取24行的数据进行发送,这24行的字节数

           Int32 blockbytes = width * Const_OncePrintRowCount / 8;

           if (blockbytes < 1)

           {

               return false;

           }


           Boolean bl = false;


           //一共需要发送的块数量

           Int32 blocks = imgbitarray.Length / blockbytes;


           //每次发送的数据字节数 = 1B 2A 21 2字节长度 + 数据内容

           Byte[] cmdbytes = new Byte[5 + blockbytes];

           //指令

           Array.Copy(Const_SetImageCommand, cmdbytes, 3);

           //数据长度,即 每行的点数

           DataFormatProcessor.Int16ToBytes(width, ref cmdbytes, 3);

           //数据内容

           for (Int32 blockidx = 0; blockidx < blocks; ++blockidx)

           {

               Array.Copy(imgbitarray, blockidx * blockbytes, cmdbytes, 5, blockbytes);

               //发送当前指令

               bl = SendCommand(cmdbytes);

               if (!bl) return false;

               //休眠20毫秒

               Thread.Sleep(20);

               //发送 打印指令

               bl = SendCommand(Const_Cmd_Print);

               if (!bl) return false;

           }


           return bl;

       }


       ///


       /// 走纸

       ///


       ///

       ///

       public bool Feed(int length)

       {

           if (!m_Inited)

           {

               return false;

           }

           if (length < 1)

               length = 1;

           if (length > Const_MaxFeedLength)

           {

               length = Const_MaxFeedLength;

           }

           string len = length.ToString("X2");

           len = Const_FeedForward + len;

           bool bl = SendCommand(len);

           return bl;

       }


       ///


       /// 回退走纸

       ///


       ///

       ///

       public bool FeedBack(int length)

       {

           if (!m_Inited)

           {

               return false;

           }

           if (length < 1)

               length = 1;

           if (length > Const_MaxFeedLength)

           {

               length = Const_MaxFeedLength;

           }

           string len = length.ToString("X2");

           len = Const_FeedBack + len;

           bool bl = SendCommand(len);

           return bl;

       }

     

       ///


       /// 设置字体大小.本函数不可与SetBigFont同时使用

       ///


       /// 大小倍率,取值范围 1 - 8

       ///

       public bool SetFontSize(Int32 sizerate)

       {

           if (!m_Inited)

           {

               return false;

           }

         

           if (sizerate < 1)

           {

               sizerate = 1;

           }


           if (sizerate > Const_MaxFontSize)

           {

               sizerate = Const_MaxFontSize;

           }

           sizerate--;

           String sizecodestr = Const_SetFontSize + sizerate.ToString("X1") + sizerate.ToString("X1");

           bool bl = SendCommand(sizecodestr);

           return bl;

       }


       #endregion


       


   }

}


3.图像处理 ImageProcessor

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Drawing;

using LaisonTech.CommonBLL;

using System.Drawing.Imaging;

using System.IO;

using System.Drawing.Drawing2D;

using System.Windows.Forms;

using AForge.Imaging.Filters;


namespace LaisonTech.MediaLib

{

   ///


   /// 图片格式

   ///


   public enum ePictureFileFormat

   {

       Bmp = 0,

       Gif = 1,

       Icon = 2,

       Jpeg = 3,

       Png = 4,

   }


   ///


   /// 转为灰度图像的方式

   ///


   public enum eGrayMode

   {

       ///


       /// 算数平均

       ///


       ArithmeticAverage = 0,

       ///


       /// 加权平均

       ///


       WeightedAverage = 1,

   }


   ///


   /// 比较2个图片的指定区域范围,像素的相同类型

   ///


   public enum eAreaDifferentType

   {

       ///


       /// 所有像素都相同

       ///


       AllSame = 0,

       ///


       /// 所有像素都不同

       ///


       AllDifferent = 1,

       ///


       /// 部分相同部分不同

       ///


       Partial = 2,

   }


   ///


   /// 图片文件处理

   ///


   public class ImageProcessor

   {

       #region 常量定义


       public const Byte Const_BrightnessWhite = 255;

       public const Byte Const_BrightnessBlack = 0;



       ///


       /// 比较结果的图片里,亮度相同部分的填充颜色

       ///


       public static Color Const_SameBrightnessColor = Color.Black;

       ///


       /// 比较结果的图片里,亮度相同部分的填充颜色

       ///


       public static Color Const_DifferentBrightnessColor = Color.White;


       public const Byte Const_BlackBrightness = 0;

       public const Byte Const_WhiteBrightness = 255;

       public const Int32 Const_MaxBrightness = 255;


       public const Int32 Const_MinBrightness = -255;


       ///


       /// 亮度的中间值

       ///


       public const Int32 Const_MiddleBrightness = 128;

       #endregion


       #region 屏幕截图,打印


       ///


       /// 获取屏幕分辨率

       ///


       ///

       ///

       public static void GetScreenSize(ref Int32 width, ref Int32 height)

       {

           height = Screen.PrimaryScreen.Bounds.Height;

           width = Screen.PrimaryScreen.Bounds.Width;

       }


       ///


       ///截图指定控件上显示的内容

       ///


       ///

       ///

       public static Image CaptureControlImage(Control ctrl)

       {

           if (ctrl == null)

           {

               return null;

           }


           Control parent = ctrl;

           if (ctrl.Parent != null)

           {

               parent = ctrl.Parent;

           }

           Point screenPoint = parent.PointToScreen(ctrl.Location);


           Image ret = new Bitmap(ctrl.Width, ctrl.Height);

           Graphics g = Graphics.FromImage(ret);

           g.CopyFromScreen(screenPoint.X, screenPoint.Y,

               0, 0, ctrl.Size);

           g.DrawImage(ret, 0, 0);


           return ret;

       }



       #endregion


       #region 装载图片


       ///


       /// 装载图像文件

       ///


       ///

       ///

       public static Image LoadImage(String filename)

       {

           //Boolean bl = FileProcessor.FileExist(filename);

           //if (!bl)

           //{

           //    return null;

           //}

           //Bitmap image = (Bitmap)Bitmap.FromFile(filename);

           //return image;


           //以上方法会导致图片文件被锁定,无法删除移动


           Byte[] photodata = null;

           Boolean bl = FileProcessor.FileExist(filename);

           if (!bl)

           {

               return null;

           }


           bl = FileProcessor.ReadFileBytes(filename, out photodata);

           if (!bl)

           {

               return null;

           }


           MemoryStream ms = null;

           Image myImage = null;

           try

           {

               ms = new MemoryStream(photodata);

               myImage = Bitmap.FromStream(ms);

               ms.Close();

           }

           catch (System.Exception ex)

           {

               Console.WriteLine("LoadImage error:" + ex.Message);

               myImage = null;

           }

           return myImage;

       }


       ///


       /// 装载图像文件

       ///


       ///

       ///

       public static Bitmap LoadBitImage(String filename)

       {

           Bitmap ret = (Bitmap)LoadImage(filename);

           return ret;

       }


       ///


       /// 保存图片到指定路径

       ///


       ///

       ///

       ///

       public static Boolean SaveImage(Image img, String filename)

       {

           FileProcessor.DeleteFile(filename);

           if (img == null)

           {

               return false;

           }

           //获取保存图片的路径,如果路径不存在,新建

           String folder = FileProcessor.GetDirectoryName(filename);

           if (!FileProcessor.DirectoryExist(folder))

           {

               FileProcessor.CreateDirectory(folder);

           }

           img.Save(filename);

           Boolean bl = FileProcessor.FileExist(filename);

           return bl;

       }


       #endregion

     

       #region 转换图片格式

     

       ///


       /// 转换图片格式

       ///


       ///

       ///

       ///

       public static Boolean BmpToJpg(String bmpfilename, String jpgfilename)

       {

           Boolean bl = ChangeFileFormat(bmpfilename, jpgfilename, ePictureFileFormat.Jpeg);

           return bl;

       }


       ///


       /// 转换图片格式

       ///


       ///

       ///

       ///

       ///

       public static Boolean ChangeFileFormat(String srcfilename, String destfilename, ePictureFileFormat destformat)

       {

           Boolean bl = FileProcessor.FileExist(srcfilename);

           if (!bl)

           {

               return false;

           }

           Image image = Image.FromFile(srcfilename);


           ImageFormat IFMT = null;

           switch (destformat)

           {

               case ePictureFileFormat.Bmp:

                   IFMT = ImageFormat.Bmp;

                   break;

               case ePictureFileFormat.Gif:

                   IFMT = ImageFormat.Gif;

                   break;

               case ePictureFileFormat.Icon:

                   IFMT = ImageFormat.Icon;

                   break;

               case ePictureFileFormat.Jpeg:

                   IFMT = ImageFormat.Jpeg;

                   break;

               case ePictureFileFormat.Png:

                   IFMT = ImageFormat.Png;

                   break;

               default:

                   IFMT = ImageFormat.Jpeg;

                   break;

           }

           image.Save(destfilename, IFMT);

           image.Dispose();


           bl = FileProcessor.FileExist(destfilename);

           if (!bl)

           {

               return false;

           }


           Int32 filelen = FileProcessor.GetFileLength(destfilename);

           return (filelen > 0);

       }


       ///


       /// 变成黑白图

       ///


       /// 原始图

       /// 模式。0:加权平均  1:算数平均

       ///

       public static Bitmap ToGray(Bitmap bitmap, eGrayMode mode = eGrayMode.ArithmeticAverage)

       {

           if (bitmap == null)

           {

               return null;

           }


           int width = bitmap.Width;

           int height = bitmap.Height;

           byte newColor = 0;

           try

           {

               BitmapData srcData = bitmap.LockBits(new Rectangle(0, 0, width, height),

                   ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

               unsafe

               {

                   byte* curpix = (byte*)srcData.Scan0.ToPointer();

                   if (mode == eGrayMode.ArithmeticAverage)// 算数平均

                   {

                       for (int y = 0; y < height; y++)

                       {

                           for (int x = 0; x < width; x++)

                           {

                               newColor = (byte)((float)(curpix[0] + curpix[1] + curpix[2]) / 3.0f);

                               curpix[0] = newColor;

                               curpix[1] = newColor;

                               curpix[2] = newColor;

                               curpix += 3;

                           }

                           curpix += srcData.Stride - width * 3;

                       }

                   }

                   else

                   {

                       // 加权平均

                       for (int y = 0; y < height; y++)

                       {

                           for (int x = 0; x < width; x++)

                           {

                               newColor = (byte)((float)curpix[0] * 0.114f + (float)curpix[1] * 0.587f + (float)curpix[2] * 0.299f);

                               curpix[0] = newColor;

                               curpix[1] = newColor;

                               curpix[2] = newColor;

                               curpix += 3;

                           }

                           curpix += srcData.Stride - width * 3;

                       }

                   }

                   bitmap.UnlockBits(srcData);

               }

           }

           catch

           {

               bitmap = null;

           }


           return bitmap;

       }