using MvCodeReaderSDKNet;
using System.Runtime.InteropServices;
using System.Text;
namespace Aucma.Core.Scanner
{
///
/// 扫码器初始化
///
public class ScannerService : IScannerService
{
int nRet = MvCodeReader.MV_CODEREADER_OK;
MvCodeReader device = new MvCodeReader();
public ScannerService()
{
}
public async Task StartScannerAsync()
{
await StartServer();
}
#region 获取设备个数
///
/// 获取设备个数
///
///
public Task GetDevNum()
{
MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST stDevList = new MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST();
nRet = MvCodeReader.MV_CODEREADER_EnumDevices_NET(ref stDevList, MvCodeReader.MV_CODEREADER_GIGE_DEVICE);
if (MvCodeReader.MV_CODEREADER_OK != nRet)
{
Console.WriteLine("Enum device failed:{0:x8}", nRet);
return Task.FromResult(0);
}
int deviceNum = Convert.ToInt32(stDevList.nDeviceNum);
return Task.FromResult(deviceNum);
}
#endregion
#region 获取设备列表
///
/// 获取设备个数
///
///
public MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST GetDevList()
{
MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST stDevList = new MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST();
nRet = MvCodeReader.MV_CODEREADER_EnumDevices_NET(ref stDevList, MvCodeReader.MV_CODEREADER_GIGE_DEVICE);
return stDevList;
}
#endregion
#region 获取设备信息
///
/// 获取设备个数
///
///
public async Task GetDevInfo()
{
List list=new List();
byte[] chUserDefinedName = null;
MvCodeReader.MV_CODEREADER_DEVICE_INFO stDevInfo;// 通用设备信息
MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST stDevList = GetDevList();
int deviceNum =await GetDevNum();
for (int i = 0; i < deviceNum; i++)
{
stDevInfo = (MvCodeReader.MV_CODEREADER_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[i], typeof(MvCodeReader.MV_CODEREADER_DEVICE_INFO));
if (MvCodeReader.MV_CODEREADER_GIGE_DEVICE == stDevInfo.nTLayerType)
{
MvCodeReader.MV_CODEREADER_GIGE_DEVICE_INFO stGigEDeviceInfo = (MvCodeReader.MV_CODEREADER_GIGE_DEVICE_INFO)MvCodeReader.ByteToStruct(stDevInfo.SpecialInfo.stGigEInfo, typeof(MvCodeReader.MV_CODEREADER_GIGE_DEVICE_INFO));
uint nIp1 = ((stGigEDeviceInfo.nCurrentIp & 0xff000000) >> 24);
uint nIp2 = ((stGigEDeviceInfo.nCurrentIp & 0x00ff0000) >> 16);
uint nIp3 = ((stGigEDeviceInfo.nCurrentIp & 0x0000ff00) >> 8);
uint nIp4 = (stGigEDeviceInfo.nCurrentIp & 0x000000ff);
//chUserDefinedName = Encoding.GetEncoding("GB2312").GetBytes(stGigEDeviceInfo.chUserDefinedName);
chUserDefinedName = System.Text.Encoding.Default.GetBytes(stGigEDeviceInfo.chUserDefinedName);
string strUserDefinedName = Encoding.UTF8.GetString(chUserDefinedName);
Console.WriteLine("\n" + i.ToString() + ": [GigE] User Define Name : " + strUserDefinedName);
Console.WriteLine("device IP :" + nIp1 + "." + nIp2 + "." + nIp3 + "." + nIp4);
}
else if (MvCodeReader.MV_CODEREADER_USB_DEVICE == stDevInfo.nTLayerType)
{
MvCodeReader.MV_CODEREADER_USB3_DEVICE_INFO stUsb3DeviceInfo = (MvCodeReader.MV_CODEREADER_USB3_DEVICE_INFO)MvCodeReader.ByteToStruct(stDevInfo.SpecialInfo.stUsb3VInfo, typeof(MvCodeReader.MV_CODEREADER_USB3_DEVICE_INFO));
//chUserDefinedName = Encoding.GetEncoding("GB2312").GetBytes(stUsb3DeviceInfo.chUserDefinedName);
chUserDefinedName = System.Text.Encoding.Default.GetBytes(stUsb3DeviceInfo.chUserDefinedName);
string strUserDefinedName = Encoding.UTF8.GetString(chUserDefinedName);
Console.WriteLine("\n" + i.ToString() + ": [U3V] User Define Name : " + strUserDefinedName);
Console.WriteLine("\n 序列号 : " + stUsb3DeviceInfo.chSerialNumber);
Console.WriteLine("\n 设备号 : " + stUsb3DeviceInfo.nDeviceNumber);
}
}
}
#endregion
public Task StartServer()
{
do
{
// ch:枚举设备 | en:Enum device
MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST stDevList = new MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST();
nRet = MvCodeReader.MV_CODEREADER_EnumDevices_NET(ref stDevList, MvCodeReader.MV_CODEREADER_GIGE_DEVICE);
if (MvCodeReader.MV_CODEREADER_OK != nRet)
{
Console.WriteLine("枚举设备失败:{0:x8}", nRet);
continue;
}
int deviceNum = Convert.ToInt32(stDevList.nDeviceNum);
Console.WriteLine("Enum device count : " + Convert.ToString(stDevList.nDeviceNum));
if (0 == stDevList.nDeviceNum)
{
continue;
}
MvCodeReader.MV_CODEREADER_DEVICE_INFO stDevInfo; // 通用设备信息
byte[] chUserDefinedName = null;
// ch:打印设备信息 en:Print device info
for (Int32 i = 0; i < stDevList.nDeviceNum; i++)
{
stDevInfo = (MvCodeReader.MV_CODEREADER_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[i], typeof(MvCodeReader.MV_CODEREADER_DEVICE_INFO));
if (MvCodeReader.MV_CODEREADER_GIGE_DEVICE == stDevInfo.nTLayerType)
{
MvCodeReader.MV_CODEREADER_GIGE_DEVICE_INFO stGigEDeviceInfo = (MvCodeReader.MV_CODEREADER_GIGE_DEVICE_INFO)MvCodeReader.ByteToStruct(stDevInfo.SpecialInfo.stGigEInfo, typeof(MvCodeReader.MV_CODEREADER_GIGE_DEVICE_INFO));
uint nIp1 = ((stGigEDeviceInfo.nCurrentIp & 0xff000000) >> 24);
uint nIp2 = ((stGigEDeviceInfo.nCurrentIp & 0x00ff0000) >> 16);
uint nIp3 = ((stGigEDeviceInfo.nCurrentIp & 0x0000ff00) >> 8);
uint nIp4 = (stGigEDeviceInfo.nCurrentIp & 0x000000ff);
//chUserDefinedName = Encoding.GetEncoding("GB2312").GetBytes(stGigEDeviceInfo.chUserDefinedName);
chUserDefinedName = System.Text.Encoding.Default.GetBytes(stGigEDeviceInfo.chUserDefinedName);
string strUserDefinedName = Encoding.UTF8.GetString(chUserDefinedName);
Console.WriteLine("\n" + i.ToString() + ": [GigE] 用户定义名称 : " + strUserDefinedName);
Console.WriteLine("设备IP:" + nIp1 + "." + nIp2 + "." + nIp3 + "." + nIp4);
}
else if (MvCodeReader.MV_CODEREADER_USB_DEVICE == stDevInfo.nTLayerType)
{
MvCodeReader.MV_CODEREADER_USB3_DEVICE_INFO stUsb3DeviceInfo = (MvCodeReader.MV_CODEREADER_USB3_DEVICE_INFO)MvCodeReader.ByteToStruct(stDevInfo.SpecialInfo.stUsb3VInfo, typeof(MvCodeReader.MV_CODEREADER_USB3_DEVICE_INFO));
//chUserDefinedName = Encoding.GetEncoding("GB2312").GetBytes(stUsb3DeviceInfo.chUserDefinedName);
chUserDefinedName = System.Text.Encoding.Default.GetBytes(stUsb3DeviceInfo.chUserDefinedName);
string strUserDefinedName = Encoding.UTF8.GetString(chUserDefinedName);
Console.WriteLine("\n" + i.ToString() + ": [U3V] 用户定义名称 : " + strUserDefinedName);
Console.WriteLine("\n 序列号 : " + stUsb3DeviceInfo.chSerialNumber);
Console.WriteLine("\n 设备号 : " + stUsb3DeviceInfo.nDeviceNumber);
}
}
int nDevIndex = 0;
stDevInfo = (MvCodeReader.MV_CODEREADER_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[nDevIndex], typeof(MvCodeReader.MV_CODEREADER_DEVICE_INFO));
// ch:创建设备 | en:Create device
nRet = device.MV_CODEREADER_CreateHandle_NET(ref stDevInfo);
if (MvCodeReader.MV_CODEREADER_OK != nRet)
{
Console.WriteLine("创建设备失败:{0:x8}", nRet);
continue;
}
// ch:打开设备 | en:Open device
nRet = device.MV_CODEREADER_OpenDevice_NET();
if (MvCodeReader.MV_CODEREADER_OK != nRet)
{
Console.WriteLine("打开设备失败:{0:x8}", nRet);
continue;
}
// ch:设置触发模式为off || en:set trigger mode as off
if (MvCodeReader.MV_CODEREADER_OK != device.MV_CODEREADER_SetEnumValue_NET("TriggerMode", 0))
{
Console.WriteLine("设置触发模式失败!");
continue;
}
// ch:开启抓图 | en:start grab
nRet = device.MV_CODEREADER_StartGrabbing_NET();
if (MvCodeReader.MV_CODEREADER_OK != nRet)
{
Console.WriteLine("启动抓取失败:{0:x8}", nRet);
continue;
}
int nCount = 0;
IntPtr pBufForDriver = IntPtr.Zero;
MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2 stFrameInfo = new MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2();
IntPtr pstFrameInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2)));
Marshal.StructureToPtr(stFrameInfo, pstFrameInfo, false);
//while (nCount++ != 20)
//{
nRet = device.MV_CODEREADER_GetOneFrameTimeoutEx2_NET(ref pBufForDriver, pstFrameInfo, 1000);
// ch:获取一帧图像 | en:Get one image
if (MvCodeReader.MV_CODEREADER_OK == nRet)
{
stFrameInfo = (MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2)Marshal.PtrToStructure(pstFrameInfo, typeof(MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2));
Console.WriteLine("获取一帧:" + "nChannelID[" + Convert.ToString(stFrameInfo.nChannelID) + "] , Width[" + Convert.ToString(stFrameInfo.nWidth) + "], Height[" + Convert.ToString(stFrameInfo.nHeight)
+ "] , FrameNum[" + Convert.ToString(stFrameInfo.nFrameNum) + "]");
// 分配条码内存空间
MvCodeReader.MV_CODEREADER_RESULT_BCR_EX2 stBcrResult = (MvCodeReader.MV_CODEREADER_RESULT_BCR_EX2)Marshal.PtrToStructure(stFrameInfo.UnparsedBcrList.pstCodeListEx2, typeof(MvCodeReader.MV_CODEREADER_RESULT_BCR_EX2));
//String strCode = System.Text.Encoding.Default.GetString(stBcrResultEx2.stBcrInfoEx2[i].chCode);
Console.WriteLine("获取CodeNum:" + "CodeNum[" + Convert.ToString(stBcrResult.nCodeNum) + "]");
for (int i = 0; i < stBcrResult.nCodeNum; ++i)
{
bool bIsValidUTF8 = IsTextUTF8(stBcrResult.stBcrInfoEx2[i].chCode);
if (bIsValidUTF8)
{
string strCode = System.Text.Encoding.Default.GetString(stBcrResult.stBcrInfoEx2[i].chCode);
// string strCode = Encoding.UTF8.GetString(stBcrResult.stBcrInfoEx2[i].chCode);
Console.WriteLine("Get CodeNum: " + "CodeNum[" + i.ToString() + "], CodeString[" + strCode.Trim().TrimEnd('\0') + "]");
}
else
{
//string strCode = Encoding.GetEncoding("GB2312").GetString(stBcrResult.stBcrInfoEx2[i].chCode);
string strCode = System.Text.Encoding.Default.GetString(stBcrResult.stBcrInfoEx2[i].chCode);
Console.WriteLine("Get CodeNum: " + "CodeNum[" + i.ToString() + "], CodeString[" + strCode.Trim().TrimEnd('\0') + "]");
}
}
MvCodeReader.MV_CODEREADER_OCR_INFO_LIST stOcrInfo = (MvCodeReader.MV_CODEREADER_OCR_INFO_LIST)Marshal.PtrToStructure(stFrameInfo.UnparsedOcrList.pstOcrList, typeof(MvCodeReader.MV_CODEREADER_OCR_INFO_LIST));
Console.WriteLine("ocrAllNum[" + Convert.ToString(stOcrInfo.nOCRAllNum) + "]");
for (int i = 0; i < stOcrInfo.nOCRAllNum; i++)
{
//string strOcrCharCode = Encoding.UTF8.GetString(stOcrInfo.stOcrRowInfo[i].chOcr);
string strOcrCharCode = System.Text.Encoding.Default.GetString(stOcrInfo.stOcrRowInfo[i].chOcr);
Console.WriteLine("Get OcrInfo:" + "ocrNum[" + i.ToString() + "], ocrLen[" + Convert.ToString(stOcrInfo.stOcrRowInfo[i].nOcrLen) + "], ocrChar[" + strOcrCharCode.Trim().TrimEnd('\0') + "]");
}
}
else
{
Console.WriteLine("没有数据:{0:x8}", nRet);
continue;
}
//}
// ch:停止抓图 | en:Stop grab image
nRet = device.MV_CODEREADER_StopGrabbing_NET();
if (MvCodeReader.MV_CODEREADER_OK != nRet)
{
Console.WriteLine("停止抓取失败{0:x8}", nRet);
continue;
}
} while (false);
return Task.CompletedTask;
}
#region 销毁设备
///
/// 销毁设备
///
public void Destroy()
{
// ch:关闭设备 | en:Close device
nRet = device.MV_CODEREADER_CloseDevice_NET();
if (MvCodeReader.MV_CODEREADER_OK != nRet)
{
Console.WriteLine("关闭设备失败{0:x8}", nRet);
}
// ch:销毁设备 | en:Destroy device
nRet = device.MV_CODEREADER_DestroyHandle_NET();
if (MvCodeReader.MV_CODEREADER_OK != nRet)
{
Console.WriteLine("销毁设备失败:{0:x8}", nRet);
}
if (MvCodeReader.MV_CODEREADER_OK != nRet)
{
// ch:销毁设备 | en:Destroy device
nRet = device.MV_CODEREADER_DestroyHandle_NET();
if (MvCodeReader.MV_CODEREADER_OK != nRet)
{
Console.WriteLine("销毁设备失败:{0:x8}", nRet);
}
}
}
#endregion
#region 判断字符编码
///
/// 判断字符编码
///
///
///
public static bool IsTextUTF8(byte[] inputStream)
{
int encodingBytesCount = 0;
bool allTextsAreASCIIChars = true;
for (int i = 0; i < inputStream.Length; i++)
{
byte current = inputStream[i];
if ((current & 0x80) == 0x80)
{
allTextsAreASCIIChars = false;
}
// First byte
if (encodingBytesCount == 0)
{
if ((current & 0x80) == 0)
{
// ASCII chars, from 0x00-0x7F
continue;
}
if ((current & 0xC0) == 0xC0)
{
encodingBytesCount = 1;
current <<= 2;
// More than two bytes used to encoding a unicode char.
// Calculate the real length.
while ((current & 0x80) == 0x80)
{
current <<= 1;
encodingBytesCount++;
}
}
else
{
// Invalid bits structure for UTF8 encoding rule.
return false;
}
}
else
{
// Following bytes, must start with 10.
if ((current & 0xC0) == 0x80)
{
encodingBytesCount--;
}
else
{
// Invalid bits structure for UTF8 encoding rule.
return false;
}
}
}
if (encodingBytesCount != 0)
{
// Invalid bits structure for UTF8 encoding rule.
// Wrong following bytes count.
return false;
}
// Although UTF8 supports encoding for ASCII chars, we regard as a input stream, whose contents are all ASCII as default encoding.
return !allTextsAreASCIIChars;
}
#endregion
}
}