using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Drawing.Drawing2D;

namespace Cachet
{
    public class CreatPublicSeal
    {

Font Var_Font = new Font("Arial", 12, FontStyle.Bold);//定义字符串的字体样式
        //Rectangle rect = new Rectangle(10, 10, 160, 160);//实例化Rectangle类
        private static int tem_Line = 160;//记录圆的直径
        private static int circularity_W = 4;//设置圆画笔的粗细
        //圆线条
        private static Rectangle rect = new Rectangle(circularity_W, circularity_W, tem_Line - circularity_W * 2, tem_Line - circularity_W * 2);//设置圆的绘制区域
        private static int _letterspace = 4;//字体间距
        private static Char_Direction _chardirect = Char_Direction.Center;
        private static int _degree = 90;
        //字体圆弧所在圆
        private static int space = 16;//比外面圆圈小
        private static Rectangle NewRect = new Rectangle(new Point(rect.X + space, rect.Y + space), new Size(rect.Width - 2 * space, rect.Height - 2 * space));
        
        /// <summary>
        /// 创建公司公共印章得到gif图片存储地址
        /// </summary>
        /// <param name="company">公司名字</param>
        /// <param name="department">部门名字</param>
        /// <param name="Url">图片保存路径</param>
        /// <returns></returns>
        public static string CreatSeal(string company, string department, string Url)
        {
            
            string star_Str = "★";
            Bitmap bMap = new Bitmap(160, 160);//画图初始化
            Graphics g= Graphics.FromImage(bMap);
            //Graphics g = this.panel1.CreateGraphics();//实例化Graphics类
            g.SmoothingMode = SmoothingMode.AntiAlias;//消除绘制图形的锯齿
            g.Clear(Color.White);//以白色清空panel1控件的背景
            Pen myPen = new Pen(Color.Red, circularity_W);//设置画笔的颜色
            g.DrawEllipse(myPen, rect); //绘制圆

Font star_Font = new Font("Arial", 30, FontStyle.Regular);//设置星号的字体样式
            SizeF star_Size = g.MeasureString(star_Str, star_Font);//对指定字符串进行测量
            //要指定的位置绘制星号
            PointF star_xy = new PointF(tem_Line / 2 - star_Size.Width / 2, tem_Line / 2 - star_Size.Height / 2);
            g.DrawString(star_Str, star_Font, myPen.Brush, star_xy);
           
            //绘制中间文字
            string var_txt = department;
            //string var_txt = "财务部";
            int var_len = var_txt.Length;
            Font Var_Font = new Font("Arial", 22 - var_len*2, FontStyle.Bold);//定义部门字体的字体样式
            SizeF Var_Size = g.MeasureString(var_txt, Var_Font);//对指定字符串进行测量
            //要指定的位置绘制中间文字
            PointF Var_xy = new PointF(tem_Line / 2 - Var_Size.Width / 2, tem_Line / 2 + star_Size.Height / 2 - Var_Size.Height/2+5);
            g.DrawString(var_txt, Var_Font, myPen.Brush, Var_xy);

//string text_txt = "吉林省明日科技有限公司";
            string text_txt = company + "专用";
            int text_len = text_txt.Length;//获取字符串的长度
            Font text_Font = new Font("Arial", 25 - text_len, FontStyle.Bold);//定义公司名字的字体的样式
            Pen myPenbush = new Pen(Color.White, circularity_W);

float[] fCharWidth = new float[text_len];
            float fTotalWidth = ComputeStringLength(text_txt, g, fCharWidth, _letterspace, _chardirect, text_Font);
            // Compute arc's start-angle and end-angle
            double fStartAngle, fSweepAngle;
            fSweepAngle = fTotalWidth * 360 / (NewRect.Width * Math.PI);
            fStartAngle = 270 - fSweepAngle / 2;
            // Compute every character's position and angle
            //PointF[] pntChars = new PointF[text_len];
            PointF[] pntChars = new PointF[text_len];
            double[] fCharAngle = new double[text_len];
            ComputeCharPos(fCharWidth, pntChars, fCharAngle, fStartAngle);
            for (int i = 0; i < text_len; i++)
            {
                DrawRotatedText(g, text_txt[i].ToString(), (float)(fCharAngle[i] + _degree), pntChars[i], text_Font, myPenbush);
            }
            string imageName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".gif";
            bMap.Save(Url + imageName);
            return Url + imageName;
        }
        /// <summary>
        /// 计算字符串总长度和每个字符长度
        /// </summary>
        /// <param name="sText"></param>
        /// <param name="g"></param>
        /// <param name="fCharWidth"></param>
        /// <param name="fIntervalWidth"></param>
        /// <returns></returns>
        private static float ComputeStringLength(string sText, Graphics g, float[] fCharWidth, float fIntervalWidth, Char_Direction Direction, Font text_Font)
        {
            // Init字符串格式
            StringFormat sf = new StringFormat();
            sf.Trimming = StringTrimming.None;
            sf.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap
                | StringFormatFlags.LineLimit;
            // 衡量整个字符串长度
            SizeF size = g.MeasureString(sText, text_Font, (int)text_Font.Style);
            RectangleF rect = new RectangleF(0f, 0f, size.Width, size.Height);
            // 测量每个字符大小
            CharacterRange[] crs = new CharacterRange[sText.Length];
            for (int i = 0; i < sText.Length; i++)
                crs[i] = new CharacterRange(i, 1);
            // 复位字符串格式
            sf.FormatFlags = StringFormatFlags.NoClip;
            sf.SetMeasurableCharacterRanges(crs);
            sf.Alignment = StringAlignment.Near;
            // 得到每一个字符大小
            Region[] regs = g.MeasureCharacterRanges(sText, text_Font, rect, sf);
            // Re-compute whole string length with space interval width
            float fTotalWidth = 0f;
            for (int i = 0; i < regs.Length; i++)
            {
                if (Direction == Char_Direction.Center || Direction == Char_Direction.OutSide)
                    fCharWidth[i] = regs[i].GetBounds(g).Width;
                else
                    fCharWidth[i] = regs[i].GetBounds(g).Height;
                fTotalWidth += fCharWidth[i] + fIntervalWidth;
            }
            fTotalWidth -= fIntervalWidth;//Remove the last interval width
            return fTotalWidth;
        }

/// <summary>
        /// 求出每个字符的所在的点,以及相对于中心的角度
        ///1.  通过字符长度,求出字符所跨的弧度;
        ///2.  根据字符所跨的弧度,以及字符起始位置,算出字符的中心位置所对应的角度;
        ///3.  由于相对中心的角度已知,根据三角公式很容易算出字符所在弧上的点,如下图所示;
        ///4.  根据字符长度以及间隔距离,算出下一个字符的起始角度;
        ///5.  重复1直至整个字符串结束。
        /// </summary>
        /// <param name="CharWidth"></param>
        /// <param name="recChars"></param>
        /// <param name="CharAngle"></param>
        /// <param name="StartAngle"></param>
        private static void ComputeCharPos(float[] CharWidth, PointF[] recChars, double[] CharAngle, double StartAngle)
        {
            double fSweepAngle, fCircleLength;
            //Compute the circumference
            fCircleLength = NewRect.Width * Math.PI;

for (int i = 0; i < CharWidth.Length; i++)
            {
                //Get char sweep angle
                fSweepAngle = CharWidth[i] * 360 / fCircleLength;

//Set point angle
                CharAngle[i] = StartAngle + fSweepAngle / 2;

//Get char position
                if (CharAngle[i] < 270f)
                    recChars[i] = new PointF(
                        NewRect.X + NewRect.Width / 2
                        - (float)(NewRect.Width / 2 *
                        Math.Sin(Math.Abs(CharAngle[i] - 270) * Math.PI / 180)),
                        NewRect.Y + NewRect.Width / 2
                        - (float)(NewRect.Width / 2 * Math.Cos(
                        Math.Abs(CharAngle[i] - 270) * Math.PI / 180)));
                else
                    recChars[i] = new PointF(
                        NewRect.X + NewRect.Width / 2
                        + (float)(NewRect.Width / 2 *
                        Math.Sin(Math.Abs(CharAngle[i] - 270) * Math.PI / 180)),
                        NewRect.Y + NewRect.Width / 2
                        - (float)(NewRect.Width / 2 * Math.Cos(
                        Math.Abs(CharAngle[i] - 270) * Math.PI / 180)));

//Get total sweep angle with interval space
                fSweepAngle = (CharWidth[i] + _letterspace) * 360 / fCircleLength;
                StartAngle += fSweepAngle;

}   
        }
        /// <summary>
        /// 绘制每个字符
        /// </summary>
        /// <param name="g"></param>
        /// <param name="_text"></param>
        /// <param name="_angle"></param>
        /// <param name="text_Point"></param>
        /// <param name="text_Font"></param>
        /// <param name="myPen"></param>
        private static void DrawRotatedText(Graphics g, string _text, float _angle, PointF text_Point, Font text_Font, Pen myPen)
        {
            // Init format
            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Center;
            sf.LineAlignment = StringAlignment.Center;

// Create graphics path
            GraphicsPath gp = new GraphicsPath(System.Drawing.Drawing2D.FillMode.Winding);
            int x = (int)text_Point.X;
            int y = (int)text_Point.Y;

// Add string
            gp.AddString(_text, text_Font.FontFamily, (int)text_Font.Style, text_Font.Size, new Point(x, y), sf);

// Rotate string and draw it
            Matrix m = new Matrix();
            m.RotateAt(_angle, new PointF(x, y));
            g.Transform = m;
            g.DrawPath(myPen, gp);
            g.FillPath(new SolidBrush(Color.Red), gp);
        }

public enum Char_Direction
        {
            Center = 0,
            OutSide = 1,
            ClockWise = 2,
            AntiClockWise = 3,
        }
    }
}

C#生成电子印章源码的更多相关文章

  1. Google Protocol Buffers 快速入门(带生成C#源码的方法)

    Google Protocol Buffers是google出品的一个协议生成工具,特点就是跨平台,效率高,速度快,对我们自己的程序定义和使用私有协议很有帮助. Protocol Buffers入门: ...

  2. 身份证号码查询与生成(C#源码)

    项目要用到这个功能,就写了一个,完整类也就二百来行,很简单.可以在项目中用,也可以作为学习. 源码下载 http://yunpan.cn/cmQCSWkhDnZLJ  访问密码 0227 核心代码如下 ...

  3. 2018-09-13 代码翻译尝试-使用Roaster解析和生成Java源码

    此文是前文使用现有在线翻译服务进行代码翻译的体验的编程语言方面第二点的一个尝试. 参考Which framework to generate source code ? - Cleancode and ...

  4. Hibernate 5.x 生成 SessionFactory 源码跟踪分析

    我们要使用 Hibernate 的功能,首先需要读取 Hibernate 的配置文件,根据配置启动 Hibernate ,然后创建 SessionFactory. 创建 SessionFactory ...

  5. iOS雪花动画、音频图、新闻界面框架、2048游戏、二维码条形码扫码生成等源码

    iOS精选源码 粒子雪花与烟花的动画 iOS 2048游戏 JHSoundWaveView - 简单地声波图.音波图 一个可快速集成的新闻详情界面框架,类似今日头条,腾讯新闻 二维码/条形码扫描及扫描 ...

  6. vue-cli随机生成port源码

    const portfinder = require('portfinder'): const port = await portfinder.getPortPromise(): 两行代码 端口搜索范 ...

  7. 1、Hibernate之生成SessionFactory源码追踪

    Hibernate的所有session都是由sessionFactory来生成的,那么,sessionFactory是怎么得来的呢?它与我们配置的xxx.cfg.xml文件以及xxx.hbm.xml文 ...

  8. 关于aspx 页面生成html 源码顶部空行不得不说的事儿

    原文引用自 http://www.360doc.com/content/12/0910/21/10504424_235418578.shtml 使用.aspx生成的页面一般都会有一个或多个空行,当然这 ...

  9. C#生成缩略图源码

    先看调用的方法: ).ToUpper())                {                    case "JPG":                      ...

随机推荐

  1. Insert插入语句中带有select语句

    我们有时候在写Insert语句的时候会遇到values里面的个别列的值需要从别的表中查询获取,这时候SQL语句需要使用向表中插入多条数据的写法: INSERT INTO LoginRecordInfo ...

  2. 数据库 proc编程七

    #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <stri ...

  3. 【BZOJ】1064: [Noi2008]假面舞会(判环+gcd+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1064 表示想到某一种情况就不敢写下去了.... 就是找环的gcd...好可怕.. 于是膜拜了题解.. ...

  4. 360破解大赛crackme分析--之3DES解密附加数据

    具体的分析这里有.本人仅仅是对这里面有趣的算法进行了一些学习 分析链接 这次是逆向的使用3DES解密的过程中的内容: 使用微软的crypt库 使用3DES解密程序中的附加数据 代码: VOID enc ...

  5. hdu 2857:Mirror and Light(计算几何,点关于直线的对称点,求两线段交点坐标)

    Mirror and Light Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. 解决项目导入dubbo依赖项目报红叉问题

    1.maven+ssm项目导入dubbo依赖 项目报错如下 2.出错原因在于dubbo依赖低版本的spring和低版本netty,准备通过maven的依赖管理将依赖传递过来的低版本的spring和ne ...

  7. 高级service之ipc ADIL用法

    感谢 如果你还没有看过前面一篇文章,建议先去阅读一下 Android Service完全解析,关于服务你所需知道的一切(上) ,因为本篇文章中涉及到的代码是在上篇文章的基础上进行修改的. 在上篇文章中 ...

  8. 13个非常实用的JavaScript小技巧

    使用!!操作符转换布尔值 有时候我们需要对一个变量查检其是否存在或者检查值是否有一个有效值,如果存在就返回true值.为了做这样的验证,我们可以使用!!操作符来实现是非常的方便与简单.对于变量可以使用 ...

  9. ng2-file-upload上传附件同时传参

    由于业务需要,需要的场景是发某条公告的时候能够上传附件,不只是图片,图片的话可以直接用base64传给后台,但上传附件这个就不能这样干了, 与此同时,每条公告都有一个对应的唯一标识id, 附件以文件流 ...

  10. tcpdump linux抓http请求头

    sudo tcpdump -i eth0 port 80 -s 1024 -l -A