图片合并
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.Text;
using System.Threading.Tasks;
namespace Manjinba.Communication.Common.Utils
{
/// <summary>
/// 合并图片
/// </summary>
public class CombineGroupImgUtil
{
/// <summary>
/// 使用群成员头像合成群头像
/// </summary>
/// <param name="BigImg">群头像背景图</param>
/// <param name="sImgPath">传入的群成员头像数组</param>
/// <param name="position">传入的每张群成员在群头像中的拼合位置坐标</param>
/// <returns></returns>
public static string CombineImg(string BigImg, string[] sImgPath, string position)
{
string newImg = System.IO.Path.GetDirectoryName(BigImg);//获取图片的绝对路径(去除图片名和扩展名)
string[] AllFile = Directory.GetFiles(newImg + "\\", ".png");
string[] poitStr = position.Split(';');
try
{
System.Drawing.Image image = System.Drawing.Image.FromFile(BigImg);
Bitmap b = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(b);
g.Clear(Color.White);
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.High;
g.DrawImage(image, 0, 0, image.Width, image.Height);
for (int i = 0; i < sImgPath.Length; i++)
{
string[] ImgSize = poitStr[i].Split(',');
System.Drawing.Image simg = System.Drawing.Image.FromFile(sImgPath[i]);
addWatermarkImage(g, sImgPath[i], ImgSize, simg.Width, simg.Height, sImgPath.Length);//添加成员头像到背景图
simg.Dispose();
File.Delete(sImgPath[i]);
}
newImg += "\\" + DateTime.Now.ToString().Replace("/", "").Replace(":", "").Replace(" ", "") + ".png";
if (newImg == BigImg)
{
newImg = "\\" + DateTime.Now.ToString().Replace("/", "").Replace(":", "").Replace(" ", "") + "1.png";
}
b.Save(newImg);
b.Dispose();
image.Dispose();
}
catch
{
if (File.Exists(BigImg))
{
File.Delete(BigImg);
}
}
finally
{
if (File.Exists(BigImg))
{
File.Delete(BigImg);
}
}
return newImg;
}
/// <summary>
/// 合成/加水印图片
/// </summary>
/// <param name="picture">imge 对象</param>
/// <param name="WaterMarkPicPath">水印图片的地址</param>
/// <param name="_watermarkPosition">水印位置</param>
/// <param name="_width">被加水印图片的宽</param>
/// <param name="_height">被加水印图片的高</param>
private static void addWatermarkImage(Graphics picture, string WaterMarkPicPath, string[] position, int _width, int _height, int imgNum)
{
Image watermark = new Bitmap(WaterMarkPicPath);
ImageAttributes imageAttributes = new ImageAttributes();
ColorMap colorMap = new ColorMap();
colorMap.OldColor = Color.FromArgb(255, 255, 255, 0);
colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
ColorMap[] remapTable = { colorMap };
string[] SimgSize = calculateImgSize(120, 120, imgNum).Split(',');
//添加图片的位置
int xpos = int.Parse(position[0]);
int ypos = int.Parse(position[1]);
picture.DrawImage(watermark, new Rectangle(xpos, ypos, int.Parse(SimgSize[0]), int.Parse(SimgSize[1])), 0, 0, watermark.Width, watermark.Height, GraphicsUnit.Pixel, imageAttributes);
watermark.Dispose();
imageAttributes.Dispose();
}
/// <summary>
/// 压缩图片(缩略)
/// </summary>
/// <param name="imgPath">图片的绝对路径</param>
/// <param name="newImgPath">要保存的新图片路径</param>
/// <returns></returns>
public static string PressImg(string imgPath, string newImgPath, int ImgsNum)
{
String fileExt = System.IO.Path.GetExtension(imgPath);//获取图片文件扩展名,如.png,.jpg,.gif等
String fileName = System.IO.Path.GetFileNameWithoutExtension(imgPath);
//加载图片
System.Drawing.Image image = System.Drawing.Image.FromStream(new System.IO.MemoryStream(System.IO.File.ReadAllBytes(imgPath)));
string[] getWh = calculateImgSize(120, 120, ImgsNum).Split(',');//获取生成新的单幅图片的尺寸
//生成压缩后的图片
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(int.Parse(getWh[0]), int.Parse(getWh[1]));
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
System.Drawing.Rectangle rectDestination = new System.Drawing.Rectangle(0, 0, int.Parse(getWh[0]), int.Parse(getWh[1]));
g.DrawImage(image, rectDestination, 0, 0, image.Width, image.Height, System.Drawing.GraphicsUnit.Pixel);
newImgPath = newImgPath + fileName + "_new" + ".png";//拼接为新的路径和文件扩展名
bmp.Save(newImgPath);
bmp.Dispose();
image.Dispose();
return newImgPath;
}
/// <summary>
/// 根据合成后图片宽高以及要拼合图片的数量计算单幅图片的尺寸
/// </summary>
/// <param name="Width">合成后完整图片的宽度</param>
/// <param name="Height">合成后完整图片的高度</param>
/// /// <param name="imgNum">小图片总数</param>
/// <returns></returns>
public static string calculateImgSize(int Width, int Height, int imgNum)
{
int sImgHeight = 1;//设定小图片的初始高为1像素;
int sImgWidth = 1;//设定小图片的初始宽为1像素;
//如果图片总数为3-5张(不包含5),则图片为正方形,图片为总高的1/2
if (imgNum >= 3 && imgNum < 5)
{
sImgHeight = int.Parse(Math.Round((float)Height / 2 - 2).ToString());//压缩单幅图片的高度
sImgWidth = int.Parse(Math.Round((float)Width / 2 - 2).ToString());//压缩单幅图片的宽度
}
else if (imgNum >= 5 && imgNum <= 9)//如果图片在5-9张,则宽高分别为拼合后大图的1/3,要空余2像素的结合部宽度
{
sImgHeight = int.Parse(Math.Round((float)Height / 3 - 2).ToString());//压缩单幅图片的高度
sImgWidth = int.Parse(Math.Round((float)Width / 3 - 2).ToString());//压缩单幅图片的宽度
}
string SizeStr = sImgWidth + "," + sImgHeight;
return SizeStr;
}
/// <summary>
/// 根据传入的目标图片的宽、高以及文件路径,创建一副白色底的空白背景图片
/// </summary>
/// <param name="w">预创建图片的宽度</param>
/// <param name="h">预创建图片的高度</param>
/// <param name="WhiteImgPath">预创建的空白图片的完整文件路径</param>
/// <returns></returns>
public static string createWhiteImg(int w, int h, string WhiteImgPath)
{
//生成压缩后的图片
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(w, h);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp);
Rectangle rect = new Rectangle();
rect.Width = 120; rect.Height = 120;
g.FillRectangle(Brushes.WhiteSmoke, rect);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
System.Drawing.Rectangle rectDestination = new System.Drawing.Rectangle(0, 0, w, h);
WhiteImgPath += "bg" + DateTime.Now.ToString().Replace("/", "").Replace(":", "").Replace(" ", "") + ".png";//拼接为新的路径和文件扩展名
bmp.Save(WhiteImgPath);
bmp.Dispose();
return WhiteImgPath;
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话