引用: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. Windows安装Redis并添加本地自启动服务并解决客户端dll报错

    参考文章:https://blog.csdn.net/realjh/article/details/82026160 Redis下载: https://github.com/MicrosoftArch ...

  2. Docker 记一次 docker-compose 完整实践(转)

    本文介绍docker-compose实践时的一些疑问与解决方案, 可能对新手略有帮助, 因此整理成文. 有不妥之处欢迎指摘! Q1: docker-compose 如何安装? A1: https:// ...

  3. DataSource接口 Connection pooling(连接池

    一.DataSource接口是一个更好的连接数据源的方法:  JDBC1.0是原来是用DriverManager类来产生一个对数据源的连接.JDBC2.0用一种替代的方法,使用DataSource的实 ...

  4. ISO/IEC 9899:2011 条款6.7.7——类型名

    6.7.7 类型名 语法 1.type-name: specifier-qualifier-list    abstract-declaratoropt abstract-declarator: po ...

  5. Python3基础 continue while循环示例

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  6. 多重if结构

    package com.imooc; import java.util.Scanner; public class TypeExchange { public static void main(Str ...

  7. android webview带cookie访问url

    问题描述在原生和h5混合开发的时候会遇到这么一个问题,用webview加载某个url时,你只是app登录了账号,但是网页却没有,所有会禁止访问此url,webview就会显示白屏.所以要访问此url, ...

  8. Linux的桌面虚拟化技术KVM(二)——远程桌面管理

    Linux的桌面虚拟化技术KVM(一)——新建KVM虚拟机 远程桌面管理,指的是远程图形界面管理,所以要保证物理机要有图形化界面. (1).VNC管理 安装VNC-server服务,并进行配置 [ro ...

  9. Linux系统调优——网络(四)

    (1).查看网络(Network)运行状态相关工具 1)nload监控总体带宽使用情况 nload需要自己安装,而且在安装前需要安装epel-release [root@youxi1 ~]# yum ...

  10. Sound (audio file) player in java - working source code example

    转载自:http://ganeshtiwaridotcomdotnp.blogspot.com/2011/12/sound-audio-file-player-in-java-working.html ...