using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Runtime.InteropServices; using System.Windows.Forms; namespace DNScanner.Scan { /** * 华高扫描实现 * **/ class HgScan { [DllImport("hgscannersdk.dll", EntryPoint = "HG_Init", CallingConvention = CallingConvention.Cdecl)] public static extern void HG_Init(); [DllImport("hgscannersdk.dll", EntryPoint = "HG_CloseScanner", CallingConvention = CallingConvention.Cdecl)] public static extern void HG_CloseScanner(); [DllImport("hgscannersdk.dll", EntryPoint = "HG_GetDevices", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern IntPtr HG_GetDevices(string sep); [DllImport("hgscannersdk.dll", EntryPoint = "HG_OpenScanner", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern IntPtr HG_OpenScanner(string deviceName); [DllImport("hgscannersdk.dll", EntryPoint = "HG_StartScan", CallingConvention = CallingConvention.Cdecl)] public static extern int HG_StartScan(IntPtr handle, int count); [DllImport("hgscannersdk.dll", EntryPoint = "HG_StopScan", CallingConvention = CallingConvention.Cdecl)] public static extern int HG_StopScan(IntPtr handle); [DllImport("hgscannersdk.dll", EntryPoint = "HG_Set_Scan_Params", CallingConvention = CallingConvention.Cdecl)] public static extern int HG_Set_Scan_Params(IntPtr handle, HG_SCANPARAMS param); [DllImport("hgscannersdk.dll", EntryPoint = "HG_Get_Scan_Params", CallingConvention = CallingConvention.Cdecl)] public static extern int HG_Get_Scan_Params(IntPtr handle, ref HG_SCANPARAMS param); [DllImport("hgscannersdk.dll", EntryPoint = "HG_Set_AquireImg_callback", CallingConvention = CallingConvention.Cdecl)] public static extern void HG_Set_AquireImg_callback(HG_OnImage_Callback callBack, IntPtr obj); [DllImport("hgscannersdk.dll", EntryPoint = "HG_Set_OnDeviceEvent_callback", CallingConvention = CallingConvention.Cdecl)] public static extern void HG_Set_OnDeviceEvent_callback(HG_OnDevice_Event_Callback callBack, IntPtr obj); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void HG_OnImage_Callback(IntPtr img, IntPtr obj); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void HG_OnDevice_Event_Callback(HG_STATUSCODE code, IntPtr obj); public enum HG_PAPERTYPE { HG_None = 0, HG_A4Letter = 1, HG_A4 = 1, HG_B5Letter = 2, HG_JISB5 = 2, HG_B5 = 2, HG_USLetter = 3, HG_USLegal = 4, HG_A5 = 5, HG_B4 = 6, HG_ISOB4 = 6, HG_B6 = 7, HG_ISOB6 = 7, HG_USLedger = 9, HG_USExecutive = 10, HG_A3 = 11, HG_B3 = 12, HG_ISOB3 = 12, HG_A6 = 13, HG_C4 = 14, HG_C5 = 15, HG_C6 = 16, HG__4A0 = 17, HG__2A0 = 18, HG_A0 = 19, HG_A1 = 20, HG_A2 = 21, HG_A7 = 22, HG_A8 = 23, HG_A9 = 24, HG_A10 = 25, HG_ISOB0 = 26, HG_ISOB1 = 27, HG_ISOB2 = 28, HG_ISOB5 = 29, HG_ISOB7 = 30, HG_ISOB8 = 31, HG_ISOB9 = 32, HG_ISOB10 = 33, HG_JISB0 = 34, HG_JISB1 = 35, HG_JISB2 = 36, HG_JISB3 = 37, HG_JISB4 = 38, HG_JISB6 = 39, HG_JISB7 = 40, HG_JISB8 = 41, HG_JISB9 = 42, HG_JISB10 = 43, HG_C0 = 44, HG_C1 = 45, HG_C2 = 46, HG_C3 = 47, HG_C7 = 48, HG_C8 = 49, HG_C9 = 50, HG_C10 = 51, HG_USStatement = 52, HG_MaxSize = 54, }; public enum HG_FILTER { HG_FILTER_RED, /* 除红色 */ HG_FILTER_GREEN, /* 除绿色 */ HG_FILTER_BLUE, /* 除蓝色 */ HG_FILTER_NONE, /* 无除色 */ HG_FILTER_ALL, /* 全除色 */ HG_ENHANCE_RED, /* 红色增强 */ HG_ENHANCE_GREEN, /* 绿色增强 */ HG_ENHANCE_BLUE /* 蓝色增强 */ }; public enum HG_COLORMODE { HG_BlackWhite, /* 黑白 */ HG_Gray, /* 灰度 */ HG_RGB /* 彩色 */ }; public enum HG_MULTIOUTPUT { HG_Unused = -1, /* 无 */ HG_All, /* 彩色+灰度+黑白 */ HG_ColorGray, /* 彩色+灰度 */ HG_ColorBw, /* 彩色+黑白 */ HG_GrayBw /* 灰度+黑白 */ }; /*缓存文件格式*/ public enum HG_CACHEIMGFORMAT { HG_CJPG, HG_CPNG, HG_CBMP, HG_CTIFF }; public enum HG_PAPERALIGN { HG_Rot0 = 0, /* 纵向 */ HG_Rot270 = 3 /* 横向 */ }; public enum HG_SHARPENTYPE { HG_STNone, /* 无滤镜 */ HG_Sharpen, /* 锐化 */ HG_SharpenMore, /* 锐化加强 */ HG_Blur, /* 模糊 */ HG_BlurMore /* 模糊加强 */ }; public enum HG_ORENTATION { HG_ROTATE_NONE = 0, /* 无旋转 */ HG_ROTATE_90, /* 旋转逆时针90度 */ HG_ROTATE_180, /* 旋转180度 */ HG_ROTATE_270, /* 旋转顺时针90度 */ HG_AUTOTEXT_DETECT /* 文稿方向识别 */ }; public enum HG_STATUSCODE { HG_STATUS_SCANNING = 1, /* 正在扫描 */ HG_STATUS_SCANSTOP, /* 扫描停止 */ HG_STATUS_NO_FEED, /* 无纸 */ HG_STATUS_COVEROPEN, /* 开盖 */ HG_STATUS_FEED_IN_ERROR, /* 馈纸错误 */ HG_STATUS_PAPER_JAM, /* 卡纸 */ HG_STATUS_DETECT_STAPLE, /* 订书钉 */ HG_STATUS_DETECT_DOUBLE_FEED, /* 双张 */ HG_STATUS_DETECT_SIZECHECKERROR, /* 尺寸检测错误 */ HG_STATUS_PAPER_SKEW, /* 纸张歪斜 */ HG_STATUS_USBCONNECT, /* 设备已连接 */ HG_STATUS_USBDISCONNECT, /* 设备未连接 */ HG_STATUS_USBERROR /* USB错误 */ }; public enum HG_TRANSFERMODE { HG_XFERMEMORY, /* 内存保存图像信息 */ HG_XFERFILE /* 图像文件保存图像信息 */ }; [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct HG_FILLHOLE { public int enable; /* 使能:开启该功能为true;关闭该功能为false */ public int ratio; /* 穿孔搜索范围(从边缘到页面中心比例):1~50,对应1%~50% */ }; [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct HG_HARDWARECAPS { public int capturepixtype; /* 颜色模式 */ public int doubleFeedDetection; /* 双张检测 */ public int bindingDetection; /* 订书钉检测 */ }; [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct HG_SCANSIDE { public int Duplex; /* 1: both ; 0: front */ public int DiscardBlank; /* 跳过空白页通用 0:disable 1: enbale */ public int DiscardBlankVince; /* 跳过空白页(发票)0:disable 1: enbale */ public int Fold; /* 对折 0:disable 1: enbale */ public int SwitchFrontBack; /* 互换正反面 0:disable 1: enbale */ }; [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct HG_IMG { public int width; /* 像素宽度 */ public int height; /* 像素高度 */ public int bitdepth; /* 位深 */ public IntPtr pimgdata; /* 数据指针 */ public int bytesperline; /* 每行数据长度 */ public int bufferlength; /*bmp buffer 长度*/ }; [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct HG_IMAGEPROCESS { public int AutoCrop; /* 自动裁剪尺寸 */ public int Brightness; /* 1~255 */ public int Contrast; /* 1~7 */ public float Gamma; /* 0.1f~5.0f */ public int FillBlackRect; /* 消除黑框 */ public int AutoDescrew; /* 自动纠偏 */ public int RefuseInflow; /* 防止渗透 */ public HG_FILLHOLE FillHole; /* 填穿孔参数 */ public HG_FILTER Filter; /* 除色与颜色增强 */ public int ColorCorrection; /* 色彩校正 */ public int RemoveMorr; /* 去除摩尔纹 */ public int ErrorExtention; /* 错误扩散 */ public int NosieDetach; /* 噪点优化 */ public int NosieDetachEnable; /* 噪点优化使能 */ public int TextureRemove; /* 除网纹 */ public int Indent; /* 边缘缩进像素 */ public int Noise; /* 降噪像素点 */ public int AutoCrop_threshold; /* 自动裁剪二值化阀值 */ public bool Is_convex; /* 填充黑框方式 */ public HG_SHARPENTYPE SharpenType; /* 滤镜类型 */ public int MultiOutFilterRed; /* 多流输出除红 */ public int AnswerSheetFilterRed; /* 答题卡除红 */ public HG_ORENTATION Orentation; /* 图像旋转 */ public int BackRotate180; /* 背面旋转180 */ public int SplitImage; /* 图像拆分 */ public int DiscardBlankThre; /* 跳过空白页阈值 */ }; [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct HG_SCANPARAMS { public HG_COLORMODE PixelType; /* 色彩:彩色/灰度/黑白 */ public HG_MULTIOUTPUT MultiOutput; /* 多流输出:彩色+灰度+黑白 */ public HG_PAPERTYPE PaperSize; /* 幅面 */ public HG_PAPERALIGN PaperAlign; /* 文档方向 */ public HG_CACHEIMGFORMAT CacheFormat; /* 缓存图像格式*/ public int Resolution; /* 分辨率:100/150/200/300/600 */ public HG_SCANSIDE ScanSide; /* 正反面:正面/正反双面 */ public HG_IMAGEPROCESS ImageProcess; /* 图像处理 */ public HG_HARDWARECAPS HardwareParam; /* 硬件参数 */ }; private string selectedScanner; private IntPtr scannerHandle = IntPtr.Zero; private static HG_OnImage_Callback imageCallback = new HG_OnImage_Callback(ImageCallback); private static HG_OnDevice_Event_Callback deviceCallback = new HG_OnDevice_Event_Callback(DeviceCallback); public int initDriver() { HG_Init(); return 0; } public int unloadDriver() { HG_CloseScanner(); scannerHandle = IntPtr.Zero; return 0; } public void initInstance() { string aa = ","; var ret = HG_GetDevices(aa); selectedScanner = Marshal.PtrToStringAnsi(ret); } public void initSetting() { } /// /// 热效参数设置 /// public int TimelySetParams() { if (scannerHandle == IntPtr.Zero) { HG_Set_OnDeviceEvent_callback(deviceCallback, IntPtr.Zero); if (selectedScanner == null) return -1; scannerHandle = HG_OpenScanner(selectedScanner); if (scannerHandle == IntPtr.Zero) { return -1; } } HG_SCANPARAMS scanParams = new HG_SCANPARAMS(); int retVal = HG_Get_Scan_Params(scannerHandle, ref scanParams); if (retVal != 0) { return retVal; } //HG_SCANPARAMS scanParams = (HG_SCANPARAMS)Marshal.PtrToStructure(param, typeof(HG_SCANPARAMS)); //设置当前使用的配置项 scanParams.PixelType = HG_COLORMODE.HG_RGB; scanParams.MultiOutput = HG_MULTIOUTPUT.HG_Unused; scanParams.PaperSize = HG_PAPERTYPE.HG_None; scanParams.PaperAlign = (HG_PAPERALIGN.HG_Rot0); scanParams.ImageProcess.AutoCrop = 1; int resolution = 200; scanParams.Resolution = resolution; int duplex = 1; scanParams.ScanSide.Duplex = duplex; scanParams.ImageProcess.FillBlackRect = 1; scanParams.ImageProcess.AutoDescrew = 1; scanParams.HardwareParam.doubleFeedDetection = 1; scanParams.HardwareParam.bindingDetection = 1; scanParams.ImageProcess.AutoCrop_threshold = 40; retVal = HG_Set_Scan_Params(scannerHandle, scanParams); if (retVal != 0) { return retVal; } return retVal; } static int imgindex = 0; public static void ImageCallback(IntPtr img, IntPtr obj) { // { //logger.Debug("Image callback invoked."); } if (img == IntPtr.Zero) { return; } HG_IMG image = (HG_IMG)Marshal.PtrToStructure(img, typeof(HG_IMG)); // { //logger.Debug("The result for image is: width -> " + image.width + ", height -> " + image.height + ", bitdepth -> " + image.bitdepth + ", bytesperline -> " + image.bytesperline); } if (image.height == 0 || image.width == 0 || image.bitdepth == 0) { //r.IsErrorEnabled) { //logger.Error("Image is invalid."); } return; } string destFileName = "aa.tiff"; // 从图像数据生成文件 byte[] data = new byte[image.bufferlength]; Marshal.Copy(image.pimgdata, data, 0, image.bufferlength); //for (int i = 0; i < 12; i++) //{ // //logger.Debug("Byte content is: " + data[i]); //} var ptr= Marshal.UnsafeAddrOfPinnedArrayElement(data, 0); // Bitmap bmp; //using (var stream = new MemoryStream(data)) //{ // bmp = new Bitmap(stream); /* System.Drawing.Imaging.Encoder myEncoder; EncoderParameter myEncoderParameter; EncoderParameters myEncoderParameters; ImageCodecInfo myImageCodecInfo = ImageCodecInfo.GetImageDecoders()[0]; //设置图像颜色深度参数colordepth为8位,并加入到编码器参数parameters中 myEncoder = System.Drawing.Imaging.Encoder.Compression; myEncoderParameters = new EncoderParameters(1); myEncoderParameter = new EncoderParameter(myEncoder, 95); myEncoderParameters.Param[0] = myEncoderParameter;*/ // bmp.Save((imgindex++).ToString() + ".jpg"); //bmp.Save((imgindex++).ToString() + ".jpg", ImageFormat.Bmp); //} System.IO.MemoryStream ms = new System.IO.MemoryStream(data); System.Drawing.Image img1 = System.Drawing.Image.FromStream(ms); //保存到磁盘文件 string imagePath = System.IO.Path.Combine(); // if (!System.IO.Directory.Exists(imagePath)) // System.IO.Directory.CreateDirectory(imagePath); img1.Save(System.IO.Path.Combine(imagePath, (imgindex++).ToString() + ".jpg"), System.Drawing.Imaging.ImageFormat.Jpeg); ms.Dispose(); // MessageBox.Show("图片已保存至:" + m_ImagrRootDir); //bmp.Save(imgindex.ToString() + ".bmp", ImageFormat.Bmp); //bmp.Save(destFileName, ImageFormat.Tiff); // { //logger.Debug("Save scan result into file: " + destFileName); } // 通过图像路径地址显示 } public static void DeviceCallback(HG_STATUSCODE code, IntPtr obj) { switch (code) { case HG_STATUSCODE.HG_STATUS_SCANNING: break; case HG_STATUSCODE.HG_STATUS_SCANSTOP: break; case HG_STATUSCODE.HG_STATUS_NO_FEED: MessageBox.Show("没有纸"); break; case HG_STATUSCODE.HG_STATUS_COVEROPEN: break; case HG_STATUSCODE.HG_STATUS_FEED_IN_ERROR: MessageBox.Show("进纸错误"); break; case HG_STATUSCODE.HG_STATUS_PAPER_JAM: MessageBox.Show("卡纸"); break; case HG_STATUSCODE.HG_STATUS_DETECT_STAPLE: MessageBox.Show("检测到订书钉"); break; case HG_STATUSCODE.HG_STATUS_DETECT_DOUBLE_FEED: MessageBox.Show("检测到双页进纸"); break; case HG_STATUSCODE.HG_STATUS_DETECT_SIZECHECKERROR: break; case HG_STATUSCODE.HG_STATUS_PAPER_SKEW: MessageBox.Show("纸张歪斜"); break; case HG_STATUSCODE.HG_STATUS_USBCONNECT: break; case HG_STATUSCODE.HG_STATUS_USBDISCONNECT: break; case HG_STATUSCODE.HG_STATUS_USBERROR: break; default: break; } } public int scanExec() { TimelySetParams(); HG_Set_AquireImg_callback(imageCallback, IntPtr.Zero); // 输入参数 -1: 连续扫描 >=1: 指定页数 int retVal = HG_StartScan(scannerHandle, -1); if (retVal != 0) { MessageBox.Show("扫描时发生错误,错误码: " + retVal); } return retVal; } public int stopscan() { // 重置扫描状态 int retVal = HG_StopScan(scannerHandle); if (retVal != 0) { } // HG_CloseScanner(); // scannerHandle = IntPtr.Zero; return retVal; ; } protected int scanCancel() { // 重置扫描状态 int retVal = HG_StopScan(scannerHandle); if (retVal != 0) { } HG_CloseScanner(); scannerHandle = IntPtr.Zero; return retVal; } } }