HDCodeHelper.cs 13.9 KB
using HalconDotNet; 
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CodeLibrary
{ 
    public class HDCodeHelper
    {
        /// <summary>
        /// 二维码参数文件保存的默认路径\CodeParam\
        /// </summary>
        public static string CodeParamPath = @"\CodeParam\";
        /// <summary>
        /// 显示的窗口
        /// </summary>
        public static HWindow HalconWindow = null;

        /// <summary>
        /// 根据图片路径解析二维码
        /// </summary>
        /// <param name="filePath">图片路径</param>
        /// <param name="codeCount">二维码数量</param>
        /// <param name="codeParamPath">二维码参数路径,""表示不使用参数</param>
        /// <param name="paramType">二维码类型,不传类型默认Data Matrix ECC 200</param>
        /// <returns>解析到的二维码</returns>
        public static List<CodeInfo> DecodeCode(string filePath, int codeCount, string codeParamPath, params string[] paramType)
        {
            HObject ho_Image;
            HOperatorSet.GenEmptyObj(out ho_Image);
            ho_Image.Dispose();
            HOperatorSet.ReadImage(out ho_Image, filePath);
            if (HalconWindow != null)
            {
                HOperatorSet.DispObj(ho_Image, HalconWindow);
            }
            return DecodeCode(ho_Image, codeCount, codeParamPath, paramType);
        }
        /// <summary>
        /// 根据图片解析二维码
        /// </summary>
        /// <param name="map">图片对象</param>
        /// <param name="codeCount">二维码数量</param>
        /// <param name="codeParamPath">二维码参数路径,""表示不使用参数</param>
        /// <param name="paramType">二维码类型,不传类型默认Data Matrix ECC 200</param>
        /// <returns>解析到的二维码</returns>
        public static List<CodeInfo> DecodeCode(Bitmap map, int codeCount, string codeParamPath, params string[] paramType)
        {
            HObject ho_image = Bitmap2HObjectBpp24(map);
            return DecodeCode(ho_image, codeCount, codeParamPath, paramType);
        }
        /// <summary>
        /// 根据图片解析二维码
        /// </summary>
        /// <param name="ho_Image">Halcon中的图片对象</param>
        /// <param name="codeCount">二维码数量</param>
        /// <param name="codeParamPath">二维码参数路径,""表示不使用参数</param>
        /// <param name="paramType">二维码类型,不传类型默认Data Matrix ECC 200</param>
        /// <returns>解析到的二维码</returns>
        public static List<CodeInfo> DecodeCode(HObject ho_Image, int codeCount, string codeParamPath, params string[] paramType)
        {
            List<string> codeType = new List<string>(paramType.ToList());
            if (codeType.Count<string>() <= 0)
            {
                codeType.Add("Data Matrix ECC 200");
            }
            List<CodeInfo> codeList = new List<CodeInfo>();

            foreach (string t in codeType)
            {
                List<CodeInfo> array = DecodeCode(ho_Image, t, codeParamPath, codeCount);
                codeList.AddRange(array.ToArray<CodeInfo>());
            }
            return codeList;
        }
        public static List<CodeInfo> DecodeCode(HObject ho_Image, string symbolType, string hv_model_path, int codeCount,int timeOut=2000)
        {
            HDLogUtil.info(" DecodeCode[" + symbolType + "][" + hv_model_path + "][" + codeCount + "] 开始");
            List<CodeInfo> codeList = new List<CodeInfo>();
            try
            {
                HTuple hv_Area = null;
                HTuple hv_Row1 = null;
                HTuple hv_Column = null;
                HTuple hv_PointOrder = null;
                HObject ho_SymbolXLDs;

                HTuple hv_ResultHandles = null;
                HTuple hv_DecodedDataStrings = null;
                HTuple hv_DataCodeHandle = null;
                HOperatorSet.GenEmptyObj(out ho_SymbolXLDs);
                HOperatorSet.CreateDataCode2dModel(symbolType, "default_parameters", "maximum_recognition", out hv_DataCodeHandle);

                //string hv_model_path = GetCodeParamFilePath(symbolType);
                if (!hv_model_path.Equals("") && File.Exists(hv_model_path))
                {
                    HOperatorSet.ReadDataCode2dModel(hv_model_path, out hv_DataCodeHandle);
                }
            //    HOperatorSet.SetDataCode2dParam(hv_DataCodeHandle, "timeout", 3000);
                ho_SymbolXLDs.Dispose();
                // set_data_code_2d_param(DataCodeHandle, 'timeout', 200)
                HOperatorSet.SetDataCode2dParam(hv_DataCodeHandle, "timeout", timeOut);
                if (codeCount <= 0)
                {
                    HOperatorSet.FindDataCode2d(ho_Image, out ho_SymbolXLDs, hv_DataCodeHandle,
                    new HTuple(), new HTuple(), out hv_ResultHandles, out hv_DecodedDataStrings);
                }
                else
                {
                    HOperatorSet.FindDataCode2d(ho_Image, out ho_SymbolXLDs, hv_DataCodeHandle,
                    "stop_after_result_num", codeCount, out hv_ResultHandles, out hv_DecodedDataStrings);
                }
                HOperatorSet.AreaCenterXld(ho_SymbolXLDs, out hv_Area, out hv_Row1, out hv_Column, out hv_PointOrder);
                if (HalconWindow != null)
                {
                    ShowImage(HalconWindow, ho_Image, ho_SymbolXLDs);
                }
                HOperatorSet.ClearDataCode2dModel(hv_DataCodeHandle);

                if (hv_DecodedDataStrings.Length > 0)
                {
                    string[] resultList = hv_DecodedDataStrings.SArr;
                    for (int i = 0; i < hv_DecodedDataStrings.SArr.Length; i++)
                    {
                        try
                        {
                            int x = (int)Math.Round(hv_Column.DArr[i]);
                            int y = (int)Math.Round(hv_Row1.DArr[i]);
                            string str = hv_DecodedDataStrings.SArr[i];
                            CodeInfo code = new CodeInfo(str, x, y);
                            codeList.Add(code);
                        }
                        catch (Exception ex)
                        {
                            HDLogUtil.error("处理二维码出错:索引=" + i + "," + resultList.ToString());
                        }
                    }
                }
                HDLogUtil.info(" DecodeCode[" + symbolType + "][" + hv_model_path + "][" + codeCount + "] 结束,返回数量:"+codeList.Count);
                return codeList;
            }
            catch (Exception ex)
            {
                HDLogUtil.error("DecodeCode出错:" + ex.ToString());
                HDLogUtil.info(" DecodeCode[" + symbolType + "][" + hv_model_path + "][" + codeCount + "] 结束,返回数量:" + codeList.Count);
                return codeList;
            }
            
        }
        internal static void ShowImage(HWindow window, HObject ho_Image, HObject ho_SymbolXLDs)
        {
            if (window == null || ho_Image == null)
            {
                return;
            }
            Task.Factory.StartNew(delegate ()
            {
                try
                {

                    HTuple width, height;
                    //int dWidth = 0; int dHeight = 0;
                    HOperatorSet.GetImageSize(ho_Image, out width, out height);

                    int dWidth = (int)width.D;
                    int dHeight = (int)height.D;
                    window.SetPart(0, 0, dHeight, dWidth);

                    HOperatorSet.SetColor(window, "red");
                    HOperatorSet.SetLineWidth(window, new HTuple(2));
                    if (ho_Image != null)
                    {
                        HOperatorSet.DispObj(ho_Image, window);
                    }
                    if (ho_SymbolXLDs != null)
                    {
                        HOperatorSet.DispObj(ho_SymbolXLDs, window);
                    }
                }
                catch (Exception ex)
                {

                }
            });
        }
        /// <summary>
        /// 将BitMap转换为HObject对象
        /// </summary> 
        public static HObject Bitmap2HObjectBpp24(Bitmap bmp)
        {
            HObject ho_Image = null;
            try
            {
                HOperatorSet.GenEmptyObj(out ho_Image);
                ho_Image.Dispose();
                Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

                BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);
                HOperatorSet.GenImageInterleaved(out ho_Image, srcBmpData.Scan0, "bgrx", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0);
                bmp.UnlockBits(srcBmpData);

            }
            catch (Exception ex)
            {
                HDLogUtil.error("将BitMap转换为HObject对象出错:" +  ex.ToString());
                ho_Image = null;
            }
            return ho_Image;
        }

        internal static string GetCodeParamFilePath(string codeType)
        {
            if (CodeParamPath.Equals(""))
            {
                CodeParamPath = @"\CodeParam\";
            }
            string appPath = Application.StartupPath + CodeParamPath;
            if (!Directory.Exists(appPath))
            {
                Directory.CreateDirectory(appPath);
            }

            string filePath = appPath + codeType + ".dcm";
            return filePath;
        }
        public static List<CodeInfo> DecodeBarCode(string filePath)
        {
            HObject ho_Image;
            HOperatorSet.GenEmptyObj(out ho_Image);
            ho_Image.Dispose();
            HOperatorSet.ReadImage(out ho_Image, filePath);
            return DecodeBarCode(ho_Image);
        }
        public static List<CodeInfo> DecodeBarCode(Bitmap bitmap)
        {
            HObject ho_image = Bitmap2HObjectBpp24(bitmap);
            return DecodeBarCode(ho_image);
        }
       
        public static List<CodeInfo> DecodeBarCode(HObject ho_Image)
        {
            List<CodeInfo> codeList = new List<CodeInfo>();
            try
            {
                HObject ho_GrayImage, ho_SymbolRegions;
                HTuple hv_BarCodeHandle = null, hv_DecodedDataStrings = null, hv_DecodedDataTypes = null; ;
                HOperatorSet.GenEmptyObj(out ho_GrayImage);
                HOperatorSet.GenEmptyObj(out ho_SymbolRegions);

                HTuple hv_Area = null;
                HTuple hv_Row1 = null;
                HTuple hv_Column = null;
                HTuple hv_Orientation = null;
                HOperatorSet.Rgb1ToGray(ho_Image, out ho_GrayImage);
                HOperatorSet.GenEmptyObj(out ho_SymbolRegions);
                ho_SymbolRegions.Dispose();

                HOperatorSet.CreateBarCodeModel(new HTuple(), new HTuple(), out hv_BarCodeHandle);

                HOperatorSet.FindBarCode(ho_GrayImage, out ho_SymbolRegions, hv_BarCodeHandle, "auto", out hv_DecodedDataStrings);
                //HOperatorSet.AreaCenterXld(ho_SymbolRegions, out hv_Area, out hv_Row1, out hv_Column, out hv_PointOrder);
                HOperatorSet.GetBarCodeResult(hv_BarCodeHandle, "all", "decoded_types", out hv_DecodedDataTypes);
                HOperatorSet.GetBarCodeResult(hv_BarCodeHandle, "all", "orientation", out hv_Orientation);
                HOperatorSet.AreaCenter(ho_SymbolRegions, out hv_Area, out hv_Row1, out hv_Column);
                if (HalconWindow != null)
                { 
                    HOperatorSet.SetDraw(HalconWindow, "margin");
                    ShowImage(HalconWindow, ho_Image, ho_SymbolRegions); 
                }

                string[] resultList = hv_DecodedDataStrings.SArr;
                if (resultList.Length > 0)
                {
                    for (int i = 0; i < hv_DecodedDataStrings.SArr.Length; i++)
                    {
                        try
                        {
                            int x = (int)Math.Round(hv_Column.DArr[i]);
                            int y = (int)Math.Round(hv_Row1.DArr[i]);
                            string str = hv_DecodedDataStrings.SArr[i];
                            string type = hv_DecodedDataTypes.SArr[i];
                            CodeInfo code = new CodeInfo(str, x, y, type);
                            code.Orientation = hv_Orientation.DArr[i];
                            codeList.Add(code);
                            if (HalconWindow != null)
                            {
                                HOperatorSet.SetTposition(HalconWindow, new HTuple(x), new HTuple(y));
                                HOperatorSet.WriteString(HalconWindow,new HTuple ( "(" + (i + 1).ToString() + ")")); 
                            }
                        }
                        catch (Exception ex)
                        {
                            HDLogUtil.error("处理一维码出错:索引=" + i + "," + resultList.ToString());
                        }
                    }
                }
                HOperatorSet.ClearBarCodeModel(hv_BarCodeHandle);
             
                return codeList;
            }
            catch (Exception ex)
            {
                return codeList;
            }
        }
    }
    
   
 
public class CodeInfo
    {
        public string CodeStr = "";
        public int X = 0;
        public int Y = 0;
        public string CodeType;
        public double Orientation = 0;
        public CodeInfo(string codeStr,int x,int y)
        {
            this.CodeStr = codeStr;
            this.X = x;
            this.Y = y;
        }
        public CodeInfo(string codeStr, int x, int y,string type)
        {
            this.CodeType = type;
            this.CodeStr = codeStr;
            this.X = x;
            this.Y = y;
        }
    }
}