Bootstrap

Sebia蛋白电泳画图

西比亚这个东西还是有点坑的。明明仪器软件就几行代码的事,把自己图转base64串传输不就完了。非得要每个lis按他文档画图。画图也就算了,还有蛋白电泳、尿蛋白电泳、固定电泳等。画图还有差异,有的要参考区间,有的要参照先,有的要标记峰值。搞的真是难受。本身这些事是仪器自己的事,lis有什么义务给还原图,无奈市面上无底线lis太多了,行情不好。

仪器原图
在这里插入图片描述

lis还原的图
在这里插入图片描述

仪器数据

S0003                                                      000                            00000g/dl                                                                                                                                                          TS 2402202305Albumin   Alpha 1   Alpha 2   Beta      Gamma                                                       055.1003.5009.7009.0022.70000000000000000000000000000000000000000000000000000000000000000000000000001                                       015.4000.0000.0000.000000000000000000000001.2301.00                                                                                                                                                                                                                                      000300A01000079006400000000000000000000000080080008000800070007000600060005000500060006000700080009000A000A000A000A000A000A000A000A000A000A000B000B000B000B000A000A00090008000800070007000600060006000700070007000800080009000B000E00120019002300320048006A009C00E4014801D102850370049C061307CD09AC0B600C830CC40C2A0AF3097007DB065C050703E402F302310198012300CC008D00610043002E00210018001400128012001300150018001D0023002B00350041004E005D006C007A0086008E00920092008D0085007A006E00620057004D00460040003D003B803A003B003D004000440049004F00570060006B00770085009500A600B800CB00DD00ED00FC01090113011A011F0120011E0118010D00FE00EB00D400BC00A4008D007A006A005E0055004F004C004A804A004C004F0054005B006500720082009500AB00C500E100FE011B013401480153015401490136011D010000E200C300A6008C0075006100510045003C00350030002D002A00280026002400220020001E001C801B001B001C001D001F002200250028002B002F00330037003B00400045004B0052005A006400700080009400AC00CB00F0011E0156019801E30235028902D8031B0349035D0352032C02EF02A3025001FC01AB0161012000E900BD009A007F006B005C005100490043003E003B003800350032002E002A00260022001E001B00180015001300110010000F000E000D000C000B0009000800060005000400020001000000000001000200040006000700080008000900090009000A000A000A000A000A000A000A000B000D000F00108012|

仪器说明,反正很懵,不如拿具体数据说明
在这里插入图片描述

以前一直没搞明白峰值的解释,所以一直没画峰值。这次不上了。峰值那段文档的解释是结果串那些位置的串每4位表示一个坐标。数字是10进制的数,如果不足4位就把前面补0到4位。所以画图时候去了前面0得到10进制数。而这个10进制数还不是直接的x坐标。他表示的是300个点最后一个点的偏离点乘10。即x坐标由那个数字按这个公式算:drawX=300-(峰值数字/10)

C#绘图和解析结果源码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PreDeal.Interface;
using LIS.Model.Bussiness;
using LIS.DAL.DataAccess;
using PreDeal.Ftp;
using PreDeal.Attributes;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.IO;
using System.Collections;

namespace PreDeal
{
    ///<summary  NoteObject="Class">
    /// [功能描述:Sebia蛋白电泳仪的数据和图像处理,不画Z区间坐标系,画峰值,处理数据格式] <para/>
    /// [创建者:zlz] <para/>
    /// [创建时间:2023年2月25日] <para/>
    ///<说明>
    ///  [说明:Sebia蛋白电泳仪的数据和图像处理,处理数据格式
    ///  ]<para/>
    ///</说明>
    ///<修改记录>
    ///    [修改时间:2016-11-15]<para/>
    ///    S0003                                                      000                            00000g/dl                                                                                                                                                          TS 2402202305Albumin   Alpha 1   Alpha 2   Beta      Gamma                                                       055.1003.5009.7009.0022.70000000000000000000000000000000000000000000000000000000000000000000000000001                                       015.4000.0000.0000.000000000000000000000001.2301.00                                                                                                                                                                                                                                      000300A01000079006400000000000000000000000080080008000800070007000600060005000500060006000700080009000A000A000A000A000A000A000A000A000A000A000B000B000B000B000A000A00090008000800070007000600060006000700070007000800080009000B000E00120019002300320048006A009C00E4014801D102850370049C061307CD09AC0B600C830CC40C2A0AF3097007DB065C050703E402F302310198012300CC008D00610043002E00210018001400128012001300150018001D0023002B00350041004E005D006C007A0086008E00920092008D0085007A006E00620057004D00460040003D003B803A003B003D004000440049004F00570060006B00770085009500A600B800CB00DD00ED00FC01090113011A011F0120011E0118010D00FE00EB00D400BC00A4008D007A006A005E0055004F004C004A804A004C004F0054005B006500720082009500AB00C500E100FE011B013401480153015401490136011D010000E200C300A6008C0075006100510045003C00350030002D002A00280026002400220020001E001C801B001B001C001D001F002200250028002B002F00330037003B00400045004B0052005A006400700080009400AC00CB00F0011E0156019801E30235028902D8031B0349035D0352032C02EF02A3025001FC01AB0161012000E900BD009A007F006B005C005100490043003E003B003800350032002E002A00260022001E001B00180015001300110010000F000E000D000C000B0009000800060005000400020001000000000001000200040006000700080008000900090009000A000A000A000A000A000A000A000B000D000F00108012|
    ///    [修改内容:画出Z区间坐标系]<para/>
    ///</修改记录>
    ///<修改记录>
    ///    [修改时间:本次修改时间]<para/>
    ///    [修改内容:本次修改内容]<para/>
    ///</修改记录>
    ///</summary>
    [Remark(Remark = "Sebia血清蛋白电泳仪的数据和图像处理处理,画出Z区间坐标系,处理数据格式。")]
    public class DealSebiaNoLine : BaseDeal, IPreDeal, ITimer
    {


        /// <summary>
        /// 前处理,抛过来一行数据
        /// </summary>
        /// <param name="result">结果</param>
        /// <param name="machID">仪器ID</param>
        /// <param name="dealProcess">处理程序</param>
        /// <param name="index">当前文件的第几行</param>
        /// <param name="fileName">当前读取的文件全名</param>
        /// <returns></returns>
        public bool PreDeal(string result, string machID, string dealProcess, int index, string fileName)
        {
            //提前流水
            string sampleNo = result.Substring(1, 4);
            string episAll = result.Split(' ')[0];
            //去掉前面多余的0
            sampleNo =sampleNo.TrimStart(new char[] { '0' });
            string LabNo = result.Substring(5, 20);
            LabNo = LabNo.Trim();
            LabNo = LabNo.Replace(":","");
            if (LabNo != "")
            {
                sampleNo = LabNo;
            }
            //取结果值
            string value1Name = result.Substring(266, 10);
            string value1 = result.Substring(367, 5);
            string value2Name = result.Substring(276, 10);
            string value2 = result.Substring(372, 5);
            string value3Name = result.Substring(286, 10);
            string value3 = result.Substring(377, 5);
            string value4Name = result.Substring(296, 10);
            string value4 = result.Substring(382, 5);
            string value5Name = result.Substring(306, 10);
            string value5 = result.Substring(387, 5);
            string value6Name = result.Substring(316, 10);
            string value6 = result.Substring(392, 5);
            string value7Name = result.Substring(326, 10);
            string value7 = result.Substring(397, 5);
            string value8Name = result.Substring(336, 10);
            string value8 = result.Substring(402, 5);
            string value9Name = result.Substring(346, 10);
            string value9 = result.Substring(407, 5);
            string value10Name = result.Substring(356, 10);
            string value10 = result.Substring(412, 5);
            string value11 = result.Substring(557, 170).Trim();

            //取峰值,封值表示为每个坐标用4位表示。去掉前面0后当做10进制数字。这个数字不是直接坐标,要把这个数据除10后得到的是和最后一点
            //往前偏移的点数,即:去前面(300-(0的十进制数/10))就是峰值的第几个点坐标
            Hashtable hsFen = new Hashtable();
            string fen1Start = result.Substring(799, 4);
            int fen1StartNum = DealToNum(fen1Start);
            string fen1End = result.Substring(803, 4);
            int fen1EndNum = DealToNum(fen1End);
            if (fen1StartNum > 0)
            {
                for (int i = fen1StartNum; i < fen1EndNum; i++)
                {
                    if (!hsFen.ContainsKey(i))
                    {
                        hsFen.Add(i, "");
                    }
                }
            }
            string fen2Start = result.Substring(807, 4).Trim();
            int fen2StartNum = DealToNum(fen2Start);
            string fen2End = result.Substring(811, 4).Trim();
            int fen2EndNum = DealToNum(fen2End);
            if (fen2StartNum > 0)
            {
                for (int i = fen2StartNum; i < fen2EndNum; i++)
                {
                    if (!hsFen.ContainsKey(i))
                    {
                        hsFen.Add(i, "");
                    }
                }
            }
            string fen3Start = result.Substring(815, 4).Trim();
            int fen3StartNum = DealToNum(fen3Start);
            string fen3End = result.Substring(819, 4).Trim();
            int fen3EndNum = DealToNum(fen3End);
            if (fen3StartNum > 0)
            {
                for (int i = fen3StartNum; i < fen3EndNum; i++)
                {
                    if (!hsFen.ContainsKey(i))
                    {
                        hsFen.Add(i, "");
                    }
                }
            }
            string fen4Start = result.Substring(823, 4).Trim();
            int fen4StartNum = DealToNum(fen4Start);
            string fen4End = result.Substring(827, 4).Trim();
            int fen4EndNum = DealToNum(fen4End);
            if (fen4StartNum > 0)
            {
                for (int i = fen4StartNum; i < fen4EndNum; i++)
                {
                    if (!hsFen.ContainsKey(i))
                    {
                        hsFen.Add(i, "");
                    }
                }
            }

            //处理数据
            DealData(value1Name + "\\" + value1 + "," + value2Name + "\\" + value2 + "," + value3Name + "\\" + value3 + "," + value4Name + "\\" + value4 + "," + value5Name + "\\" + value5 + "," + value6Name + "\\" + value6 + "," + value7Name + "\\" + value7 + "," + value8Name + "\\" + value8 + "," + value9Name + "\\" + value9 + "," + value10Name + "\\" + value10 + ",Remark" + "\\" + value11 + ",episall\\" + episAll, machID, sampleNo, dealProcess);
            //取出图形串
            string imgStr = result.Substring(830, 1200);
            List<Dto> dataList = new List<Dto>();
            int maxY = 0;
            int max1Index = 0;
            int max1Data = 0;

            int max2Index = 0;
            int max2Data = 0;

            int max3Index = 0;
            int max3Data = 0;
            //分割点数据
            for (int i = 0; i < imgStr.Length && i < 1200; i += 4)
            {
                int startIndex = i;
                int endIndex = i + 4;
                if (endIndex > imgStr.Length)
                {
                    endIndex = imgStr.Length;
                }
                Dto dto = new Dto();
                dto.Type = imgStr.Substring(startIndex, 1);
                if (dto.Type == "4" || dto.Type == "C" || dto.Type == "1" || dto.Type == "5")
                {
                    continue;
                }
                else
                {
                    dto.Y = Convert.ToInt32(imgStr.Substring(startIndex + 1, endIndex - startIndex - 1), 16);
                }
                if (dto.Y > maxY)
                {
                    maxY = dto.Y;
                }
                if (i/4 > 135 && i/4 < 165)
                {
                    if (max1Data < dto.Y)
                    {
                        max1Data = dto.Y;
                        max1Index = i/4;
                    }
                }
                if (i/4 > 170 && i/4 < 195)
                {
                    if (max2Data < dto.Y)
                    {
                        max2Data = dto.Y;
                        max2Index = i/4;
                    }
                }
                if (i/4 > 230 && i/4 < 245)
                {
                    if (max3Data < dto.Y)
                    {
                        max3Data = dto.Y;
                        max3Index = i/4;
                    }
                }
                dataList.Add(dto);
            }
            int imgY = 580;
            //创建空位图
            Image img = new Bitmap(680, imgY);
            //获得画图句柄
            Graphics g = Graphics.FromImage(img);
            g.Clear(Color.White);
            g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            int x = 40;
            int y = 40;
            //画坐标
            Pen pen = new Pen(Color.Black);
            pen.Width = 2;
            //画横坐标线
            g.DrawLine(pen, 40, imgY - y, 640, imgY - y);
            //画下面横坐标
            for (int i = 0; i < 300; i += 15)
            {
                g.DrawLine(pen, 40 + i * 2, imgY - y, 40 + i * 2, imgY - y - 4);
                Point p = new Point(40 + i * 2, imgY - y + 3);
                Font myFont = new Font("宋体", 8, FontStyle.Regular);
                Brush bush = new SolidBrush(Color.Black);
                g.DrawString(i.ToString(), myFont, bush, p);
            }
            
            int preY = -1;
            int curindex = 0;
            //遍历点画图
            foreach (var d in dataList)
            {
                if (preY == -1)
                {
                    pen = new Pen(Color.Black);
                    pen.Width = 1;
                    g.DrawLine(pen, x, imgY - Convert.ToInt32(d.Y * (imgY - y - 65.0) / maxY) - y, x, imgY - Convert.ToInt32(d.Y * (imgY - y - 25.0) / maxY) - y);
                }
                else
                {
                    pen = new Pen(Color.Black);
                    pen.Width = 1;
                    g.DrawLine(pen, x, imgY - Convert.ToInt32(d.Y * (imgY - y - 65.0) / maxY) - y, x - 1, preY - y);
                }
                if (curindex == max1Index)
                {
                    if (value1Name != "          ")
                    {
                        Point p = new Point(x-8, imgY - Convert.ToInt32(d.Y * (imgY - y - 65.0) / maxY) - y - 20);
                        Font myFont = new Font("宋体", 12, FontStyle.Regular);
                        Brush bush = new SolidBrush(Color.Black);
                        //g.DrawString("Hb A", myFont, bush, p);
                    }
                }
                if (curindex == max2Index)
                {
                    if (value2Name != "          ")
                    {
                        Point p = new Point(x-8, imgY - Convert.ToInt32(d.Y * (imgY - y - 65.0) / maxY) - y - 20);
                        Font myFont = new Font("宋体", 12, FontStyle.Regular);
                        Brush bush = new SolidBrush(Color.Black);
                        //g.DrawString("Hb F or Hb", myFont, bush, p);
                    }
                }
                if (curindex == max3Index)
                {
                    if (value3Name!="          ")
                    {
                        Point p = new Point(x-8, imgY - Convert.ToInt32(d.Y * (imgY - y - 65.0) / maxY) - y - 20);
                        Font myFont = new Font("宋体", 12, FontStyle.Regular);
                        Brush bush = new SolidBrush(Color.Black);
                        //g.DrawString("Hb A2", myFont, bush, p);
                    }
                }
                preY = imgY - Convert.ToInt32(d.Y * (imgY - y - 65.0) / maxY);
                //画峰值阴影
                if (hsFen.ContainsKey(curindex))
                {
                    pen = new Pen(Color.Black);
                    pen.Width = 1;
                    g.DrawLine(pen, x, imgY - 40, x, preY - y);
                }
                x += 2;
                curindex++;
            }
            //存图
            img.Save(Application.StartupPath + "\\temp\\" + sampleNo + ".bmp");
            string ftpPath = "";
            //得到ftp
            FtpService ftp = GetFtpHelper(machID, dealProcess, out ftpPath);
            //上传图片
            ftp.Upload(Application.StartupPath + "\\temp\\" + sampleNo + ".bmp");
            System.IO.FileInfo fInfo = new System.IO.FileInfo(Application.StartupPath + "\\temp\\" + sampleNo + ".bmp");
            System.IO.File.Delete(Application.StartupPath + "\\temp\\" + sampleNo + ".bmp");
            //保存图片
            SaveImg(machID, sampleNo, "Sebia", ftpPath.Split('^')[3] + fInfo.Name, dealProcess, episAll);
            return false;
        }

        /// <summary>
        /// 峰值处理成坐标
        /// </summary>
        /// <param name="numStr"></param>
        /// <returns></returns>
        private int DealToNum(string numStr)
        {
            string res = "";
            for (int i = 0; i < numStr.Length; i++)
            {
                if (numStr[i] == '0' && res == "")
                {
                    continue;
                }
                res += numStr[i];
            }
            if (res != "")
            {
                return 300 - Convert.ToInt32(res) / 10;
            }
            return 0;
        }



        /// <summary>
        /// 处理数据库数据
        /// </summary>
        /// <param name="row">当前行数据</param>
        /// <param name="machID">仪器ID</param>
        /// <param name="dealProcess">处理程序</param>
        /// <param name="index">当前数据的第几行</param>
        /// <param name="otherPara">其他参数</param>
        /// <returns></returns>
        public bool PreDealDataBase(System.Data.DataRow row, string machID, string dealProcess, int index, string otherPara)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 定时执行
        /// </summary>
        /// <param name="machID"></param>
        /// <param name="dealProcess"></param>
        public void Action(string machID, string dealProcess)
        {
            //按流水号取图上传,路径不带最后的\
            string OtherPara = Flag.DealFlag.GetConfigStr(machID, "OtherPara");
            if (OtherPara != null && OtherPara != "")
            {
                string[] picList = OtherPara.Split(',');
                foreach (var picPath in picList)
                {
                    LIS.Core.Util.LogUtils.WriteDebugLog("检测目录:" + picPath + "下的图片");
                    //血清图片存储
                    if (Directory.Exists(picPath))
                    {
                        LIS.Core.Util.LogUtils.WriteDebugLog("检测到目录:" + picPath);
                        string[] picPaths = Directory.GetFiles(picPath, "*.jpeg");
                        string[] picPaths1 = Directory.GetFiles(picPath, "*.jpg");
                        string ftpPath = "";
                        LIS.Core.Util.LogUtils.WriteDebugLog("目录包含:" + picPaths.Length + "个图片");
                        try
                        {
                            if (picPaths.Length > 0)
                            {
                                //得到ftp
                                FtpService ftp = GetFtpHelper(machID, dealProcess, out ftpPath);
                                foreach (string picFile in picPaths)
                                {
                                    FileInfo fInfo = new FileInfo(picFile);
                                    //上传图片
                                    ftp.Upload(picFile);
                                    LIS.Core.Util.LogUtils.WriteDebugLog(picFile + "上传成功!");
                                    //保存图片
                                    SaveImg(machID, fInfo.Name, "P", ftpPath.Split('^')[3] + fInfo.Name, dealProcess);
                                    LIS.Core.Util.LogUtils.WriteDebugLog(picFile + "保存成功!");
                                    //删除图片
                                    System.IO.File.Delete(picFile);
                                    LIS.Core.Util.LogUtils.WriteDebugLog(picFile + "删除成功!");
                                }
                            }
                            if (picPaths1.Length > 0)
                            {
                                //得到ftp
                                FtpService ftp = GetFtpHelper(machID, dealProcess, out ftpPath);
                                foreach (string picFile in picPaths1)
                                {
                                    FileInfo fInfo = new FileInfo(picFile);
                                    //上传图片
                                    ftp.Upload(picFile);
                                    LIS.Core.Util.LogUtils.WriteDebugLog(picFile + "上传成功!");
                                    //保存图片
                                    SaveImg(machID, fInfo.Name, "P", ftpPath.Split('^')[3] + fInfo.Name, dealProcess);
                                    LIS.Core.Util.LogUtils.WriteDebugLog(picFile + "保存成功!");
                                    //删除图片
                                    System.IO.File.Delete(picFile);
                                    LIS.Core.Util.LogUtils.WriteDebugLog(picFile + "删除成功!");
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            LIS.Core.Util.LogUtils.WriteDebugLog("上传图片异常:" + ex.Message);
                        }
                    }
                    else
                    {
                        LIS.Core.Util.LogUtils.WriteDebugLog("不存在目录:" + picPath + "不做图片上传");
                    }
                }
            }
            else
            {
                LIS.Core.Util.LogUtils.WriteDebugLog("未配置:OtherPara图片目录不做图片上传");
            }
        }

        /// <summary>
        /// 内部数据实体
        /// </summary>
        private class Dto
        {
            /// <summary>
            /// 类型
            /// </summary>
            public string Type
            {
                get;
                set;
            }

            /// <summary>
            /// Y坐标
            /// </summary>
            public int Y
            {
                get;
                set;
            }
        }
    }
}

把经验分享给大家,没必要内耗在这种事上

;