现在微信群越来越多了,群主为了增进群成员的归属感和互动也是想尽了办法。我参加IP潜能营有3周了,期间发现了Jesse1981的一篇文章,她用了多种程序和工具生成了一张群头像全家福的海报。

图片来自IP训练营

我看过之后,发现要把几百个头像排成漂亮的环形,工作量还是蛮大的,所以马上动手写了一款C#程序,可以极大地减轻群主的工作量。程序的实现原理比较简单,直接给出源代码。

// 裁剪图片到圆形内
public static void CropImageToCircle(string src, Color backColor, string dst)
{
    using (Image srcImage = Image.FromFile(src))
    {
        int width = srcImage.Width;
        int height = srcImage.Height;

        using (Bitmap dstImage = new Bitmap(width, height, PixelFormat.Format24bppRgb))
        {
            using (Graphics g = Graphics.FromImage(dstImage))
            {
                // 填充背景色
                g.Clear(backColor);
                // 设置裁剪区域为圆形
                using (GraphicsPath path = new GraphicsPath())
                {
                    path.AddEllipse(0, 0, width, height);
                    g.SetClip(path);
                }
                // 绘制源图像
                g.DrawImage(srcImage, 0, 0, width, height);
            }
            dstImage.MakeTransparent(backColor);
            dstImage.Save(dst, ImageFormat.Png);
        }
    }
}

C#控制台的主程序:

private static void Main(string[] args)
{
    Console.WriteLine("请将头像文件放在images文件夹下");

    string[] imageFiles = Directory.GetFiles("images\\", "*.*", SearchOption.AllDirectories)
                                    .Where(file => Path.GetExtension(file).ToLower() == ".jpg" || Path.GetExtension(file).ToLower() == ".png")
                                    .ToArray();
    Console.WriteLine("头像个数:" + imageFiles.Length);

    // 裁剪为圆形的图像放在crop文件夹下,先保证这个文件夹存在
    if (!Directory.Exists("crop"))
    {
        Directory.CreateDirectory("crop");
    }

    int rings = (int)Math.Ceiling((-23 + Math.Sqrt(23 * 23 + 56 * imageFiles.Length)) / 14.0); // 圆环的个数
    int width = (1 + rings) * 66 * 2 + 186;
    int height = (1 + rings) * 66 * 2 + 186;
    Bitmap bmp = new Bitmap(width, height);
    using (Graphics g = Graphics.FromImage(bmp))
    {
        int x0 = width / 2;
        int y0 = height / 2;
        int ringImgs = 15;   // 圆环内的头像个数
        int count = 0;

        for (int R = 159; R < width / 2; R += 66) // 每一圈的半径
        {
            for (int i = 0; i < ringImgs; i++)
            {
                string imgFile = imageFiles[count];
                Console.WriteLine(imgFile);
                string cropFile = string.Format("crop\\crop-{0}.png", count);
                CropImageToCircle(imgFile, Color.BlueViolet, cropFile);
                using (Image img = Image.FromFile(cropFile))
                {
                    double x = x0 + R * Math.Cos(2.0 / ringImgs * i * Math.PI - Math.PI / 2);
                    double y = y0 + R * Math.Sin(2.0 / ringImgs * i * Math.PI - Math.PI / 2);
                    g.DrawImage(img, (int)(x + 0.5) - 33, (int)(y + 0.5) - 33, 66, 66);
                    g.DrawEllipse(Pens.White, (int)(x + 0.5) - 32, (int)(y + 0.5) - 32, 64, 64);
                }

                if (++count >= imageFiles.Length) break;
            }
            ringImgs += 7; //每向外增加一圈,头像个数要增加
        }
    }
    bmp.Save("group-avatar.jpg", ImageFormat.Jpeg);
    bmp.Save("group-avatar.png", ImageFormat.Png);
    Console.WriteLine("\n");
    Console.WriteLine("输出的群头像全家福文件:" + "group-avatar.jpg");
    Console.WriteLine("输出的群头像全家福文件:" + "group-avatar.png");
    Console.WriteLine("程序说明: http://shenlb.me/avatar");
 
    Console.WriteLine("按任意键退出本程序...");
    Console.ReadKey();
}

程序下载及运行环境要求:

(1)如果你不会使用C#,可以点此下载程序,用winrar或7zip等软件解压缩到台式机的一个文件夹下,比如:d:\shenlb\avatar。

(2)本程序只能在Windows 10的台式机中运行,不能在手机上运行。

(3)需要Windows .NET Framework 4.8的支持,一般的机器上都有这个环境;如果运行出错,请到微软官方网站下载.NET Framework 4.8安装包

程序使用说明:

(1)先参考Jesse1981的教程下载所有头像

(2)所有头像图片全部放在images子文件夹下

(3)运行avatar.exe程序,几秒钟后,群头像全家福就生成好了,海报文件名为group-avatar.jpg

下面这张就是我为IP潜能营做的群头像全家福(感谢群成员楠子的大力支持,她帮我下载了全部头像图片)。