引用:SixLabors.ImageSharp,SixLabors.ImageSharp.Drawing,System.Drawing.Common

   /// <summary>
/// 群组图片合并
/// </summary>
public static class ImageSharpHelper
{
/// <summary>
/// 背景图片缩略图大小
/// </summary>
public static int BackHeigth = ; #region 获取合并后的图片
/// <summary>
/// 获取合并后的图片
/// </summary>
/// <param name="ImageFile">要合并的图片路径</param>
/// <returns></returns>
public static ApiResult GetImageSharp(List<string> ImageFile)
{
if (ImageFile.Count <= || ImageFile.Count > )
{
return ApiResult.Fail(ApiEnum.OtherError, "合并的图片只能2到9张");
} //背景图
var aBase64Str = @"iVBORw0KGgoAAAANSUhEUgAAALEAAACxCAIAAAAES8uSAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkE4OTBFNDM1OTMwQjExRTlBN0ZBOTQyQzFCQjg0MzRBIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkE4OTBFNDM2OTMwQjExRTlBN0ZBOTQyQzFCQjg0MzRBIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QTg5MEU0MzM5MzBCMTFFOUE3RkE5NDJDMUJCODQzNEEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QTg5MEU0MzQ5MzBCMTFFOUE3RkE5NDJDMUJCODQzNEEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7toEL7AAABQ0lEQVR42uzSQREAAAQAQfRPoiRfHexGuLmcDrhKAjyBJ/AEnsATeAJP4Ak8gSfwBJ7AE3gCT+AJ8ASewBN4Ak/gCTyBJ/AEnsATeAJP4Ak8gSfAE3gCT+AJPIEn8ASewBN4Ak/gCTyBJ/AEngBP4Ak8gSfwBJ7AE3gCT+AJPIEn8ASewBN4AjyBJ/AEnsATeAJP4Ak8gSfwBJ7AE3gCT+AJ8ASewBN4Ak/gCTyBJ/AEnsATeAJP4Ak8gSfAE3gCT+AJPIEn8ASewBN4Ak/gCTyBJ/AEngBP4Ak8gSfwBJ7AE3gCT+AJPIEn8ASewBN4Ak9IgCfwBJ7AE3gCT+AJPIEn8ASewBN4Ak/gCTwBnsATeAJP4Ak8gSfwBJ7AE3gCT+AJPIEn8AR4Ak/gCTyBJ/AEnsATeAJP4Ak8gSfwBI+sAAMAmMcDC6uBzccAAAAASUVORK5CYII="; List<byte[]> list = new List<byte[]>();
foreach (var item in ImageFile)
{
list.Add(GetImageByte(item));
}
return ImageCaoByte(Convert.FromBase64String(aBase64Str), list);
}
#endregion #region 合并图片 base64 List集合
/// <summary>
/// 合并图片 base64 List集合
/// </summary>
/// <param name="backBase64">背景图片</param>
/// <param name="ListBase64">合成图片集合</param>
/// <returns></returns>
public static ApiResult ImageCaoBase64(string backBase64, List<string> ListBase64)
{
List<byte[]> list = new List<byte[]>();
foreach (var item in ListBase64)
{
list.Add(Convert.FromBase64String(item));
}
return ImageCaoByte(Convert.FromBase64String(backBase64), list);
#region 单张测试
//byte[] templebytes = Convert.FromBase64String(aBase64Str);
//byte[] outputbytes = Convert.FromBase64String(bBase64Str); //System.Drawing.Image temple = MakeThumbnail(templebytes, 200, 200, ThumbnailMode.Cut);
//System.Drawing.Image output = MakeThumbnail(outputbytes, 100, 100, ThumbnailMode.Cut); //var templeNailByte = ImgToByt(temple);
//var outputNailByte = ImgToByt(output); //IImageFormat format = null;
//Image<Rgba32> templeRgba32= SixLabors.ImageSharp.Image.Load(templeNailByte, out format);
//Image<Rgba32> outputRgba32 = SixLabors.ImageSharp.Image.Load(outputNailByte); //var result = MergeImageRgba32(templeRgba32, outputRgba32, 0, 0, format);
//return result;
#endregion
}
#endregion #region 合并图片 字节 List集合
/// <summary>
/// 合并图片 字节 List集合
/// </summary>
/// <param name="backBase64">背景图片</param>
/// <param name="ListBase64">合成图片集合</param>
/// <returns></returns>
public static ApiResult ImageCaoByte(byte[] backBase64, List<byte[]> ListBase64)
{
//base64转字节
byte[] templebytes = backBase64;// Convert.FromBase64String(backBase64);
//缩略图
System.Drawing.Image temple = MakeThumbnail(templebytes, BackHeigth, BackHeigth, ThumbnailMode.Cut);
//图片转字节
byte[] templeNailByte = ImgToByt(temple); ApiResult result = ApiResult.Fail(ApiEnum.OtherError, "请求失败"); var ListCount = ListBase64.Count;
for (int i = ; i < ListCount; i++)
{
byte[] outputbytes = ListBase64[i];
System.Drawing.Image output = MakeThumbnail(outputbytes, SizeWidth(ListCount, BackHeigth), SizeHeight(ListCount, BackHeigth), ThumbnailMode.Cut);
byte[] outputNailByte = ImgToByt(output);
Image<Rgba32> outputRgba32 = SixLabors.ImageSharp.Image.Load(outputNailByte); //背景图
IImageFormat format = null;
Image<Rgba32> templeRgba32 = SixLabors.ImageSharp.Image.Load(templeNailByte, out format);
//合并图片
result = MergeImageRgba32(templeRgba32, outputRgba32, XWidth(ListCount, i + , BackHeigth), YHeight(ListCount, i + , BackHeigth), format); if (i < ListCount - && result.Status)
{
var str = result.Data.ToString();
var dataBase64 = str.Substring(str.IndexOf(',') + );
templeNailByte = Convert.FromBase64String(dataBase64);
}
}
return result;
}
#endregion #region 合并图片 小图片放在大图片上面 MergeImageBase64
/// <summary>
/// 合并图片 小图片放在大图片上面 MergeImageBase64
/// </summary>
/// <param name="TempleBase64Str">模板大图片base64</param>
/// <param name="OutputBase64Str">模板小图片base64</param>
/// <param name="x">X坐标</param>
/// <param name="y">y坐标</param>
/// <returns></returns>
public static ApiResult MergeImageBase64(string TempleBase64Str, string OutputBase64Str, int x, int y)
{
string strRet = null;
if (string.IsNullOrEmpty(TempleBase64Str))
{
return ApiResult.Fail(ApiEnum.ParameterError, "请传入模板大图片base64");
}
if (string.IsNullOrEmpty(OutputBase64Str))
{
return ApiResult.Fail(ApiEnum.ParameterError, "请传入模板小图片base64");
}
if (x < || y < )
{
return ApiResult.Fail(ApiEnum.ParameterError, "坐标不能传入负数");
}
try
{
byte[] templebytes = Convert.FromBase64String(TempleBase64Str);
byte[] outputbytes = Convert.FromBase64String(OutputBase64Str);
IImageFormat format = null;
var imagesTemle = SixLabors.ImageSharp.Image.Load(templebytes, out format);
var outputImg = SixLabors.ImageSharp.Image.Load(outputbytes); if (imagesTemle.Height - (outputImg.Height + y) <= )
{
return ApiResult.Fail(ApiEnum.ParameterError, "Y坐标高度超限");
}
if (imagesTemle.Width - (outputImg.Width + x) <= )
{
return ApiResult.Fail(ApiEnum.ParameterError, "X坐标宽度超限");
}
//进行多图片处理
imagesTemle.Mutate(a =>
{
//还是合并
a.DrawImage(outputImg, new SixLabors.Primitives.Point(x, y), );
});
strRet = imagesTemle.ToBase64String(format);
return ApiResult.Success(strRet);
}
catch (Exception ex)
{
return ApiResult.Fail(ApiEnum.ParameterError, "报错信息" + ex.Message);
}
}
#endregion #region 合并图片 小图片放在大图片上面 MergeImageRgba32
/// <summary>
/// 合并图片 小图片放在大图片上面 MergeImageRgba32
/// </summary>
/// <param name="TempleByte">模板大图片Byte</param>
/// <param name="OutputBaseByte">模板小图片Byte</param>
/// <param name="x">X坐标</param>
/// <param name="y">y坐标</param>
/// <param name="format">format</param>
/// <returns></returns>
public static ApiResult MergeImageRgba32(Image<Rgba32> TempleByte, Image<Rgba32> OutputBaseByte, int x, int y, IImageFormat format)
{
string strRet = null;
if (x < || y < )
{
return ApiResult.Fail(ApiEnum.ParameterError, "坐标不能传入负数");
}
try
{
var imagesTemle = TempleByte;
var outputImg = OutputBaseByte; if (imagesTemle.Height - (outputImg.Height + y) < )
{
return ApiResult.Fail(ApiEnum.ParameterError, "Y坐标高度超限");
}
if (imagesTemle.Width - (outputImg.Width + x) < )
{
return ApiResult.Fail(ApiEnum.ParameterError, "X坐标宽度超限");
}
//进行多图片处理
imagesTemle.Mutate(a =>
{
//还是合并
a.DrawImage(outputImg, new SixLabors.Primitives.Point(x, y), );
});
strRet = imagesTemle.ToBase64String(format);
return ApiResult.Success(strRet, "成功");
}
catch (Exception ex)
{
return ApiResult.Fail(ApiEnum.ParameterError, "报错信息" + ex.Message);
}
}
#endregion #region 生成缩略图
/// <summary>
/// 生成缩略图
/// </summary>
/// <param name="imgBytes">源文件字节数组</param>
/// <param name="width">缩略图宽度</param>
/// <param name="height">缩略图高度</param>
/// <param name="mode">缩略图方式</param>
public static System.Drawing.Image MakeThumbnail(byte[] imgBytes, int width, int height, ThumbnailMode mode)
{
using (var sourceImage = FromBytes(imgBytes))
{
return MakeThumbnailThis(sourceImage, width, height, mode);
}
} /// <summary>
/// 生成缩略图
/// </summary>
/// <param name="sourceImage">源图</param>
/// <param name="width">缩略图宽度</param>
/// <param name="height">缩略图高度</param>
/// <param name="mode">缩略图方式</param>
public static System.Drawing.Image MakeThumbnailThis(System.Drawing.Image sourceImage, int width, int height, ThumbnailMode mode)
{
var towidth = width;
var toheight = height; var x = ;
var y = ;
var ow = sourceImage.Width;
var oh = sourceImage.Height; switch (mode)
{
case ThumbnailMode.FixedBoth:
break;
case ThumbnailMode.FixedW:
toheight = oh * width / ow;
break;
case ThumbnailMode.FixedH:
towidth = ow * height / oh;
break;
case ThumbnailMode.Cut:
if (ow / (double)oh > towidth / (double)toheight)
{
oh = sourceImage.Height;
ow = sourceImage.Height * towidth / toheight;
y = ;
x = (sourceImage.Width - ow) / ;
}
else
{
ow = sourceImage.Width;
oh = sourceImage.Width * height / towidth;
x = ;
y = (sourceImage.Height - oh) / ;
}
break;
}
//1、新建一个BMP图片
var bitmap = new Bitmap(towidth, toheight);
//2、新建一个画板
var g = Graphics.FromImage(bitmap);
try
{
//3、设置高质量插值法
g.InterpolationMode = InterpolationMode.High;
//4、设置高质量,低速度呈现平滑程度
g.SmoothingMode = SmoothingMode.HighQuality;
//5、清空画布并以透明背景色填充
g.Clear(Color.Transparent);
//6、在指定位置并且按指定大小绘制原图片的指定部分
g.DrawImage(sourceImage, new Rectangle(, , towidth, toheight), new Rectangle(x, y, ow, oh),
GraphicsUnit.Pixel);
return bitmap;
}
catch (Exception e)
{
throw e;
}
finally
{
g.Dispose();
}
}
#endregion #region 字节转换成图片流
/// <summary>
/// 字节转换成图片流
/// </summary>
/// <param name="bytes">字节数组</param>
/// <returns></returns>
public static System.Drawing.Image FromBytes(byte[] bytes)
{
using (var ms = new MemoryStream(bytes))
{
return System.Drawing.Image.FromStream(ms);
}
}
#endregion #region 图片流转换成字节
/// <summary>
/// 图片流转换成字节
/// </summary>
/// <param name="img">要转换的Image对象</param>
/// <returns>转换后返回的字节流</returns>
public static byte[] ImgToByt(System.Drawing.Image img)
{
MemoryStream ms = new MemoryStream();
byte[] imagedata = null;
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
imagedata = ms.GetBuffer();
return imagedata;
}
#endregion #region 根据http图片路径返回图片的字节流byte[]
/// <summary>
/// 根据http图片路径返回图片的字节流byte[]
/// </summary>
/// <param name="imagePath">图片路径</param>
/// <returns>返回的字节流</returns>
public static byte[] GetImageByte(string imagePath)
{
WebClient client = new WebClient();
byte[] pageData = client.DownloadData(imagePath);
return pageData;
}
#endregion #region 根据本机图片路径返回图片的字节流byte[]
/// <summary>
/// 根据本机图片路径返回图片的字节流byte[]
/// </summary>
/// <param name="imagePath">图片路径</param>
/// <returns>返回的字节流</returns>
public static byte[] GetImageByteIam(string imagePath)
{
FileStream files = new FileStream(imagePath, FileMode.Open);
byte[] imgByte = new byte[files.Length];
files.Read(imgByte, , imgByte.Length);
files.Close();
return imgByte;
}
#endregion #region 获取小的缩略图高度
/// <summary>
/// 获取小的缩略图高度
/// </summary>
/// <param name="Sum">总张数</param>
/// <param name="BackHeigth">背景图片的大小</param>
/// <returns></returns>
public static int SizeHeight(int Sum, int BackHeigth)
{
if (Sum <= )
{
return BackHeigth / ;
}
else if (Sum > && Sum <= )
{
return BackHeigth / ;
}
return ;
}
#endregion #region 获取小的缩略图宽度
/// <summary>
/// 获取小的缩略图宽度
/// </summary>
/// <param name="Sum">总张数</param>
/// <param name="BackWidth">背景图片的大小</param>
/// <returns></returns>
public static int SizeWidth(int Sum, int BackWidth)
{
if (Sum <= )
{
return BackHeigth / ;
}
else if (Sum > && Sum <= )
{
return BackHeigth / ;
}
return ;
}
#endregion #region 获取X坐标点
/// <summary>
/// 获取X坐标点
/// </summary>
/// <param name="Sum">总张数</param>
/// <param name="Several">第几张图片</param>
/// <param name="BackHeigth">背景图片的大小</param>
/// <returns></returns>
public static int XWidth(int Sum, int Several, int BackHeigth)
{
if (Sum == )
{
return (Several - ) * (BackHeigth / );
}
else if (Sum > && Sum <= )
{
if (Several % == )
{
return ;
}
else
{
return BackHeigth / ;
}
}
else if (Sum > && Sum <= )
{
if (Several % == )
{
return ;
}
else if (Several % == )
{
return BackHeigth / ;
}
else
{
return (BackHeigth / ) * ;
}
}
return ;
}
#endregion #region 获取Y坐标点
/// <summary>
/// 获取Y坐标点
/// </summary>
/// <param name="Sum">总张数</param>
/// <param name="Several">第几张图片</param>
/// <param name="BackHeigth">背景图片的大小</param>
/// <returns></returns>
public static int YHeight(int Sum, int Several, int BackHeigth)
{
if (Sum == )
{
return BackHeigth / ;
}
else if (Sum > && Sum <= )
{
if (Several <= )
{
return ;
}
else
{
return BackHeigth / ;
}
}
else if (Sum > && Sum <= )
{
if (Several <= )
{
return BackHeigth / ;
}
else
{
return BackHeigth / ;
}
}
else if (Sum > && Sum <= )
{
if (Several <= )
{
return ;
}
else if (Several > && Several <= )
{
return BackHeigth / ;
}
else
{
return (BackHeigth / ) * ;
}
}
return ;
}
#endregion
}
/// <summary>
/// 缩略图模式
/// </summary>
public enum ThumbnailMode
{
/// <summary>
/// 指定宽高裁剪(不变形)
/// </summary>
Cut = ,
/// <summary>
/// 指定宽度,高度自动
/// </summary>
FixedW = ,
/// <summary>
/// 指定高度,宽度自动
/// </summary>
FixedH = ,
/// <summary>
/// 指定宽高(变形)
/// </summary>
FixedBoth =
}

.net core微信群图片合并的更多相关文章

  1. 一行实现QQ群组头像,微信群组,圆角等效果. 并支持url直接加载图片

    说点题外话. Coding中我们总是经历着这么几个过程. 学会使用: 不管是API也好, 开源库也好. 总是在最开始的学会去用. 了解实现原理: 可能会因为一些不兼容, 代码的异常状态的处理不够完美等 ...

  2. PHP 图片合成、仿微信群头像

    PHP 图片合成.仿微信群头像 参考文章: 作者:凯歌~,php图片合成方法(多张图片合成一张). 经过测试,略作调整和注释,感谢分享. 欢迎提出改善优化意见! 示例代码: /** * 合成图片 * ...

  3. Python如何实现微信群万人同步直播?

    很多人传言微信网页版(https://wx.qq.com/)接口已经被封了,所以所有的微信都不能登录网页版,这是错误的. 2019年7月微信对网页版微信进行了动态安全策略调整,导致一大批微信号不能登录 ...

  4. 微信群打卡机器人XiaoV项目开源 | 蔡培培的独立博客

    原文首发于蔡培培的独立博客.原文链接<微信群打卡机器人XiaoV项目开源>. 5月21日,在米花(后面" 亚里士多德式友谊"专题会提及)的影响下,决定搞个私人运动群,拉 ...

  5. 微信群API接口

    安卓微信的api,个人微信开发API协议,微信 ipad sdk,微信ipad协议,微信web版接口api,微信网页版接口,微信电脑版sdk,微信开发sdk,微信开发API,微信协议,微信接口文档sd ...

  6. 微信群里一道六年级数学题,求阴影面积,那我只能用python代码了

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取http ...

  7. 利用python在微信群中签到、抢沙发(适用于任何账号)

    利用python在微信群中签到.抢沙发 注意 程序仅能在电脑上运行,运行时需要保证群界面在最前端且不被移动. 背景 我是一名高中生(2020年),疫情期间,在家上网课,有的老师让我们在班群里签到. 其 ...

  8. Android微信分享图片大于32k进行压缩

    微信分享视频的时候,需要传一个图片数组,大小不能大于32k. 解决方案:使用Bitmap自带的compress方法解决了这个问题. 源码如下: <span style="font-si ...

  9. 今天微信群需要人家通过吗?是微信bug吗

    今天遇到微信群拉人的问题,所以来和大家取经,刚开始拉人一下就拉进去了,后来拉的需要人家通过,今天朋友些也帮我拉人也是这样的,所以想问下微信群扩容的问题.晚上有位朋友跟我说一次拉十个人,不能拉多,这样就 ...

随机推荐

  1. 【DataBase】H2 DateBase的拓展使用

    连接模式 支持以下连接模式: 嵌入模式(使用JDBC的本地连接) 服务器模式(使用JDBC或ODBC over TCP / IP进行远程连接) 混合模式(同时本地和远程连接) 嵌入模式 在嵌入模式下, ...

  2. Hadoop记录-部署hadoop环境shell实现

    #!/bin/bash menu() { echo "---欢迎使用hadoop部署管理程序---" echo "# 1.初始化Linux环境" echo &q ...

  3. c#中多线程同步Lock(锁)的研究以及跨线程UI的操作 (转)

    https://www.cnblogs.com/tommyheng/p/4104552.html 本文只针对C#中,多线程同步所用到的锁(lock)作为研究对象.由于想更直观的显示结果,所以,在做de ...

  4. 用easymock来mock数据

    昨天学习微信小程序了解了一个模拟数据的工具EasyMock,一早到公司就使用试试. 1.创建项目: 创建好如下所示: 2.创建接口: 点击右下角+号按钮即可. 操作栏依次是:预览,编辑,链接,更多操作 ...

  5. laravel5.1框架model类查询实现

    laravel框架model类查询实现: User::where(['uid'=8])->get(); User类继承自Model类:Illuminate\Database\Eloquent\M ...

  6. 【WAP触屏】YouKu视频弹窗播放组件

    (function(window){ /* youku api : http://open.youku.com/tools 调用方法 : LM_youkuPop.open('XODI5Mzk3MDAw ...

  7. Red Team远程控制软件

    开源远程管理控制 https://github.com/malwaredllc/byob 僵尸网络生成框架 https://github.com/panda-re/lava 大规模向程序中植入恶意程序 ...

  8. redis 部署

    wget http://download.redis.io/releases/redis-4.0.14.tar.gz tar -zxvf redis-4.0.14.tar.gz mv redis-4. ...

  9. 【GStreamer开发】GStreamer播放教程09——数字音频传输

    目标 本教程展示GStreamer是如何进行数字音频传输的. 介绍 在常见的模拟格式外,高端的音频系统通常都接受数字格式,压缩的非压缩的都能接受.因为音频信号是从电脑传到音箱,用一种更有弹性的形态会更 ...

  10. Appium移动自动化测试-----(十二)appium API 之 TouchAction 操作

    Appium的辅助类,主要针对手势操作,比如滑动.长按.拖动等. 1.按压控件 方法: press() 开始按压一个元素或坐标点(x,y).通过手指按压手机屏幕的某个位置. press(WebElem ...