zoukankan      html  css  js  c++  java
  • C# 绘制印章

      最近有个.net core的项目要绘制印章功能,一个公司印章,一个个人印章,于是抽了点时间自己写了一个,现在分享出来    

    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Text;
    
    namespace DemoConsole
    {
        public class SealHelper
        {
            public static MechanismSealHelper Mechanism()
            {
                return new MechanismSealHelper();
            }
            public static PersonalSealHelper Personal()
            {
                return new PersonalSealHelper();
            }
            public class MechanismSealHelper : IDisposable
            {
                string star = "";
                int size = 160;
                Image map;
                Graphics g;
                int defaultWidth;
                float defaultStarSize;
                float defaultTitleSize;
                float defaultHorizontalSize;
                float defaultChordSize;
    
                public Color Color { get; set; } = Color.Red;
                public string DefaultFontName { get; set; } = "SimSun";
    
                public MechanismSealHelper()
                {
                    map = new Bitmap(size, size);
                    g = Graphics.FromImage(map);//实例化Graphics类
                    g.SmoothingMode = SmoothingMode.AntiAlias;  //System.Drawing.Drawing2D;           
                    g.Clear(Color.Transparent);
    
                    defaultWidth = size / 40;
                    defaultStarSize = size / 5;
                    defaultTitleSize = (float)Math.Sqrt(size);
                    defaultHorizontalSize = (float)Math.Sqrt(size);
                    defaultChordSize = size / 20;
                }
    
                /// <summary>
                /// 绘制圆
                /// </summary>
                public void DrawCircle()
                {
                    DrawCircle(defaultWidth);
                }
                /// <summary>
                /// 绘制圆
                /// </summary>
                /// <param name="width">画笔粗细</param>
                public void DrawCircle(int width)
                {
                    Rectangle rect = new Rectangle(width, width, size - width * 2, size - width * 2);//设置圆的绘制区域
                    Pen pen = new Pen(Color, width);  //设置画笔(颜色和粗细)
                    g.DrawEllipse(pen, rect);  //绘制圆
                }
                /// <summary>
                /// 绘制星星
                /// </summary>
                public void DrawStar()
                {
                    DrawStar(defaultStarSize, defaultWidth);
                }
                /// <summary>
                /// 绘制星星
                /// </summary>
                /// <param name="emSize"></param>
                public void DrawStar(float emSize)
                {
                    DrawStar(emSize, defaultWidth);
                }
                /// <summary>
                /// 绘制星星
                /// </summary>
                /// <param name="emSize">字体大小</param>
                /// <param name="width">画笔粗细</param>
                public void DrawStar(float emSize, int width)
                {
                    Font starFont = new Font(DefaultFontName, emSize, FontStyle.Bold);//设置星号的字体样式
                    var starSize = g.MeasureString(star, starFont);//对指定字符串进行测量
                                                                   //要指定的位置绘制星号
                    PointF starXy = new PointF(size / 2 - starSize.Width / 2, size / 2 - starSize.Height / 2);
                    g.DrawString(star, starFont, new SolidBrush(Color), starXy);
                }
    
                /// <summary>
                /// 绘制主题
                /// </summary>
                /// <param name="title">主题(公司名称)</param>
                /// <param name="startAngle">开始角度</param>
                public void DrawTitle(string title, float startAngle = 160)
                {
                    DrawTitle(title, startAngle, defaultTitleSize);
                }
                /// <summary>
                /// 绘制主题
                /// </summary>
                /// <param name="title">主题(公司名称)</param>
                /// <param name="startAngle">开始角度,必须是左半边,推荐(135-270)</param>
                /// <param name="emSize">字体大小</param>
                public void DrawTitle(string title, float startAngle, float emSize)
                {
                    DrawTitle(title, startAngle, emSize, defaultWidth);
                }
                /// <summary>
                /// 绘制主题
                /// </summary>
                /// <param name="title">主题(公司名称)</param>
                /// <param name="startAngle">开始角度,必须是左半边,推荐(135-270)</param>
                /// <param name="emSize">字体大小</param>
                /// <param name="width">画笔粗细</param>
                public void DrawTitle(string title, float startAngle, float emSize, int width)
                {
                    Font font = new Font(DefaultFontName, emSize, FontStyle.Bold);
                    DrawTitle(title, startAngle, font, width);
                }
                /// <summary>
                /// 绘制主题
                /// </summary>
                /// <param name="title">主题(公司名称)</param>
                /// <param name="startAngle">开始角度,必须是左半边,推荐(135-270)</param>
                /// <param name="font">字体</param>
                /// <param name="width">画笔粗细</param>
                public void DrawTitle(string title, float startAngle, Font font, int width)
                {
                    if (string.IsNullOrEmpty(title))
                    {
                        return;
                    }
                    if (Math.Cos(startAngle / 180 * Math.PI) > 0)
                    {
                        throw new ArgumentException($"初始角度错误:{startAngle}(建议135-270)", nameof(startAngle));
                    }
    
                    startAngle = startAngle % 360;//起始角度
    
                    var length = title.Length;
                    float changeAngle = (270 - startAngle) * 2 / length;//每个字所占的角度,也就是旋转角度
                    var circleWidth = size / 2 - width * 3;//字体圆形的长度
                    var fontSize = g.MeasureString(title, font);//测量一下字体
                    var per = fontSize.Width / length;//每个字体的长度
    
                    //在指定的角度绘制字符
                    void action(string t, float a)
                    {
                        var angleXy = a / 180 * Math.PI;
                        var x = size / 2 + Math.Cos(angleXy) * circleWidth;
                        var y = size / 2 + Math.Sin(angleXy) * circleWidth;
    
                        DrawChar(t, (float)x, (float)y, a + 90, font, width);
                    }
    
                    //起始绘制角度=起始角度+旋转角度/2-字体所占角度的一半
                    var angle = startAngle + changeAngle / 2 - (float)(Math.Asin(per / 2 / circleWidth) / Math.PI * 180);//起始绘制角度
                    for (var i = 0; i < length; i++)
                    {
                        action(title[i].ToString(), angle);
                        angle += changeAngle;
                    }
                }
                /// <summary>
                /// 绘制横向文
                /// </summary>
                /// <param name="text">横向文</param>
                public void DrawHorizontal(string text)
                {
                    DrawHorizontal(text, defaultHorizontalSize);
                }
                /// <summary>
                /// 绘制横向文
                /// </summary>
                /// <param name="text">横向文</param>
                /// <param name="emSize">字体大小</param>
                public void DrawHorizontal(string text, float emSize)
                {
                    Font font = new Font(DefaultFontName, emSize, FontStyle.Bold);//定义字体的字体样式
                    DrawHorizontal(text, font);
                }
                /// <summary>
                /// 绘制横向文
                /// </summary>
                /// <param name="text">横向文</param>
                /// <param name="font">字体</param>
                public void DrawHorizontal(string text, Font font)
                {
                    int length = text.Length;
                    SizeF textSize = g.MeasureString(text, font);//对指定字符串进行测量
                    while (textSize.Width > size * 2 / 3)
                    {
                        DrawHorizontal(text, new Font(font.Name, font.Size - 1, font.Style));
                        return;
                    }
                    //要指定的位置绘制中间文字
                    PointF point = new PointF(size / 2 - textSize.Width / 2, size * 2 / 3);
    
                    g.ResetTransform();
                    g.DrawString(text, font, new SolidBrush(Color), point);
                }
    
                /// <summary>
                /// 绘制下弦文
                /// </summary>
                /// <param name="text">下弦文</param>
                /// <param name="startAngle">开始角度,必须是左下半边,推荐(90-180)</param>
                public void DrawChord(string text, float startAngle = 135)
                {
                    DrawChord(text, startAngle, defaultChordSize);
                }
                /// <summary>
                /// 绘制下弦文
                /// </summary>
                /// <param name="text">下弦文</param>
                /// <param name="startAngle">开始角度,必须是左下半边,推荐(90-180)</param>
                /// <param name="emSize">字体大小</param>
                public void DrawChord(string text, float startAngle, float emSize)
                {
                    DrawChord(text, startAngle, emSize, defaultWidth);
                }
                /// <summary>
                /// 绘制下弦文
                /// </summary>
                /// <param name="text">下弦文</param>
                /// <param name="startAngle">开始角度,必须是左下半边,推荐(90-180)</param>
                /// <param name="emSize">字体大小</param>
                /// <param name="width">画笔粗细</param>
                public void DrawChord(string text, float startAngle, float emSize, int width)
                {
                    Font font = new Font(DefaultFontName, emSize, FontStyle.Bold);//定义字体的字体样式
                    DrawChord(text, startAngle, font, width);
                }
                /// <summary>
                /// 绘制下弦文
                /// </summary>
                /// <param name="text">下弦文</param>
                /// <param name="startAngle">开始角度,必须是左下半边,推荐(90-180)</param>
                /// <param name="font">字体</param>
                /// <param name="width">画笔粗细</param>
                public void DrawChord(string text, float startAngle, Font font, int width)
                {
                    if (string.IsNullOrEmpty(text))
                    {
                        return;
                    }
                    if (Math.Cos(startAngle / 180 * Math.PI) > 0)
                    {
                        throw new ArgumentException($"初始角度错误:{startAngle}(建议90-135)", nameof(startAngle));
                    }
    
                    startAngle = startAngle % 360;//起始角度
    
                    var length = text.Length;
                    float changeAngle = (startAngle - 90) * 2 / length;//每个字所占的角度,也就是旋转角度
                    var fontSize = g.MeasureString(text, font);//测量一下字体
                    var per = fontSize.Width / length;//每个字体的长度
                    var circleWidth = size / 2 - width * 2 - fontSize.Height;//字体圆形的长度
    
                    //在指定的角度绘制字符
                    void action(string t, float a)
                    {
                        var angleXy = a / 180 * Math.PI;
                        var x = size / 2 + Math.Cos(angleXy) * circleWidth;
                        var y = size / 2 + Math.Sin(angleXy) * circleWidth;
    
                        DrawChar(t, (float)x, (float)y, a - 90, font, width);
                    }
    
                    //起始绘制角度=起始角度-旋转角度/2+字体所占角度的一半
                    var angle = startAngle - changeAngle / 2 + (float)(Math.Asin(per / 2 / circleWidth) / Math.PI * 180);//起始绘制角度
                    for (var i = 0; i < length; i++)
                    {
                        action(text[i].ToString(), angle);
                        angle -= changeAngle;
                    }
                }
                /// <summary>
                /// 绘制单个字符
                /// </summary>
                /// <param name="char">字符</param>
                /// <param name="x">距离画布左边的距离</param>
                /// <param name="y">距离画布上边的距离</param>
                /// <param name="emSize">字体大小</param>
                /// <param name="width">画笔粗细</param>
                public void DrawChar(string @char, float x, float y, float emSize)
                {
                    DrawChar(@char, x, y, 0, emSize);
                }
                /// <summary>
                /// 绘制单个字符
                /// </summary>
                /// <param name="char">字符</param>
                /// <param name="x">距离画布左边的距离</param>
                /// <param name="y">距离画布上边的距离</param>
                /// <param name="angle">选中角度,0度为右方,顺时针增加</param>
                /// <param name="emSize">字体大小</param>
                /// <param name="width">画笔粗细</param>
                public void DrawChar(string @char, float x, float y, float angle, float emSize)
                {
                    DrawChar(@char, x, y, angle, emSize, defaultWidth);
                }
                /// <summary>
                /// 绘制单个字符
                /// </summary>
                /// <param name="char">字符</param>
                /// <param name="x">距离画布左边的距离</param>
                /// <param name="y">距离画布上边的距离</param>
                /// <param name="angle">选中角度,0度为右方,顺时针增加</param>
                /// <param name="emSize">字体大小</param>
                /// <param name="width">画笔粗细</param>
                public void DrawChar(string @char, float x, float y, float angle, float emSize, int width)
                {
                    Font font = new Font(DefaultFontName, emSize, FontStyle.Bold);
                    DrawChar(@char, x, y, angle, font, width);
                }
                /// <summary>
                /// 绘制单个字符
                /// </summary>
                /// <param name="char">字符</param>
                /// <param name="x">距离画布左边的距离</param>
                /// <param name="y">距离画布上边的距离</param>
                /// <param name="angle">选中角度,0度为右方,顺时针增加</param>
                /// <param name="fontName">字体</param>
                /// <param name="width">画笔粗细</param>
                public void DrawChar(string @char, float x, float y, float angle, Font font, int width)
                {
                    if (string.IsNullOrEmpty(@char) || @char.Length != 1)
                    {
                        throw new ArgumentException("only one char is supported", nameof(@char));
                    }
    
                    g.ResetTransform();//重置
                    g.TranslateTransform(x, y);//调整偏移
                    g.RotateTransform(angle);//旋转角度
                    g.DrawString(@char, font, new SolidBrush(Color), 0, 0);//绘制,因为使用了偏移,所以这里的坐标是相对偏移的,所以是0
                }
    
                /// <summary>
                /// 保存图片
                /// </summary>
                /// <param name="fileName"></param>
                public void Save(string fileName)
                {
                    map.Save(fileName);
                }
                /// <summary>
                /// 保存图片
                /// </summary>
                /// <param name="stream"></param>
                /// <param name="format"></param>
                public void Save(Stream stream, ImageFormat format)
                {
                    map.Save(stream, format);
                }
    
                public void Dispose()
                {
                    try
                    {
                        if (map != null)
                        {
                            map.Dispose();
                        }
                        if (g != null)
                        {
                            g.Dispose();
                        }
                    }
                    catch { }
                }
            }
            public class PersonalSealHelper : IDisposable
            {
                int size = 160;
                Image map;
                Graphics g;
                int defaultWidth;
                float defaultSquareSize;
                float defaultNameSize;
                bool isSquare = false;
    
                public Color Color { get; set; } = Color.Red;
                public string DefaultFontName { get; set; } = "SimSun";
    
                public PersonalSealHelper()
                {
                    map = new Bitmap(size, size);
                    g = Graphics.FromImage(map);//实例化Graphics类
                    g.SmoothingMode = SmoothingMode.AntiAlias;  //System.Drawing.Drawing2D;           
                    g.Clear(Color.Transparent);
    
                    defaultWidth = size / 40;
                    defaultSquareSize = size / 4;
                    defaultNameSize = size / 4;
                }
    
                /// <summary>
                /// 绘制方形之印
                /// </summary>
                public void DrawSquare()
                {
                    DrawSquare(defaultSquareSize);
                }
                /// <summary>
                /// 绘制方形之印
                /// </summary>
                /// <param name="emSize">字体大小</param>
                public void DrawSquare(float emSize)
                {
                    DrawSquare(emSize, defaultWidth);
                }
                /// <summary>
                /// 绘制方形之印
                /// </summary>
                /// <param name="font">字体</param>
                public void DrawSquare(Font font)
                {
                    DrawSquare(font, defaultWidth);
                }
                /// <summary>
                /// 绘制方形之印
                /// </summary>
                /// <param name="emSize">字体大小</param>
                /// <param name="width">画笔粗细</param>
                public void DrawSquare(float emSize, int width)
                {
                    Font font = new Font(DefaultFontName, emSize, FontStyle.Bold);//设置之印的字体样式
                    DrawSquare(font, width);
                }
                /// <summary>
                /// 绘制方形之印
                /// </summary>
                /// <param name="font">字体</param>
                /// <param name="width">画笔粗细</param>
                public void DrawSquare(Font font, int width)
                {
                    isSquare = true;
    
                    var pen = new Pen(Color, width);//设置画笔的颜色
                    Rectangle rect = new Rectangle(width, width, size - width * 2, size - width * 2);//设置绘制区域
                    g.DrawRectangle(pen, rect);
    
                    var textSize = g.MeasureString("之印", font);//对指定字符串进行测量
                    var left = (size / 2 - width * 2 - textSize.Width / 2) / 2;
                    var perHeght = (size - width * 4 - textSize.Height * 2) / 3;
    
                    PointF point1 = new PointF(left + width * 2, perHeght + width * 2);
                    g.DrawString("", font, pen.Brush, point1);
    
                    PointF point2 = new PointF(left + width * 2, perHeght * 2 + width * 2 + textSize.Height);
                    g.DrawString("", font, pen.Brush, point2);
                }
                /// <summary>
                /// 绘制带边框的姓名
                /// </summary>
                /// <param name="name">姓名</param>
                public void DrawNameWithBorder(string name)
                {
                    DrawNameWithBorder(name, defaultNameSize, defaultWidth);
                }
                /// <summary>
                /// 绘制带边框的姓名
                /// </summary>
                /// <param name="name">姓名</param>
                /// <param name="font">字体</param>
                public void DrawNameWithBorder(string name, Font font)
                {
                    DrawNameWithBorder(name, font, defaultWidth);
                }
                /// <summary>
                /// 绘制带边框的姓名
                /// </summary>
                /// <param name="name">姓名</param>
                /// <param name="emSize">字体大小</param>
                public void DrawNameWithBorder(string name, float emSize)
                {
                    DrawNameWithBorder(name, emSize, defaultWidth);
                }
                /// <summary>
                /// 绘制带边框的姓名
                /// </summary>
                /// <param name="name">姓名</param>
                /// <param name="emSize">字体大小</param>
                /// <param name="width">画笔粗细</param>
                public void DrawNameWithBorder(string name, float emSize, int width)
                {
                    Font font = new Font(DefaultFontName, emSize, FontStyle.Bold);//设置字体样式
                    DrawNameWithBorder(name, font, width);
                }
                /// <summary>
                /// 绘制带边框的姓名
                /// </summary>
                /// <param name="name">姓名</param>
                /// <param name="font">字体</param>
                /// <param name="width">画笔粗细</param>
                public void DrawNameWithBorder(string name, Font font, int width)
                {
                    var nameSize = g.MeasureString(name, font);//对指定字符串进行测量
                    while (nameSize.Width > size - width * 6)
                    {
                        DrawNameWithBorder(name, new Font(font.Name, font.Size - 1, font.Style), width);
                        return;
                    }
                    var left = (int)(size - nameSize.Width - width * 4) / 2;
                    var height = (int)(size - nameSize.Height - width * 4) / 2;
    
                    var pen = new Pen(Color, width);//设置画笔的颜色
                    Rectangle rect = new Rectangle(width, height, size - width * 2, size - height * 2);//设置绘制区域
                    g.DrawRectangle(pen, rect);
    
                    PointF point = new PointF(width + width * 2, height + width * 2);
                    g.DrawString(name, font, pen.Brush, point);
                }
                /// <summary>
                /// 绘制带边框的姓名
                /// </summary>
                /// <param name="name">姓名</param>
                public void DrawName(string name)
                {
                    DrawName(name, defaultNameSize, defaultWidth);
                }
                /// <summary>
                /// 绘制带边框的姓名
                /// </summary>
                /// <param name="name">姓名</param>
                /// <param name="font">字体</param>
                public void DrawName(string name, Font font)
                {
                    DrawName(name, font, defaultWidth);
                }
                /// <summary>
                /// 绘制带边框的姓名
                /// </summary>
                /// <param name="name">姓名</param>
                /// <param name="emSize">字体大小</param>
                public void DrawName(string name, float emSize)
                {
                    DrawName(name, emSize, defaultWidth);
                }
                /// <summary>
                /// 绘制带边框的姓名
                /// </summary>
                /// <param name="name">姓名</param>
                /// <param name="emSize">字体大小</param>
                /// <param name="width">画笔粗细</param>
                public void DrawName(string name, float emSize, int width)
                {
                    Font font = new Font(DefaultFontName, emSize, FontStyle.Bold);//设置字体样式
                    DrawName(name, font, width);
                }
                /// <summary>
                /// 绘制姓名
                /// </summary>
                /// <param name="name">姓名</param>
                /// <param name="font">字体</param>
                /// <param name="width">画笔粗细</param>
                public void DrawName(string name, Font font, int width)
                {
                    var nameSize = g.MeasureString(name, font);//对指定字符串进行测量
                    while (nameSize.Width > size - width * 6)
                    {
                        DrawName(name, new Font(font.Name, font.Size - 1, font.Style), width);
                        return;
                    }
                    if (isSquare)
                    {
                        int length = name.Length;//获取字符串的长度
                        var left = (size / 2 - width - nameSize.Width / length) / 2;
                        var height = (size - width * 4 - nameSize.Height * length) / (length + 1);
                        if (left <= 0 || height <= 0)
                        {
                            return;
                        }
    
                        for (var i = 0; i < length; i++)
                        {
                            PointF point = new PointF(width + size / 2, height * (i + 1) + width * 2 + nameSize.Height * i);
                            g.DrawString(name[i].ToString(), font, new SolidBrush(Color), point);
                        }
                    }
                    else
                    {
                        var left = (size - nameSize.Width) / 2;
                        var height = (size - nameSize.Height) / 2;
                        PointF point = new PointF(width, height);
                        g.DrawString(name, font, new SolidBrush(Color), point);
                    }
                }
    
                /// <summary>
                /// 保存图片
                /// </summary>
                /// <param name="fileName"></param>
                public void Save(string fileName)
                {
                    map.Save(fileName);
                }
                /// <summary>
                /// 保存图片
                /// </summary>
                /// <param name="stream"></param>
                /// <param name="format"></param>
                public void Save(Stream stream, ImageFormat format)
                {
                    map.Save(stream, format);
                }
                public void Dispose()
                {
                    try
                    {
                        if (map != null)
                        {
                            map.Dispose();
                        }
                        if (g != null)
                        {
                            g.Dispose();
                        }
                    }
                    catch { }
                }
            }
        }
    }
    View Code

      注意了,.net core没有System.Drawing,替代方案是使用第三方的依赖,这里推荐使用Nuget的System.Drawing.Common。

      另外,代码使用的是最新版本的C#,如果使用旧版本的可能会报错,相对于的调整一下就好了

      这个辅助类还能生成不同颜色和字体的印章,可随需求而变

      如果在Linux下发现中文乱码,那应该是没有安装相应的字体,可以将windows下的C:\Windows\Fonts的字体拷贝到linux对应目录下(Ubuntu是/usr/share/fonts),在安装,清空缓存,重启后就可以了

      生成公司印章:   

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    
    namespace DemoConsole
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var helper = SealHelper.Mechanism())
                {
                    helper.DrawCircle();//绘制圆
                    helper.DrawStar();//绘制星星
                    helper.DrawTitle("某某科技股份有限公司");//绘制公司名称
                    helper.DrawHorizontal("练习专用");//绘制横向文
                    helper.DrawChord("20191016094709");//绘制下弦文
                    helper.Save(Path.Combine(Directory.GetCurrentDirectory(), "公司印章.png"));
                }
            }
        }
    }
    View Code

       生成的印章:

      

      生成个人印章:  

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    
    namespace DemoConsole
    {
        class Program
        {
            static void Main(string[] args)
            {
                //绘制方形印章
                using (var helper = SealHelper.Personal())
                {
                    helper.DrawSquare();
                    helper.DrawName("张三");
                    helper.Save(Path.Combine(Directory.GetCurrentDirectory(), "张三.png"));
                }
                //绘制姓名带边框
                using (var helper = SealHelper.Personal())
                {
                    helper.DrawNameWithBorder("李四");
                    helper.Save(Path.Combine(Directory.GetCurrentDirectory(), "李四.png"));
                }
                //绘制姓名
                using (var helper = SealHelper.Personal())
                {
                    helper.DrawName("王五");
                    helper.Save(Path.Combine(Directory.GetCurrentDirectory(), "王五.png"));
                }
            }
        }
    }
    View Code

      生成的印章:

           

  • 相关阅读:
    18. 4Sum(双指针)
    17. Letter Combinations of a Phone Number(bfs)
    16. 3Sum Closest(双指针)
    15. 3Sum(字典) (双指针)
    14. Longest Common Prefix(暴力循环)
    8. String to Integer (atoi)
    54. Spiral Matrix(剑指offer--19)
    Baidu 推荐技术平台(offer)
    134. Gas Station(数学定理依赖题)
    187. Repeated DNA Sequences(建立词典,遍历一遍 o(n))
  • 原文地址:https://www.cnblogs.com/shanfeng1000/p/11683731.html
Copyright © 2011-2022 走看看