123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500 |
- using OpenCvSharp;
- using PaintDotNet.Base.Enum;
- using PaintDotNet.Base.SettingModel;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Drawing.Imaging;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Runtime.Serialization.Formatters.Binary;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using System.Xml.Serialization;
- namespace PaintDotNet.Base.CommTool
- {
- /// <summary>
- /// 绘制标尺
- /// </summary>
- public class DrawRulerHelper
- {
- /// <summary>
- /// 绘制标尺
- /// </summary>
- /// <param name="rulerModel">标尺配置类</param>
- /// <param name="graphics">画布</param>
- /// <param name="center">中心点</param>
- /// <param name="lineLength">标尺长度</param>
- /// <param name="text">标尺显示文字</param>
- public static void drawRuler(RulerModel rulerModel, Graphics graphics, PointF center, int lineLength, String text, out RectangleF borderPenRectangle)
- {
- Pen linePen = new Pen(Color.FromArgb(rulerModel.lineColor));
- Pen borderPen = new Pen(Color.FromArgb(rulerModel.borderColor));
- // 标尺线段
- PointF lineL = new PointF(center.X - lineLength / 2, center.Y);
- PointF lineR = new PointF(center.X + lineLength / 2, center.Y);
- linePen.Width = (int)rulerModel.lineWidth;
- int lineWidthOffset = (int)rulerModel.lineWidth / 2 - 1;
- // 垂线
- decimal verticalLength = lineLength * rulerModel.verticalLineLength / 100;
- PointF verticalLT = new PointF(lineL.X, lineL.Y - (int)(verticalLength / 2));
- PointF verticalLB = new PointF(lineL.X, lineL.Y + (int)(verticalLength / 2));
- PointF verticalRT = new PointF(lineR.X, lineR.Y - (int)(verticalLength / 2));
- PointF verticalRB = new PointF(lineR.X, lineR.Y + (int)(verticalLength / 2));
- // 文字
- Font textFont;
- decimal textHeight = lineLength * rulerModel.textHeight / 100;
- if (rulerModel.textBold == 0)
- textFont = new Font(rulerModel.textFont, (float)rulerModel.textFontSize,FontStyle.Regular);
- else
- textFont = new Font(rulerModel.textFont, (float)rulerModel.textFontSize, FontStyle.Bold);
- float textSizes = textFont.SizeInPoints * text.Length;
- float textX = lineL.X;
- if (rulerModel.textPosition == 1)
- {
- textX = (lineR.X - lineL.X) / 2 - (int)(textSizes / 2) + lineL.X;
- }
- else if (rulerModel.textPosition == 2)
- {
- textX = lineR.X - (int)(textSizes);
- }
- PointF textLT = new PointF(textX, lineL.Y - lineWidthOffset - (int)(textHeight + new Decimal(textFont.Height)));
- // 背景参照Y坐标,垂线高,使用垂线Y值,文字高使用文字Y值。
- float backRectangleReferY = textLT.Y < verticalLT.Y - 2 ? textLT.Y : verticalLT.Y -2;
- // 背景大小
- decimal backLength = lineLength * rulerModel.backgroundSize / 100;
- float backRectangleX = verticalLT.X - (int)backLength - (int)linePen.Width;
- float backRectangleY = backRectangleReferY - (int)(backLength);
- float backRectangleW = (verticalRT.X - verticalLT.X) + (int)(backLength * 2) + (int)(linePen.Width * 2);
- float backRectangleH = (verticalLB.Y - backRectangleReferY) + (int)(backLength * 2) + lineWidthOffset + 2;
- RectangleF backRectangle = new RectangleF(backRectangleX, backRectangleY, backRectangleW, backRectangleH);
- // 边框
- borderPen.Width = (int)rulerModel.borderWidth;
- int offset = borderPen.Width>0?(int)(borderPen.Width / 2) - 2:0;
- borderPenRectangle = new RectangleF(backRectangle.X - offset, backRectangle.Y - offset, backRectangle.Width + offset * 2, backRectangle.Height + offset * 2);
- // 计算中心Y轴偏移量
- // 绘制
- graphics.FillRectangle(new SolidBrush(Color.FromArgb(rulerModel.backColor)), backRectangle);
- graphics.DrawRectangle(borderPen, borderPenRectangle.X, borderPenRectangle.Y, borderPenRectangle.Width, borderPenRectangle.Height);
- graphics.DrawLine(linePen, lineL, lineR);
- graphics.DrawLine(linePen, verticalLT, verticalLB);
- graphics.DrawLine(linePen, verticalRT, verticalRB);
- graphics.DrawString(text, textFont, new SolidBrush(Color.FromArgb(rulerModel.textColor)), textLT.X, textLT.Y);
- }
- /// <summary>
- /// 绘制网格
- /// </summary>
- /// <param name="rulerModel"></param>
- /// <param name="graphics"></param>
- public static void drawGrid(GridModel gridModel, Graphics graphics, int width, int height)
- {
- int length = gridModel.grid.SideLength; //网格宽度
- int sideHeight = gridModel.grid.SideHeight; //网格高度
- int hnum = gridModel.grid.HorizontalNum; //水平网格数
- int vnum = gridModel.grid.VerticalNum; //垂直网格数
- int dashStyle = gridModel.grid.DashStyle; //线形
- int thickness = gridModel.grid.Thickness; //粗细
- int color = gridModel.grid.Color; //颜色
-
- int hlines = vnum + 1; //水平线条数
- int vlines = hnum + 1; //垂直线条数
- Pen pen = new Pen(new SolidBrush(Color.FromArgb(color)), thickness);
- pen.DashStyle = (DashStyle)dashStyle;
- int y = (height - vnum * sideHeight) / 2;
- int x = (width - hnum * length) / 2;
- for (int i=0; i< hlines; i++)
- {
- graphics.DrawLine(pen, x, y + i * sideHeight, x + length * hnum, y + i * sideHeight);
- }
- for (int i = 0; i < vlines; i++)
- {
- graphics.DrawLine(pen, x + i * length, y, x + i * length, y + sideHeight * vnum);
- }
- }
- /// <summary>
- /// 绘制网格
- /// </summary>
- /// <param name="rulerModel"></param>
- /// <param name="graphics"></param>
- public static void drawGridFull(GridModel gridModel, Graphics graphics, int width, int height)
- {
- int hnum = gridModel.grid.HorizontalNum; //水平网格数
- int vnum = gridModel.grid.VerticalNum; //垂直网格数
- int dashStyle = gridModel.grid.DashStyle; //线形
- int thickness = gridModel.grid.Thickness; //粗细
- int color = gridModel.grid.Color; //颜色
- int hlines = vnum + 1; //水平线条数
- int vlines = hnum + 1; //垂直线条数
- Pen pen = new Pen(new SolidBrush(Color.FromArgb(color)), thickness);
- pen.DashStyle = (DashStyle)dashStyle;
- float y = ((height * 1.0f ) / vnum);
- float x = ((width * 1.0f) / hnum);
- for (int i = 0; i < hlines; i++)
- {
- graphics.DrawLine(pen, 0, y * i , width, y * i);
- }
- for (int i = 0; i < vlines; i++)
- {
- graphics.DrawLine(pen, x * i, 0, x * i, height);
- }
- }
- /// <summary>
- /// 绘制方形网格,未按标尺进行处理
- /// </summary>
- /// <param name="gridModel"></param>
- /// <param name="graphics"></param>
- /// <param name="width"></param>
- /// <param name="height"></param>
- public static void drawGridRectangle(GridModel gridModel, Graphics graphics, int width, int height, double micronRatio)
- {
- int length = gridModel.rectangle.sideLength; //边长
- int dashStyle = gridModel.rectangle.DashStyle; //线形
- int thickness = gridModel.rectangle.Thickness; //粗细
- int color = gridModel.rectangle.Color; //颜色
- Pen pen = new Pen(new SolidBrush(Color.FromArgb(color)), thickness);
- pen.DashStyle = (DashStyle)dashStyle;
- //float side = (float)(length / micronRatio);
- float x = (width - length) / 2;
- float y = (height - length) / 2;
- graphics.DrawRectangle(pen, x, y, length, length);
- }
- /// <summary>
- /// 绘制圆形网格,未按标尺进行处理
- /// </summary>
- /// <param name="gridModel"></param>
- /// <param name="graphics"></param>
- /// <param name="width"></param>
- /// <param name="height"></param>
- public static void drawGridRound(GridModel gridModel, Graphics graphics, int width, int height, double micronRatio)
- {
- int diameter = gridModel.round.diameter;//直径
- int dashStyle = gridModel.round.DashStyle; //线形
- int thickness = gridModel.round.Thickness; //粗细
- int color = gridModel.round.Color; //颜色
- Pen pen = new Pen(new SolidBrush(Color.FromArgb(color)), thickness);
- pen.DashStyle = (DashStyle)dashStyle;
- //float diameter = (float)(70 / micronRatio);//直径固定70微米
- float x = (width - diameter) / 2;
- float y = (height - diameter) / 2;
- graphics.DrawEllipse(pen, new RectangleF(x, y , diameter, diameter));
- }
- /// <summary>
- /// 绘制十字线,未按标尺进行处理
- /// </summary>
- /// <param name="gridModel"></param>
- /// <param name="graphics"></param>
- /// <param name="width"></param>
- /// <param name="height"></param>
- public static void drawGridCrossCurve(GridModel gridModel, Graphics graphics, int width, int height)
- {
- if (gridModel == null)
- {
- //样式暂时写死,没有对应样式设置
- int dashStyle = 0; //线形
- int thickness = 5; //粗细
- int color = -59111; //颜色
- Pen pen = new Pen(new SolidBrush(Color.FromArgb(color)), thickness);
- pen.DashStyle = (DashStyle)dashStyle;
- float lineLength = width < height ? width * 0.3f : height * 0.3f;//线长
- float x = (width - lineLength) / 2;
- float y = (height - lineLength) / 2;
- graphics.DrawLine(pen, x, height / 2, x + lineLength, height / 2);
- graphics.DrawLine(pen, width / 2, y, width / 2, y + lineLength);
- }
- }
- /// <summary>
- /// bitmap转base64
- /// </summary>
- /// <param name="bmp"></param>
- /// <returns></returns>
- public static string ImgToBase64String(Bitmap source)
- {
- OpenCvSharp.Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(source);
- Bitmap bitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);
- string base64 = "";
- using (MemoryStream ms = new MemoryStream())
- {
- bitmap.Save(ms, ImageFormat.Jpeg);
- base64 = Convert.ToBase64String(ms.ToArray());
- ms.Close();
- bitmap.Dispose();
- }
- return base64;
- }
- /// <summary>
- /// base64转bitmap
- /// </summary>
- /// <param name="strbase64"></param>
- /// <returns></returns>
- public static Bitmap Base64StringToImage(string strbase64)
- {
- try
- {
- byte[] arr = Convert.FromBase64String(strbase64);
- MemoryStream ms = new MemoryStream(arr);
- Bitmap bmp = new Bitmap(ms);
- ms.Close();
- return bmp;
- }
- catch (Exception)
- {
- return null;
- }
- }
- /// <summary>
- /// 缩放图像
- /// </summary>
- /// <param name="originalImage"></param>
- /// <param name="width"></param>
- /// <param name="height"></param>
- /// <param name="mode"></param>
- /// <returns></returns>
- public static Image ResizeImage(Image originalImage, int width, int height, ThumbnailMode mode)
- {
- int towidth = width;
- int toheight = height;
- int x = 0;
- int y = 0;
- int initWidth = originalImage.Width;
- int initHeight = originalImage.Height;
- switch (mode)
- {
- case ThumbnailMode.UsrHeightWidth: //指定高宽缩放(可能变形)
- break;
- case ThumbnailMode.UsrHeightWidthBound: //指定高宽缩放(可能变形)(过小则不变)
- if (originalImage.Width <= width && originalImage.Height <= height)
- {
- return originalImage;
- }
- if (originalImage.Width < width)
- {
- towidth = originalImage.Width;
- }
- if (originalImage.Height < height)
- {
- toheight = originalImage.Height;
- }
- break;
- case ThumbnailMode.UsrWidth: //指定宽,高按比例
- toheight = originalImage.Height * width / originalImage.Width;
- break;
- case ThumbnailMode.UsrWidthBound: //指定宽(过小则不变),高按比例
- if (originalImage.Width <= width)
- {
- return originalImage;
- }
- else
- {
- toheight = originalImage.Height * width / originalImage.Width;
- }
- break;
- case ThumbnailMode.UsrHeight: //指定高,宽按比例
- towidth = originalImage.Width * height / originalImage.Height;
- break;
- case ThumbnailMode.UsrHeightBound: //指定高(过小则不变),宽按比例
- if (originalImage.Height <= height)
- {
- return originalImage;
- }
- else
- {
- towidth = originalImage.Width * height / originalImage.Height;
- }
- break;
- case ThumbnailMode.Cut: //指定高宽裁减(不变形)
- //计算宽高比
- double srcScale = (double)originalImage.Width / (double)originalImage.Height;
- double destScale = (double)towidth / (double)toheight;
- //宽高比相同
- if (srcScale - destScale >= 0 && srcScale - destScale <= 0.001)
- {
- x = 0;
- y = 0;
- initWidth = originalImage.Width;
- initHeight = originalImage.Height;
- }
- //源宽高比大于目标宽高比
- //(源的宽比目标的宽大)
- else if (srcScale > destScale)
- {
- initWidth = originalImage.Height * towidth / toheight;
- initHeight = originalImage.Height;
- x = (originalImage.Width - initWidth) / 2;
- y = 0;
- }
- //源宽高比小于目标宽高小,源的高度大于目标的高度
- else
- {
- initWidth = originalImage.Width;
- initHeight = originalImage.Width * height / towidth;
- x = 0;
- y = (originalImage.Height - initHeight) / 2;
- }
- break;
- default:
- break;
- }
- Image bitmap = new Bitmap(towidth, toheight);
- //新建一个画板
- using (Graphics g = Graphics.FromImage(bitmap))
- {
- //设置高质量插值法
- g.CompositingQuality = CompositingQuality.HighQuality;
- //设置高质量,低速段呈现的平滑程度
- g.SmoothingMode = SmoothingMode.HighQuality;
- //在指定的位置上,并按指定大小绘制原图片的指定部分
- g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight), new Rectangle(x, y, initWidth, initHeight), GraphicsUnit.Pixel);
- }
- return bitmap;
- }
- /// <summary>
- /// 深拷贝,反射
- /// </summary>
- /// <param name="obj"></param>
- /// <returns></returns>
- public static T DeepCopyByReflect<T>(T obj)
- {
- //如果是字符串或值类型则直接返回
- if (obj==null || obj is string || obj.GetType().IsValueType) return obj;
- object retval = Activator.CreateInstance(obj.GetType());
- FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
- foreach (FieldInfo field in fields)
- {
- try { field.SetValue(retval, DeepCopyByReflect(field.GetValue(obj))); }
- catch { }
- }
- return (T)retval;
- }
- public static List<T> DeepCopyListByReflect<T>(List<T> objs)
- {
- List<T> list = new List<T>();
- if (objs!=null && objs.Count>0)
- {
- foreach(T t in objs)
- {
- list.Add(DeepCopyByReflect(t));
- }
- }
- return list;
- }
- /// <summary>
- /// 深拷贝,xml序列化与反序列化
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="xmlData"></param>
- /// <returns></returns>
- public static T DeserializeXML<T>(string xmlData) where T : new()
- {
- if (string.IsNullOrEmpty(xmlData))
- return default(T);
- TextReader tr = new StringReader(xmlData);
- T DocItms = new T();
- XmlSerializer xms = new XmlSerializer(DocItms.GetType());
- DocItms = (T)xms.Deserialize(tr);
- return DocItms == null ? default(T) : DocItms;
- }
- /// <summary>
- /// 图片裁剪
- /// </summary>原图
- /// <param name="b"></param>
- /// <param name="StartX">裁剪起始点横坐标</param>
- /// <param name="StartY">裁剪起始点纵坐标</param>
- /// <param name="iWidth">裁剪宽度</param>
- /// <param name="iHeight">裁剪高度</param>
- /// <returns></returns>
- public static Bitmap KiCut(Bitmap b, int StartX, int StartY, int iWidth, int iHeight)
- {
- if (b == null)
- {
- return null;
- }
- //不对超过原图尺寸的区域做处理,以黑色背景显示
- //int w = b.Width;
- //int h = b.Height;
- //if (StartX >= w || StartY >= h)
- //{
- // return null;
- //}
- //if (StartX + iWidth > w)
- //{
- // iWidth = w - StartX;
- //}
- //if (StartY + iHeight > h)
- //{
- // iHeight = h - StartY;
- //}
- try
- {
- Bitmap bmpOut = new Bitmap(iWidth, iHeight);
- Graphics g = Graphics.FromImage(bmpOut);
- g.Clear(Color.Black);
- g.DrawImage(b, new Rectangle(0, 0, iWidth, iHeight), new Rectangle(StartX, StartY, iWidth, iHeight), GraphicsUnit.Pixel);
- g.Dispose();
- return bmpOut;
- }
- catch
- {
- return null;
- }
- }
- }
- }
|