一、需求概述
多人聊天(群组,讨论组,聊天室,以下统称: “群组” )生成一个拼接头像,需要把最先加入群组的几个人(最多4个人,以下简称:头部用户,A、B、C、D)的头像拼凑成在一起。
群组创建后,A、B、C、D其中任何一个修改了自己的头像,需要 "异步" 更新群组头像。
以上是简单的需求描述。
本文使用.net core实现了N张图片拼接算法。
完整代码点击:https://github.com/night-king/ImageMerge
二、方案实现探讨
本需求可以在服务端实现,也可以在客户端实现。
(1)服务端实现:
群组创建时,下载A、B、C、D的头像,然后合并即可;
头部用户修改头像后,后台任务刷新群组头像。
(2)客户端实现:客户端包括iOS,Android,React,Web。
情况有些复杂,所以最后决定直接采用服务端实现。
Github上搜索无果,只能自己动手完成了。
先看效果:
采用四位Github大神头像作为源图片:
结果如下:
三、解决方案
群组2个用户,3个用户,4个以及以上用户头像不一样,总结如下:
/// <summary> /// 合并布局枚举 /// </summary> public enum Merge2LayoutEnum { /// <summary> /// 2张图片,上下各1个长方形 /// ——————————————————— /// | | /// | R1 | /// | | /// ——————————————————— /// | | /// | R2 | /// | | /// ——————————————————— /// </summary> Merge2R1 = 1, /// <summary> /// 2张图片,左右各1个长方形 /// ——————————————————— /// | | | /// | | | /// | | | /// | R1 | R2 | /// | | | /// | | | /// | | | /// ——————————————————— /// </summary> Merge2R2 = 2 } public enum Merge3LayoutEnum { /// <summary> /// 3张图片, 上面一个长方形,下面2个正方形并排 /// ——————————————————— /// | | /// | R1 | /// | | /// ——————————————————— /// | | | /// | S1 | S2 | /// | | | /// ——————————————————— /// </summary> Merge1R2S1 = 3, /// <summary> /// 3张图片,上面2个正方形并排,下面一个长方形 /// ——————————————————— /// | | | /// | S1 | S2 | /// | | | /// ——————————————————— /// | | /// | R1 | /// | | /// ——————————————————— /// </summary> Merge1R2S2 = 4, /// <summary> /// 3张图片,上面2个正方形并排,下面一个长方形 /// ——————————————————— /// | | | /// | | S1 | /// | | | /// | R1 |————————— /// | | | /// | | S2 | /// | | | /// ——————————————————— /// </summary> Merge1R2S3 = 5, /// <summary> /// 3张图片,上面2个正方形并排,下面一个长方形 /// ——————————————————— /// | | | /// | S2 | | /// | | | /// |—————————| R1 | /// | | | /// | S2 | | /// | | | /// ——————————————————— /// </summary> Merge1R2S4 = 6 } public enum Merge4LayoutEnum { /// <summary> /// 4张图片,上面一个长方形,下面2个正方形并排 /// ——————————————————— /// | | | /// | S1 | S2 | /// | | | /// ——————————————————— /// | | | /// | S3 | S4 | /// | | | /// ——————————————————— /// </summary> Merge4S = 7 }
以下是2张图片实现代码:
/// <summary>
/// 合并2张图片
/// </summary>
/// <param name="image1"></param>
/// <param name="image2"></param>
/// <param name="layout"></param>
/// <returns></returns>
public static Image Merge2Images(Image image1, Image image2, Merge2LayoutEnum layout = Merge2LayoutEnum.Merge2R1, int size = 250)
{
var width = size;
var height = size;
var pf = PixelFormat.Format32bppArgb;
using (var bg = new Bitmap(width, height, pf))
{
using (var g = Graphics.FromImage(bg))
{
g.FillRectangle((Brush)Brushes.White, 0, 0, width, height);//全幅背景为白色
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
switch (layout)
{
/// <summary>
/// 2张图片,上下各1个长方形
/// ———————————————————
/// | |
/// | R1 |
///