迈瑞的几个仪器出图需要画图,搞的很费劲,没办法,厂商自己不改,明明有图发Base64串的,就非两个图要自己画,画的方法又描述不清。每个LIS厂商都要浪费很多时间,没什么必要浪费在这种没意义的事情上,共有5800系列,BC3000系列,2600系列,分享给大家。
示例代码和程序
6800型号
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LIS.BLL.ImageCore;
using System.Drawing;
using System.Data;
using System.IO;
using System.Drawing.Drawing2D;
namespace LIS.Mach.ImageDeal
{
///<summary NoteObject="Class">
/// [功能描述:M调用绘图测试] <para/>
/// [创建者:zlz] <para/>
/// [创建时间:2018年03月22日] <para/>
///<说明>
/// [说明:[功能描述:M调用绘图测试,配合M处理仪器绘图]<para/>
///</说明>
///<修改记录>
/// [修改时间:本次修改时间]<para/>
/// [修改内容:本次修改内容]<para/>
///</修改记录>
///<修改记录>
/// [修改时间:本次修改时间]<para/>
/// [修改内容:本次修改内容]<para/>
/// M端触发代码,其他的和监听程序一样
/// s retObj=##Class(wbsLisMsgAsyncHandler.LISMsg.wbsLisDrawImageAsyncHandlerSoap).%New()
/// s ret=retObj.DrawImage("1","绘图数据","仪器","处理M","传输次数","其他参数","LIS.Mach.ImageDeal.ImageDealTest,LIS.Mach.ImageDeal")
/// s ret=$$DealImage^MI.MIF000(epis,"RBC绘图数据串",mi,"和监听一样的有保存图片的M类","-1","Histogram#RBC#RBC######10#10#320#138","LIS.Mach.ImageDeal.Imagebc6800,LIS.Mach.ImageDeal")
/// s ret=$$DealImage^MI.MIF000(epis,"RBC带背景绘图数据串",mi,"和监听一样的有保存图片的M类","-1","Histogram#RBC#RBCH.bmp######10#10#320#138","LIS.Mach.ImageDeal.Imagebc6800,LIS.Mach.ImageDeal")
/// s ret=$$DealImage^MI.MIF000(epis,"PLT绘图数据串",mi,"和监听一样的有保存图片的M类","-1","Histogram#PLT#PLT######10#10#320#138","LIS.Mach.ImageDeal.Imagebc6800,LIS.Mach.ImageDeal")
/// s ret=$$DealImage^MI.MIF000(epis,"PLT带背景绘图数据串",mi,"和监听一样的有保存图片的M类","-1","Histogram#PLT#PLT.bmp######10#10#320#138","LIS.Mach.ImageDeal.Imagebc6800,LIS.Mach.ImageDeal")
/// s ret=$$DealImage^MI.MIF000(epis,"DIFF绘图数据串",mi,"和监听一样的有保存图片的M类","-1","DiffPlot#DIFF#######10#10#320#138","LIS.Mach.ImageDeal.Imagebc6800,LIS.Mach.ImageDeal")
/// s ret=$$DealImage^MI.MIF000(epis,"Baso绘图数据串",mi,"和监听一样的有保存图片的M类","-1","DiffPlot#Baso#######10#10#320#138","LIS.Mach.ImageDeal.Imagebc6800,LIS.Mach.ImageDeal")
///</修改记录>
///</summary>
public class Imagebc6800 : IDrawImage
{
/// <summary>
/// 绘图方法
/// </summary>
/// <param name="epis">流水号</param>
/// <param name="result">结果</param>
/// <param name="machID">仪器ID</param>
/// <param name="dealProcess">处理M</param>
/// <param name="index">-1认为传到最后</param>
/// <param name="otherPara">其他参数</param>
/// <param name="dealClass">C#处理类格式:类全名,不带后缀的动态库名</param>
/// <returns>是否成功</returns>
public bool DrawImage(string epis, string result, string machID, string dealProcess, string index, string otherPara, string dealClass)
{
//string epis = row["Epis"].ToString();
//1.1从其他参数中获取所需要的参数
string[] paraList = otherPara.Split('#');
string graphType = "";
string imgClass = "";
string label = "";
string title = "";
string maxDot = "";
string maxValue = "";
string memo = "";
string foreColor = "";
string top = "";
string left = "";
string width = "";
string height = "";
if (paraList.Length > 1)
{
graphType = paraList[0];
imgClass = paraList[1];
}
else
{
return true;
}
if (paraList.Length > 11)
{
title = paraList[2];
label = paraList[3];
maxDot = paraList[4];
maxValue = paraList[5];
memo = paraList[6];
foreColor = paraList[7];
top = paraList[8];
left = paraList[9];
width = paraList[10];
height = paraList[11];
}
//#2.1校验必要参数是否存在
if (String.IsNullOrEmpty(width))
{
width = "330";
}
if (String.IsNullOrEmpty(height))
{
height = "140";
}
if (String.IsNullOrEmpty(foreColor))
{
foreColor = "0";
}
//#2.2取得画图所需要的元素
double imageWidth = Convert.ToDouble(width);
double imageHeight = Convert.ToDouble(height);
//#2.3分不同类型的图形来进行绘图
//画直方图
if (graphType == "Histogram")
{
//先把串转比特数组
byte[] imageBytes = Convert.FromBase64String(result);
float[] dot = new float[imageBytes.Length];
int imgMaxDot = 0;
float imgMaxValue = 0;
for (int j = 0; j < imageBytes.Length; j++)
{
dot[j] = imageBytes[j];
if (dot[j] > imgMaxValue)
{
imgMaxValue = dot[j];
}
imgMaxDot++;
}
Bitmap image = null;
//使用背景画图
if (title == "PLT.bmp" || title == "RBCH.bmp")
{
image = CreateImage(title, imgMaxValue, dot, null);
}
else
{
Dictionary<int, string> xshow = new Dictionary<int, string>();
if (imgClass == "RBC")
{
xshow.Add(10, "0");
xshow.Add(60, "50");
xshow.Add(110, "100");
xshow.Add(160, "150");
xshow.Add(210, "200");
xshow.Add(260, "250");
xshow.Add(310, "fL");
}
if (imgClass == "PLT")
{
xshow.Add(10, "0");
xshow.Add(50, "5");
xshow.Add(100, "10");
xshow.Add(150, "15");
xshow.Add(200, "20");
xshow.Add(250, "25");
xshow.Add(300, "fL");
}
//按十进制结果画图
Histogram histogram = new Histogram(label, title, imgMaxDot, imgMaxValue, foreColor, Convert.ToInt32(width), Convert.ToInt32(height), xshow);
histogram.Values = dot;
image = histogram.CreateImage();
}
//判断C盘trak是否存在
string tmpPath = @"c:\trak\tmpMach";
if (!Directory.Exists("C:\\trak"))
{
Directory.CreateDirectory("C:\\trak"); //新建文件夹
if (!Directory.Exists(tmpPath))
{
Directory.CreateDirectory(tmpPath); //新建文件夹
}
}
//先删除临时目录里面的所有文件
DeleteFolder(tmpPath);
image.Save(tmpPath + "\\" + imgClass + epis + ".bmp");
image.Dispose();
string ftpPath = "";
//FtpService ftp = GetFtpHelper(machID, dealProcess, out ftpPath);
//上传图片
//ftp.Upload(tmpPath + "\\" + imgClass + epis + ".bmp");
//保存图片
//SaveImg(machID, epis, imgClass, ftpPath.Split('^')[3] + imgClass + epis + ".bmp", dealProcess);
}
//散点图就是图片的Base64串表示,直接还原
else if (graphType == "DiffPlot")
{
Bitmap image = null;
try
{
byte[] arr = Convert.FromBase64String(result);
MemoryStream ms = new MemoryStream(arr);
image = new Bitmap(ms);
ms.Dispose();
ms.Close();
Bitmap imgTMP = new Bitmap(image.Width, image.Height);
Graphics g = Graphics.FromImage(imgTMP);
g.DrawImage(image, 0, 0, image.Width, image.Height);
image.Dispose();
image = imgTMP;
//判断C盘trak是否存在
string tmpPath = @"c:\trak\tmpMach";
if (!Directory.Exists("C:\\trak"))
{
Directory.CreateDirectory("C:\\trak"); //新建文件夹
if (!Directory.Exists(tmpPath))
{
Directory.CreateDirectory(tmpPath); //新建文件夹
}
}
//先删除临时目录里面的所有文件
DeleteFolder(tmpPath);
//反转底色
GraphUtil.GrayReverse(image);
image.Save(tmpPath + "\\" + imgClass + epis + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
image.Dispose();
string ftpPath = "";
//FtpService ftp = GetFtpHelper(machID, dealProcess, out ftpPath);
//上传图片
//ftp.Upload(tmpPath + "\\" + imgClass + epis + ".bmp");
//保存图片
//SaveImg(machID, epis, imgClass, ftpPath.Split('^')[3] + imgClass + epis + ".bmp", dealProcess);
}
catch (Exception ex)
{
throw new Exception("Base64String到图片转换失败\n异常:"+ex.Message);
}
}
return true;
}
/// 清空指定的文件夹,但不删除文件夹
/// </summary>
/// <param name="dir"></param>
public static void DeleteFolder(string dir)
{
foreach (string d in Directory.GetFileSystemEntries(dir))
{
if (File.Exists(d))
{
FileInfo fi = new FileInfo(d);
if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1)
fi.Attributes = FileAttributes.Normal;
File.Delete(d);//直接删除其中的文件
}
else
{
DirectoryInfo d1 = new DirectoryInfo(d);
if (d1.GetFiles().Length != 0)
{
DeleteFolder(d1.FullName);递归删除子文件夹
}
Directory.Delete(d);
}
}
}
/// <summary>
/// 获得图片流
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public Stream GetImageStram(string name)
{
return this.GetType().Assembly.GetManifestResourceStream("iMedicalLISBCIMage.Image." + name);
}
/// <summary>
/// 画图逻辑
/// </summary>
public Bitmap CreateImage(string bgName, float MaxValue, float[] Values, Bitmap imageold)
{
//#1.画坐标系,先简单画两条线,暂时不做细节
Bitmap img = null;
//#1.2获得画图句柄
Graphics g = null;
if (imageold != null)
{
img = imageold;
g = Graphics.FromImage(img);
}
else
{
Image imgtmp = Image.FromStream(GetImageStram(bgName)) as Bitmap;
img = new Bitmap(imgtmp.Width, imgtmp.Height);
g = Graphics.FromImage(img);
g.Clear(Color.White);
//+抗锯齿
g.SmoothingMode = SmoothingMode.AntiAlias;
g.DrawImage(imgtmp, 0, 0, img.Width, img.Height);
}
int Height = img.Height;
//#1.3偏移
int x = 1;
int y = 20;
//画横纵坐标线
Pen pen = new Pen(Color.Black);
pen.Width = 2;
//#3.开始进点的数据,进行绘图
double radix = (img.Width - 30) * 1.0 / Values.Length;
if (Values.Length == 256)
{
radix = radix * 2;
}
float preY = -1;
int curindex = 0;
double radiy = 1;
if (MaxValue != 0)
{
radiy = (Height - 40) * 1.0 / MaxValue;
}
foreach (var d in Values)
{
if (preY == -1)
{
pen = new Pen(Color.Black);
pen.Width = 1;
}
else
{
pen = new Pen(Color.Black);
pen.Width = 1;
if (10 + x * radix > img.Width)
{
continue;
}
if (Height - d * radiy - y > img.Height || Height - d * radiy - y < 0)
{
continue;
}
g.DrawLine(pen, 10 + (int)(x * radix), Height - (int)(d * radiy) - y, 10 + (int)((x - 1) * radix), preY - y);
}
preY = Height - (int)(d * radiy);
x += 1;
curindex++;
}
return img;
}
}
}
BC3000型号
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LIS.BLL.ImageCore;
using System.Drawing;
using System.Data;
using System.IO;
using System.Drawing.Drawing2D;
namespace LIS.Mach.ImageDeal
{
///<summary NoteObject="Class">
/// [功能描述:M调用绘图测试] <para/>
/// [创建者:zlz] <para/>
/// [创建时间:2018年03月22日] <para/>
///<说明>
/// [说明:[功能描述:M调用绘图测试,配合M处理仪器绘图]<para/>
///</说明>
///<修改记录>
/// [修改时间:本次修改时间]<para/>
/// [修改内容:本次修改内容]<para/>
///</修改记录>
///<修改记录>
/// [修改时间:本次修改时间]<para/>
/// [修改内容:本次修改内容]<para/>
/// M端触发代码,其他的和监听程序一样
/// s retObj=##Class(wbsLisMsgAsyncHandler.LISMsg.wbsLisDrawImageAsyncHandlerSoap).%New()
/// s ret=retObj.DrawImage("1","绘图数据","仪器","处理M","传输次数","其他参数","LIS.Mach.ImageDeal.ImageDealTest,LIS.Mach.ImageDeal")
/// s ret=$$DealImage^MI.MIF000(epis,"整个BC3000的数据,绘图自己提取绘图数据",mi,"和监听一样的有保存图片的M类","-1","","LIS.Mach.ImageDeal.ImageDealBC3000Plus,LIS.Mach.ImageDeal")
///</修改记录>
///</summary>
public class ImageDealBC3000Plus : IDrawImage
{
/// <summary>
/// 绘图方法
/// </summary>
/// <param name="epis">流水号</param>
/// <param name="result">结果</param>
/// <param name="machID">仪器ID</param>
/// <param name="dealProcess">处理M</param>
/// <param name="index">-1认为传到最后</param>
/// <param name="otherPara">其他参数</param>
/// <param name="dealClass">C#处理类格式:类全名,不带后缀的动态库名</param>
/// <returns>是否成功</returns>
public bool DrawImage(string epis, string result, string machID, string dealProcess, string index, string otherPara, string dealClass)
{
if (result.Length > 2304)
{
string imgStr = result.Substring(result.Length - 2304, 2304);
//每个图256*3表示 依次是WBC RBC PLT
for (int i = 0; i < 3; i++)
{
string oneImgStr = imgStr.Substring(i*768,768);
float maxVal = 0;
float [] points = new float[256];
for (int j = 0; j < 256; j++)
{
string onePoint = oneImgStr.Substring(j*3,3);
float curVal = Convert.ToInt32(onePoint);
if(maxVal<curVal)
{
maxVal=curVal;
}
points[j]=curVal;
}
//图片类别
string imgClass = "";
if (i == 0)
{
imgClass = "WBC";
}
else if (i == 1)
{
imgClass = "RBC";
}
else if (i == 2)
{
imgClass = "PLT";
}
Dictionary<int, string> xshow = new Dictionary<int, string>();
if (imgClass == "RBC")
{
xshow.Add(10, "0");
xshow.Add(60, "50");
xshow.Add(110, "100");
xshow.Add(160, "150");
xshow.Add(210, "200");
xshow.Add(260, "250");
xshow.Add(310, "fL");
}
if (imgClass == "PLT")
{
xshow.Add(10, "0");
xshow.Add(50, "5");
xshow.Add(100, "10");
xshow.Add(150, "15");
xshow.Add(200, "20");
xshow.Add(250, "25");
xshow.Add(300, "fL");
}
//按十进制结果画图
Histogram histogram = new Histogram("", imgClass, 256, maxVal, "0", 329, 128, xshow);
histogram.Values = points;
Bitmap img = histogram.CreateImage();
//判断C盘trak是否存在
string tmpPath = @"c:\trak\tmpMach";
if (!Directory.Exists("C:\\trak"))
{
Directory.CreateDirectory("C:\\trak"); //新建文件夹
if (!Directory.Exists(tmpPath))
{
Directory.CreateDirectory(tmpPath); //新建文件夹
}
}
//先删除临时目录里面的所有文件
DeleteFolder(tmpPath);
img.Save(tmpPath + "\\" + imgClass + epis + ".bmp");
img.Dispose();
}
}
return true;
}
/// 清空指定的文件夹,但不删除文件夹
/// </summary>
/// <param name="dir"></param>
public static void DeleteFolder(string dir)
{
foreach (string d in Directory.GetFileSystemEntries(dir))
{
if (File.Exists(d))
{
FileInfo fi = new FileInfo(d);
if ((DateTime.Now - fi.CreationTime).Minutes > 10)
{
if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1)
{
fi.Attributes = FileAttributes.Normal;
}
File.Delete(d);//直接删除其中的文件
}
}
else
{
DirectoryInfo d1 = new DirectoryInfo(d);
if (d1.GetFiles().Length != 0)
{
DeleteFolder(d1.FullName);递归删除子文件夹
}
Directory.Delete(d);
}
}
}
}
}
BC2600型号
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LIS.BLL.ImageCore;
using System.Drawing;
using System.Data;
using System.IO;
using System.Drawing.Drawing2D;
namespace LIS.Mach.ImageDeal
{
///<summary NoteObject="Class">
/// [功能描述:M调用绘图测试] <para/>
/// [创建者:zlz] <para/>
/// [创建时间:2018年03月22日] <para/>
///<说明>
/// [说明:[功能描述:M调用绘图测试,配合M处理仪器绘图]<para/>
///</说明>
///<修改记录>
/// [修改时间:本次修改时间]<para/>
/// [修改内容:本次修改内容]<para/>
///</修改记录>
///<修改记录>
/// [修改时间:本次修改时间]<para/>
/// [修改内容:本次修改内容]<para/>
/// M端触发代码,其他的和监听程序一样
/// s retObj=##Class(wbsLisMsgAsyncHandler.LISMsg.wbsLisDrawImageAsyncHandlerSoap).%New()
/// s ret=retObj.DrawImage("1","绘图数据","仪器","处理M","传输次数","其他参数","LIS.Mach.ImageDeal.ImageDealTest,LIS.Mach.ImageDeal")
/// s ret=$$DealImage^MI.MIF000(epis,"整个BC3000的数据,绘图自己提取绘图数据",mi,"和监听一样的有保存图片的M类","-1","","LIS.Mach.ImageDeal.ImageDealBC3000Plus,LIS.Mach.ImageDeal")
///</修改记录>
///</summary>
public class ImageDealBC2600 : IDrawImage
{
/// <summary>
/// 绘图方法
/// </summary>
/// <param name="epis">流水号</param>
/// <param name="result">结果</param>
/// <param name="machID">仪器ID</param>
/// <param name="dealProcess">处理M</param>
/// <param name="index">-1认为传到最后</param>
/// <param name="otherPara">其他参数</param>
/// <param name="dealClass">C#处理类格式:类全名,不带后缀的动态库名</param>
/// <returns>是否成功</returns>
public bool DrawImage(string epis, string result, string machID, string dealProcess, string index, string otherPara, string dealClass)
{
result = result.Replace(" ","").Replace("\n","");
string[] paraList = otherPara.Split('#');
string imgClass = "";
if (paraList.Length > 1)
{
imgClass = paraList[1];
if (imgClass == "PLT")
{
result = result.Substring(0,result.Length/2);
}
}
float[] dot = new float[result.Length / 2];
float imgMaxValue = 0;
int indexD = 0;
for (int i = 0; i < result.Length - 2; i = i + 2)
{
dot[indexD] = Convert.ToInt32(result[i] + "", 16) * 16 + Convert.ToInt32(result[i + 1] + "", 16);
if (dot[indexD] > imgMaxValue)
{
imgMaxValue = dot[indexD];
}
indexD++;
}
Dictionary<int, string> xshow = new Dictionary<int, string>();
if (imgClass == "RBC")
{
xshow.Add(10, "0");
xshow.Add(60, "50");
xshow.Add(110, "100");
xshow.Add(160, "150");
xshow.Add(210, "200");
xshow.Add(260, "250");
xshow.Add(310, "fL");
}
if (imgClass == "WBC")
{
xshow.Add(10, "0");
xshow.Add(60, "50");
xshow.Add(110, "100");
xshow.Add(160, "150");
xshow.Add(210, "200");
xshow.Add(260, "250");
xshow.Add(310, "fL");
}
if (imgClass == "PLT")
{
xshow.Add(10, "0");
xshow.Add(50, "5");
xshow.Add(100, "10");
xshow.Add(150, "15");
xshow.Add(200, "20");
xshow.Add(250, "25");
xshow.Add(300, "fL");
}
Histogram histogram = new Histogram("", imgClass, dot.Length, imgMaxValue, "0", 339, 130, xshow);
histogram.Values = dot;
Bitmap img = histogram.CreateImage();
//判断C盘trak是否存在
string tmpPath = @"c:\trak\tmpMach";
if (!Directory.Exists("C:\\trak"))
{
Directory.CreateDirectory("C:\\trak"); //新建文件夹
if (!Directory.Exists(tmpPath))
{
Directory.CreateDirectory(tmpPath); //新建文件夹
}
}
//先删除临时目录里面的所有文件
DeleteFolder(tmpPath);
img.Save(tmpPath + "\\" + imgClass + epis + ".bmp");
img.Dispose();
return true;
}
/// 清空指定的文件夹,但不删除文件夹
/// </summary>
/// <param name="dir"></param>
public static void DeleteFolder(string dir)
{
foreach (string d in Directory.GetFileSystemEntries(dir))
{
if (File.Exists(d))
{
FileInfo fi = new FileInfo(d);
if ((DateTime.Now - fi.CreationTime).Minutes > 10)
{
if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1)
{
fi.Attributes = FileAttributes.Normal;
}
File.Delete(d);//直接删除其中的文件
}
}
else
{
DirectoryInfo d1 = new DirectoryInfo(d);
if (d1.GetFiles().Length != 0)
{
DeleteFolder(d1.FullName);递归删除子文件夹
}
Directory.Delete(d);
}
}
}
}
}
提倡一下分享精神