546 lines
20 KiB
C#
546 lines
20 KiB
C#
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()
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 热效参数设置
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
}
|