212 lines
8.3 KiB
C#
212 lines
8.3 KiB
C#
using Abp.Dependency;
|
|
using SkiaSharp;
|
|
using System.Text;
|
|
using Yunda.ISAS.DataMonitoringServer.DataAnalysis.Model;
|
|
|
|
namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis.LinkageAnalysis
|
|
{
|
|
/// <summary>
|
|
/// 谷歌skia图像处理图调用API
|
|
/// </summary>
|
|
public class SkiaSharpHandlePicture : ISingletonDependency
|
|
{
|
|
private float _radius = 8; //画圈半径
|
|
private int _fontSize = 24; //文字大小
|
|
private int _maxPixQuality = 1920 * 1080; //最大像素质量
|
|
private SKEncodedImageFormat _sKEncodedImageFormat = SKEncodedImageFormat.Jpeg; //存储文件格式
|
|
private string _tmpPath = "./CaptureJPEGPicture/resultPicture.jpg"; //临时文件目录
|
|
|
|
public SkiaSharpHandlePicture()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// 谷歌skia图像处理图调用API
|
|
/// </summary>
|
|
/// <param name="radius">画圈半径</param>
|
|
/// <param name="fontSize">文字大小</param>
|
|
/// <param name="tmpPath">临时文件目录</param>
|
|
/// <param name="sKEncodedImageFormat">存储文件格式</param>
|
|
/// <param name="maxPixQuality">最大像素质量</param>
|
|
public SkiaSharpHandlePicture(float radius, int fontSize, string tmpPath, SKEncodedImageFormat sKEncodedImageFormat, int maxPixQuality)
|
|
{
|
|
_radius = radius;
|
|
_tmpPath = tmpPath;
|
|
_fontSize = fontSize;
|
|
_sKEncodedImageFormat = sKEncodedImageFormat;
|
|
_maxPixQuality = maxPixQuality;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据给的关键点获取文字显示的位置
|
|
/// </summary>
|
|
/// <param name="measureTempCoordinate"></param>
|
|
/// <param name="textWidth"></param>
|
|
/// <param name="textHeight"></param>
|
|
/// <param name="bmpWidth"></param>
|
|
/// <param name="bmpHeight"></param>
|
|
/// <returns></returns>
|
|
private (float, float) GetTextCoordinate(MeasureTempCoordinate measureTempCoordinate, float textWidth, float textHeight, int bmpWidth, int bmpHeight)
|
|
{
|
|
//var measureTempCoordinate = points[0];
|
|
var isCloseUpSide = measureTempCoordinate.Y - textHeight <= 0;//当选择点靠近上边时
|
|
var isCloseDownSide = measureTempCoordinate.Y + textHeight >= bmpHeight;//当选择点靠近下边时
|
|
|
|
var isCloseLeftSide = measureTempCoordinate.X - textWidth / 2 <= 0;// 当选择点靠近左边时
|
|
var isCloseRightSide = measureTempCoordinate.X + textWidth / 2 >= bmpWidth;// 当选择点靠近右边时
|
|
|
|
var textX = measureTempCoordinate.X - textWidth / 2;//文字起点的X坐标
|
|
var textY = measureTempCoordinate.Y + textHeight;//文字起点的Y坐标
|
|
|
|
if (isCloseUpSide)
|
|
{
|
|
//不处理
|
|
}
|
|
if (isCloseDownSide)
|
|
{
|
|
textY = measureTempCoordinate.Y - textHeight;
|
|
}
|
|
if (isCloseLeftSide)
|
|
{
|
|
textX = 0;
|
|
}
|
|
if (isCloseRightSide)
|
|
{
|
|
textX = bmpWidth - textWidth;
|
|
}
|
|
return (textX, textY);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 绘图API
|
|
/// </summary>
|
|
/// <param name="points">绘图点集合(百分比)</param>
|
|
/// <param name="filePath">背景图路径</param>
|
|
/// <param name="content">文字内容</param>
|
|
/// <returns>生成文件路径</returns>
|
|
public void Bitmap(List<MeasureTempCoordinate> points, ref string filePath, string content)
|
|
{
|
|
if (points == null || points.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
if (!File.Exists(filePath))
|
|
{
|
|
return;
|
|
}
|
|
//载入底图
|
|
var bmp = SKBitmap.Decode(filePath);
|
|
//图像宽度
|
|
var bmpWidth = bmp.Width;
|
|
//图像高度
|
|
var bmpHeight = bmp.Height;
|
|
|
|
foreach (var item in points)//处理points坐标换算
|
|
{
|
|
item.X = item.X * bmpWidth;
|
|
item.Y = item.Y * bmpHeight;
|
|
}
|
|
//初始化画布
|
|
var canvas = new SKCanvas(bmp);
|
|
|
|
//保存当前画布状态,即正常全图绘制状态
|
|
canvas.Save();
|
|
var paint = new SKPaint
|
|
{
|
|
//抗锯齿
|
|
IsAntialias = true,
|
|
IsStroke = true,
|
|
StrokeWidth = 0.8f,
|
|
//StrokeCap = SKStrokeCap.Butt,
|
|
//颜色
|
|
Color = new SKColor(255, 255, 255, 255)
|
|
};
|
|
|
|
if (points.Count == 1) //当传入的参数是一个点
|
|
{
|
|
var point = new SKPoint(points[0].X, points[0].Y);
|
|
canvas.DrawCircle(point, _radius, paint);
|
|
canvas.Save();
|
|
|
|
//写文字
|
|
float beta = 4 / 3;//文字和像素之间的换算系数
|
|
//文字长度
|
|
var textWidth = content.Length * _fontSize * beta;
|
|
//文字高度
|
|
var textHeight = _fontSize * beta;
|
|
byte[] gb = Encoding.UTF8.GetBytes(content);
|
|
var fontPath = Path.GetFullPath("Fonts/PingFang Regular.otf"); // 为了解决不能写汉字,需要字体文件
|
|
var font = new SKFont { Typeface = SKTypeface.FromFile(fontPath), Size = _fontSize };
|
|
SKTextBlob sKTextBlob = SKTextBlob.Create(gb, SKTextEncoding.Utf8, font);
|
|
|
|
var coordinate = GetTextCoordinate(points[0], textWidth, textHeight, bmpWidth, bmpHeight);
|
|
|
|
canvas.DrawText(sKTextBlob, coordinate.Item1, coordinate.Item2, paint);
|
|
canvas.Save();
|
|
}
|
|
else
|
|
{
|
|
var skpath = new SKPath();
|
|
float maxPos = 0;
|
|
MeasureTempCoordinate measureTempCoordinate = new MeasureTempCoordinate();
|
|
for (int i = 0; i < points.Count; i++)
|
|
{
|
|
var X = points[i].X;
|
|
|
|
var Y = points[i].Y;
|
|
if (i == 0)
|
|
{
|
|
skpath.MoveTo(X, Y); //开始点
|
|
}
|
|
else
|
|
{
|
|
skpath.LineTo(X, Y);
|
|
}
|
|
if (X * Y > maxPos) //找到坐标乘积最大的点
|
|
{
|
|
maxPos = X * Y;
|
|
measureTempCoordinate.X = X;
|
|
measureTempCoordinate.Y = Y;
|
|
}
|
|
}
|
|
skpath.Close();
|
|
canvas.DrawPath(skpath, paint);
|
|
canvas.Save();
|
|
//写文字
|
|
byte[] gb = Encoding.UTF8.GetBytes(content);
|
|
float beta = 4 / 3;//文字和像素之间的换算系数
|
|
var fontPath = Path.GetFullPath("Fonts/PingFang Regular.otf"); // 为了解决不能写汉字,需要字体文件
|
|
var font = new SKFont { Typeface = SKTypeface.FromFile(fontPath), Size = _fontSize };
|
|
SKTextBlob sKTextBlob = SKTextBlob.Create(gb, SKTextEncoding.Utf8, font);
|
|
//文字长度
|
|
var textWidth = content.Length * _fontSize * beta;
|
|
//文字高度
|
|
var textHeight = _fontSize * beta;
|
|
var coordinate = GetTextCoordinate(measureTempCoordinate, textWidth, textHeight, bmpWidth, bmpHeight);
|
|
canvas.DrawText(sKTextBlob, coordinate.Item1, coordinate.Item2, paint);
|
|
canvas.Save();
|
|
}
|
|
//保存为图片
|
|
|
|
var path = Path.GetFullPath(_tmpPath);
|
|
if (!Directory.Exists("./CaptureJPEGPicture"))
|
|
{
|
|
Directory.CreateDirectory("./CaptureJPEGPicture");
|
|
}
|
|
var file = File.OpenWrite(path);
|
|
bmp.Encode(file, _sKEncodedImageFormat, _maxPixQuality);
|
|
|
|
paint.Dispose(); //释放画笔
|
|
|
|
file.Dispose(); //释放文件
|
|
|
|
bmp.Dispose(); //释放图像
|
|
|
|
canvas.Dispose(); //释放画板
|
|
|
|
File.Delete(filePath);
|
|
FileInfo fi = new FileInfo(path);
|
|
fi.MoveTo(filePath);
|
|
}
|
|
}
|
|
} |