WebWork.cs 7.0 KB
using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.IO;
using HalconDotNet;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using System.Text;
using System.Drawing;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

namespace ScanCodeServer
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple, IncludeExceptionDetailInFaults = false, UseSynchronizationContext = false)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    internal class WebWork : IWeb
    {
        public WebWork()
        {
        }

        public Result TakeOldGet(string place)
        {
            Common.log.Info("takeOld[GET] place=" + place);
            return TakeOld(place);
        }
        public string alive() {
            return "1";
        }
        public string ProcessBitmap(Stream info, string param)
        {
            BinaryFormatter bf = new BinaryFormatter();
            Bitmap bitmap = (Bitmap)bf.Deserialize(info);
            HDCodeHelper.Bitmap2HObjectBpp24(bitmap, out HObject ho_Image);
            //bitmap.Dispose();
            return Process(ho_Image, bitmap, GetRemoteDecodeParam(param));
        }
        public string Process(Stream info, string param)
        {
            HObject ho_Image = HObject.Deserialize(info);
            return Process(ho_Image,null, GetRemoteDecodeParam(param));
        }
        object o = new object();
        string Process(HObject ho_Image,Bitmap bitmap, RemoteDecodeParam remoteDecodeParam)
        {
            string[] codeTypeList = remoteDecodeParam.codeTypeList;
            int codeCount = remoteDecodeParam.codeCount;
            int timeout = remoteDecodeParam.timeout;
            Common.log.Info($"参数:codeTypeList:{string.Join(",",codeTypeList)}, codeCount:{codeCount}, timeout:{timeout}");
            Result res = new Result();

            List<string> code = new List<string>();
            Task[] t = new Task[codeTypeList.Length];
            int ti = 0;
            foreach (string codeType in codeTypeList)
            {
                t[ti] = Task.Run(() =>
                {
                    lock (o)
                    {
                        Monitor.ScanTimes++;
                    }
                    try
                    {
                        List<CodeInfo> cc = new List<CodeInfo>();
                        //判断是否是一维码
                        if (codeType.ToLower().Equals("barcode"))
                        {
                            cc = HDCodeHelper.DecodeBarCode(ho_Image);
                        }
                        else if (codeType.ToLower().StartsWith("eyem") && bitmap != null)
                        {
                            var b = DeepClone(bitmap);
                            cc = EyemDecode2.Decoder(ref b);
                            b.Dispose();
                        }
                        else
                        {
                            cc = HDCodeHelper.DecodeCode(ho_Image, codeType, HDCodeHelper.GetCodeParamFilePath(codeType), codeCount, timeout);
                        }
                        if (cc != null)
                        {
                            foreach (CodeInfo c in cc)
                            {
                                c.CodeType = codeType;
                                c.CodeStr = RemoveInvalidXMLChars(c.CodeStr);
                                //c.CodeStr = "<![CDATA[" + c.CodeStr+"]]";
                                lock (code)
                                {
                                    if (!code.Contains(c.CodeStr))
                                    {
                                        Common.log.Info("识别到:" + c.CodeType + ", " + c.CodeStr);
                                        code.Add(c.CodeStr);
                                        res.CodeInfos.Add(c);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Common.log.Error(ex.ToString());
                    }
                    finally
                    {

                    }
                });
                ti++;
            }
            Task.WaitAll(t,1000*10);
            ho_Image.Dispose();
            if (bitmap != null)
                bitmap.Dispose();
            using (MemoryStream respStream = new MemoryStream())
            {
                XmlSerializer xff = new XmlSerializer(typeof(List<CodeInfo>));
                xff.Serialize(respStream, res.CodeInfos);
                Monitor.Test();
                return Convert.ToBase64String(respStream.ToArray());
            }
        }

        RemoteDecodeParam GetRemoteDecodeParam(string param) {

            param = param.Replace('-', '+').Replace('_', '/');
            var stream = Convert.FromBase64String(param);
            MemoryStream mStream = new MemoryStream(stream);
            XmlSerializer xf = new XmlSerializer(typeof(RemoteDecodeParam));
            RemoteDecodeParam remoteDecodeParam = (RemoteDecodeParam)xf.Deserialize(mStream);
            mStream.Close();
            return remoteDecodeParam;
        }

        private Result TakeOld(string place)
        {
            Result res = new Result();
            return res;
        }

        public static T DeepClone<T>(T _object)
        {
            try
            {
                T dstobject;
                using (MemoryStream mStream = new MemoryStream())
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(mStream, _object);
                    mStream.Seek(0, SeekOrigin.Begin);//指定当前流的位置为流的开头。
                    dstobject = (T)bf.Deserialize(mStream);
                    mStream.Close();
                }
                return dstobject;
            }
            catch (Exception e)
            {
                Common.log.Error("DeepClone" + e.ToString());
                return default;
            }
        }

        // filters control characters but allows only properly-formed surrogate sequences
        private static Regex _invalidXMLChars = new Regex(
            @"(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F\uFEFF\uFFFE\uFFFF]",
            RegexOptions.Compiled);

        /// <summary>
        /// removes any unusual unicode characters that can't be encoded into XML
        /// </summary>
        public static string RemoveInvalidXMLChars(string text)
        {
            if (string.IsNullOrEmpty(text)) return "";
            return _invalidXMLChars.Replace(text, "");
        }
    }
    public struct RemoteDecodeParam
    {
        public string[] codeTypeList;
        public int codeCount;
        public int timeout;
    }

}