using Microsoft.AspNetCore.Razor.TagHelpers;
using Newtonsoft.Json;
using NLog.Fluent;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.Numerics;
using Wicture.DbRESTFul;
using static System.Net.Mime.MediaTypeNames;
using Image = System.Drawing.Image;
namespace JiaZhiQuan.Common.Utils
{
public static class ImageSuperposeUtils
{
///
/// 将内容添加到底图上,返回流
///
///
/// Stream图片流, Png格式
public static Stream AddContextToImage(ImageSuperposeDTO dto)
{
try
{
// 复制原始图片到临时文件夹(复制一个防止同时修改同一个图片)
File.Copy(dto.OriginImagePath, dto.TempImagePath, true);
// 加载原始图片
using Image originalImage = Image.FromFile(dto.TempImagePath);
using Graphics graphics = Graphics.FromImage(originalImage);
// 循环//处理所有叠加内容
foreach (var item in dto.SuperposeDetails)
{
if (item.Type == SuperposeType.Text)
{
var text = item.Text;
// 设置绘制文本的字体、大小和颜色
System.Drawing.Font font = new System.Drawing.Font(text.FamilyName, text.FontSize);
Brush brush = new SolidBrush(text.Color);
Point position = new Point(item.X, item.Y);
// 绘制文本
graphics.DrawString(text.Text, font, brush, new Point(item.X, item.Y));
}
else if (item.Type == SuperposeType.Image)
{
// 读取需要叠加的图片
var image = Image.FromFile(item.Image.ImagePath);
if (item.Image.isFillet)
{
image = DrawTransparentRoundCornerImage(image);
}
// 设置坐标宽高
int width = item.Image.Width is null ? image.Width : item.Image.Width.Value,
height = item.Image.Height is null ? image.Height : item.Image.Height.Value;
var rectangle = new Rectangle(item.X, item.Y, width, height);
graphics.DrawImage(image, rectangle);
}
else if (item.Type == SuperposeType.ImageStream)
{
if (item.ImageStream is null)
{
LoggerManager.Logger.Error("生成用户海报失败,图片流为空。参数:" + JsonConvert.SerializeObject(item));
}
// 设置坐标宽高
int width = item.ImageStream.Width.Value,
height = item.ImageStream.Height.Value;
// 读取需要叠加的图片
var image = Image.FromStream(item.ImageStream.ImageStream);
// 判断图片大小是否需要缩放
if (image.Width != width || image.Height != height)
{
image = ScaleImage(image, width, height);
}
// 是否圆角
if (item.ImageStream.isFillet)
{
image = DrawTransparentRoundCornerImage(image);
}
var rectangle = new Rectangle(item.X, item.Y, width, height);
graphics.DrawImage(image, rectangle);
image.Dispose();
}
}
// 保存修改后的图片
//originalImage.Save($@"C:\Users\gy\Pictures\海报\{dto.FileName}");
MemoryStream stream = new MemoryStream();
originalImage.Save(stream, ImageFormat.Png);
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
finally
{
File.Delete(dto.TempImagePath);
}
}
///
/// 图片更改圆角
///
///
///
private static Image DrawTransparentRoundCornerImage(Image image)
{
Bitmap bm = new Bitmap(image.Width, image.Height);
using Graphics g = Graphics.FromImage(bm);
g.FillRectangle(Brushes.Transparent, new Rectangle(0, 0, image.Width, image.Height));
// 将画布的区域设置为透明
g.Clear(Color.Transparent);
// 设置绘制质量为高质量
g.SmoothingMode = SmoothingMode.HighQuality;
// 创建一个圆形路径
GraphicsPath path = new GraphicsPath();
path.AddEllipse(0, 0, bm.Width, bm.Height);
// 将剪辑区域设置为圆形路径
g.SetClip(path);
// 在剪辑区域内绘制原始图像
g.DrawImage(image, 0, 0);
// 清除剪辑区域,以便添加边框
g.ResetClip();
// 添加3px白色边框
using (Pen borderPen = new Pen(Color.White, 3))
{
g.DrawEllipse(borderPen, 1, 1, bm.Width - 3, bm.Height - 3);
}
return bm;
}
///
/// 缩放图片
///
///
///
///
///
public static Bitmap ScaleImage(Image originalImage, int newWidth, int newHeight)
{
// 创建目标尺寸的位图对象
Bitmap scaledImage = new Bitmap(newWidth, newHeight);
// 使用 Graphics 类进行绘制
using (Graphics graphics = Graphics.FromImage(scaledImage))
{
// 设置绘制质量,可根据需要调整
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
// 绘制缩放后的图片
graphics.DrawImage(originalImage, 0, 0, newWidth, newHeight);
}
return scaledImage;
}
}
public class ImageSuperposeDTO
{
///
/// 文件名
///
public string FileName { get; set; }
///
/// 原始图片路径
///
public string OriginImagePath { get; set; }
///
/// 临时图片路径(需要对原始图片复制一个进行操作)
///
public string TempImagePath { get; set; }
///
/// 叠加内容详情
///
public List SuperposeDetails { get; set; }
public void Clear()
{
foreach (var item in SuperposeDetails)
{
if (item.Type == SuperposeType.ImageStream)
{
item.ImageStream.ImageStream.Close();
}
}
}
}
///
/// 图片叠加操作类型
///
public enum SuperposeType
{
Text = 0,
Image = 1,
ImageStream = 2,
ComplexText = 3
}
public class ImageSuperposeDetails
{
///
/// 叠加内容类型
///
public SuperposeType Type { get; set; }
///
/// 叠加的文字详情
/// SuperposeType.Text时,Text不能为空
///
public ImageSuperposeTextDetails Text { get; set; }
///
/// 叠加的图片路径
/// SuperposeType.Image时,Image不能为空
///
public ImageSuperposeImageDetails Image { get; set; }
///
/// 叠加的图片流
/// SuperposeType.ImageStream时,ImageStream不能为空
///
public ImageSuperposeImageStreamDetails ImageStream { get; set; }
///
/// x坐标
///
public int X { get; set; }
///
/// y坐标
///
public int Y { get; set; }
}
///
/// 叠加的文字详情
///
public class ImageSuperposeTextDetails
{
///
/// 叠加的内容
///
public string Text { get; set; }
///
/// 叠加内容的颜色
///
public Color Color { get; set; }
///
/// 文字大小
///
public int FontSize { get; set; } = 16;
///
/// 字体格式
///
public string FamilyName { get; set; }
}
///
/// 叠加的图片详情
///
public class ImageSuperposeImageDetails
{
///
/// 叠加的图片路径
///
public string ImagePath { get; set; }
///
/// 宽(如果设置了,那么将覆盖图片默认的宽)
///
public int? Width { get; set; }
///
/// 高(如果设置了,那么将覆盖图片默认的高)
///
public int? Height { get; set; }
///
/// 是否需要把图片变成圆型
///
public bool isFillet { get; set; }
}
///
/// 叠加的图片流详情
///
public class ImageSuperposeImageStreamDetails
{
///
/// 叠加的图片路径
///
public Stream ImageStream { get; set; }
///
/// 宽(如果设置了,那么将覆盖图片默认的宽)
///
public int? Width { get; set; }
///
/// 高(如果设置了,那么将覆盖图片默认的高)
///
public int? Height { get; set; }
///
/// 是否需要把图片变成圆型
///
public bool isFillet { get; set; }
}
}