通过代码实现生成并保存印章
///点击按钮事件
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;
}
}
/// <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,
}
}
最终效果图:
仅个人转载记录,不喜勿喷
参考文章:C#生成电子印章源码