C# 生成印章
1、界面实现及按钮事件
///点击按钮事件 private void button2_Click(object sender, EventArgs e) { try { string imageUrl = "C:\\Users\\Administrator\\Desktop\\新建文件夹 (2)"; string imageFormat = "jpg"; string outerCircleText = "测试公司"; string interiorText = "测试部门"; this.txt_WordsExtract.Text = Resource.Contract.CreatPublicSeal.CreatSeal(outerCircleText, interiorText, imageUrl, imageFormat); } catch (Exception ex) { throw; } }
2、生成印章源码
/// <summary> /// 生成电子印章 /// </summary> public class CreatPublicSeal { //定义字符串的字体样式 Font Var_Font = new Font("Arial", 12, FontStyle.Bold); //记录圆的直径 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> /// 创建公司公共印章得到图片存储地址 /// </summary> /// <param name="outerCircleText">最外圈文字</param> /// <param name="interiorText">内圈文字</param> /// <param name="imageUrl">保存路径</param> /// <param name="imageFormat">生成格式</param> /// <returns></returns> public static string CreatSeal(string outerCircleText, string interiorText, string imageUrl, string imageFormat) { #region 初始化和设置 //画图初始化 Bitmap bMap = new Bitmap(160, 160); Graphics g = Graphics.FromImage(bMap); //消除绘制图形的锯齿 g.SmoothingMode = SmoothingMode.AntiAlias; //以白色清空panel1控件的背景 g.Clear(Color.White); //设置画笔的颜色 Pen myPen = new Pen(Color.Red, circularity_W); //绘制圆 g.DrawEllipse(myPen, rect); #endregion #region 绘制星号 string star_Str = "★"; //设置星号的字体样式 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); #endregion #region 绘制中间文字 //绘制中间文字 int var_len = interiorText.Length; //定义中间字体样式 Font Var_Font = new Font("Arial", 22 - var_len * 2, FontStyle.Bold); //对中间字符串进行测量 SizeF Var_Size = g.MeasureString(interiorText, 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(interiorText, Var_Font, myPen.Brush, Var_xy); #endregion #region 绘制外圈文字 //最外圈文字 if (!string.IsNullOrWhiteSpace(outerCircleText)) { outerCircleText = outerCircleText + "专用章"; } //获取字符串的长度 int text_len = outerCircleText.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(outerCircleText, g, fCharWidth, _letterspace, _chardirect, text_Font); double fStartAngle, fSweepAngle; fSweepAngle = fTotalWidth * 360 / (NewRect.Width * Math.PI); fStartAngle = 270 - fSweepAngle / 2; 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, outerCircleText[i].ToString(), (float)(fCharAngle[i] + _degree), pntChars[i], text_Font, myPenbush); } #endregion #region 保存 if (!imageUrl.EndsWith("\\") && !imageUrl.EndsWith("/")) { imageUrl = imageUrl + "\\"; } if (!imageFormat.StartsWith(".")) { imageFormat = "." + imageFormat; } string imageName = DateTime.Now.ToString("yyyyMMddHHmmss") + imageFormat; string fileName = imageUrl + imageName; bMap.Save(fileName); #endregion return fileName; } /// <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); 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; 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; fCircleLength = NewRect.Width * Math.PI; for (int i = 0; i < CharWidth.Length; i++) { fSweepAngle = CharWidth[i] * 360 / fCircleLength; CharAngle[i] = StartAngle + fSweepAngle / 2; 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))); } 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) { StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; GraphicsPath gp = new GraphicsPath(System.Drawing.Drawing2D.FillMode.Winding); int x = (int)text_Point.X; int y = (int)text_Point.Y; gp.AddString(_text, text_Font.FontFamily, (int)text_Font.Style, text_Font.Size, new Point(x, y), sf); 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, } }
3、具体效果
本文来自博客园,作者:流纹,转载请注明原文链接:https://www.cnblogs.com/lwk9527/p/17374105.html