eyemDecode.cs 6.1 KB
using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace CodeLibrary
{
    public unsafe class EyemDecode
    {
        /// <summary>
        /// 识别图像二维码
        /// </summary>
        /// <param name="bmap">需要手动释放这个bitmap</param>
        /// <returns></returns>
        public static List<CodeInfo> Decoder(ref Bitmap bmap,string file=null)
        {
            List<CodeInfo> codelist = new List<CodeInfo>();

            try
            {
                //创建图像引用
                           
                EyemImage eyemImage;
                BitmapData bitmapData = null;
                if (file == null)
                {
                    Rectangle rect = new Rectangle(0, 0, bmap.Width, bmap.Height);
                    bitmapData = bmap.LockBits(rect, ImageLockMode.ReadOnly, bmap.PixelFormat);
                    eyemImage = new EyemImage();
                    eyemImage.ucpImage = bitmapData.Scan0;
                    eyemImage.iWidth = rect.Width;
                    eyemImage.iHeight = rect.Height;
                    eyemImage.iChannel = 0;
                }
                else {
                    eyemImageRead(file, 3, out eyemImage);
                }
                
                //创建扫描区域
                EyemRect eyemRect = new EyemRect();
                eyemRect.iXs = 0;
                eyemRect.iYs = 0;
                eyemRect.iWidth = eyemImage.iWidth;
                eyemRect.iHeight = eyemImage.iHeight;
                string codeType = "QR_CODE|DATA_MATRIX";//QRCode

                int ipNum;
                EyemBarCode* tpResults;
                DataCodeHandle hObject = null;
                try
                {
                    int result = eyemDetectAndDecode(eyemImage, eyemRect, "", codeType, out hObject, out tpResults, out ipNum, false, 11, 5, 128, 215);
                    HDLogUtil.info($"eyemDetectAndDecode:{result},ipNum:{ipNum}");
                    if (result != 0 || ipNum == 0)
                        return codelist;

                    for (int i = 0; i < ipNum; i++)
                    {
                        CodeInfo ci = new CodeInfo(Marshal.PtrToStringAnsi(tpResults[i].hText), tpResults[i].iCenterX, tpResults[i].iCenterY);
                        ci.CodeType = Marshal.PtrToStringAnsi(tpResults[i].hType);
                        codelist.Add(ci);
                    }
                }
                finally
                {
                    if (hObject != null)
                        hObject.Dispose();
                    if (bitmapData!=null)
                        bmap.UnlockBits(bitmapData);
                    if (file != null)
                        eyemImageFree(eyemImage.ucpImage);
                    //bmap.Dispose();
                }
            }
            catch (Exception ex)
            {
                HDLogUtil.error(ex.ToString());
            }
            //eyemImageFree(eyemImage.ucpImage);
            return codelist;
        }
        //释放解码句柄
        private class DataCodeHandle : SafeHandleZeroOrMinusOneIsInvalid
        {
            public DataCodeHandle() : base(true) { }
            protected override bool ReleaseHandle()
            {
                return eyemDetectAndDecodeFree(handle);
            }
        }
        [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
        private static extern int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, string fileName, string strCodeType, out DataCodeHandle hObject, out EyemBarCode* tpResults, out int ipNum, bool bUseNiBlack, int iBlockSize, int iRangeC, int iSymbolMin, int iSymbolMax, double dScaleUpAndDown=1, double dToleErr = 0.5, double dMinorStep = 1.0);

        /// <summary>
        /// 读取图像
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="iFalgs"></param>
        /// <param name="ucpImage"></param>
        /// <returns></returns>
        [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
        private static extern int eyemImageRead(string filename, int iFalgs, out EyemImage ucpImage);

        /// <summary>
        /// 释放图像资源
        /// </summary>
        /// <param name="ipImage"></param>
        [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
        private static extern void eyemImageFree(IntPtr ipImage);

        //释放工具
        [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
        private static extern bool eyemDetectAndDecodeFree(IntPtr hObject);

        [StructLayout(LayoutKind.Sequential)]
        public struct EyemImage
        {
            public IntPtr ucpImage;                    // 地址
            public int iWidth;                         // 图像内存 x 方向大小
            public int iHeight;                        // 图像内存 y 方向大小
            public int iChannel;                       // 图像通道数
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct EyemRect
        {
            public int iXs;                            // 起始点(左上角) x 坐标
            public int iYs;                            // 起始点(左上角) y 坐标
            public int iWidth;                         // x 方向大小(宽度)
            public int iHeight;                        // y 方向大小(高度)
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct EyemBarCode
        {
            public double dAngle;                      // 角度
            public int iCenterX;                       // y坐标
            public int iCenterY;                       // y坐标
            public IntPtr hType;                       // 码类型
            public IntPtr hText;                       // 码内容
        }
    }

}