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
{
///
/// 绘制标尺
///
public class DrawRulerHelper
{
///
/// 绘制标尺
///
/// 标尺配置类
/// 画布
/// 中心点
/// 标尺长度
/// 标尺显示文字
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);
}
///
/// 绘制网格
///
///
///
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);
}
}
///
/// 绘制网格
///
///
///
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);
}
}
///
/// 绘制方形网格,未按标尺进行处理
///
///
///
///
///
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);
}
///
/// 绘制圆形网格,未按标尺进行处理
///
///
///
///
///
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));
}
///
/// 绘制十字线,未按标尺进行处理
///
///
///
///
///
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);
}
}
///
/// bitmap转base64
///
///
///
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;
}
///
/// base64转bitmap
///
///
///
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;
}
}
///
/// 缩放图像
///
///
///
///
///
///
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;
}
///
/// 深拷贝,反射
///
///
///
public static T DeepCopyByReflect(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 DeepCopyListByReflect(List objs)
{
List list = new List();
if (objs!=null && objs.Count>0)
{
foreach(T t in objs)
{
list.Add(DeepCopyByReflect(t));
}
}
return list;
}
///
/// 深拷贝,xml序列化与反序列化
///
///
///
///
public static T DeserializeXML(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;
}
///
/// 图片裁剪
/// 原图
///
/// 裁剪起始点横坐标
/// 裁剪起始点纵坐标
/// 裁剪宽度
/// 裁剪高度
///
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;
}
}
}
}