c# gdi 绘制内切于椭圆的文字,求代码或思路 如图:
------解决思路----------------------
简单写了个效果
如图
lib文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace yangzhanglib
{
public class DrawString
{
/// <summary>
/// 根据角度 获取椭圆上一点的坐标
/// x2⒈/a2+y2/b2=1
/// y = x * tanα
/// </summary>
/// <param name="a">长半轴</param>
/// <param name="b">短半轴</param>
/// <param name="rotate">角度</param>
/// <returns></returns>
public static Point GetCoordinate(int a, int b, float rotate)
{
double x = 0, y = 0, tan = 0, Rad = 0;
if (Math.Abs(rotate) > 90)
Rad = (Math.Abs(rotate) - 90);
else
Rad = (90 - Math.Abs(rotate));
Rad = Rad * 2 * Math.PI / 360;
tan = Math.Tan(Rad);
x = Math.Sqrt((double)1 / ((double)1 / (a * a) + (tan * tan) / (b * b)));
y = x * tan;
if (rotate < 0)
x = 0 - x;
if (rotate > -90 && rotate < 90)
y = 0 - y;
x = a + x;
y = b + y;
return new Point((int)Math.Round(x), (int)Math.Round(y));
}
public static Bitmap DrawText(string text)
{
char[] texts = text.ToArray();
int beginRotate = -120;
int endRotate = 120;
float Rotate = (float)(endRotate - beginRotate) / (texts.Length - 1);
int ecllpse_width = 200;
int ecllpse_height = 150;
int fontsize = 18;
Bitmap map = new Bitmap(ecllpse_width *2, ecllpse_height *2);
using (Graphics g = Graphics.FromImage(map))
{
g.FillRectangle(new SolidBrush(Color.White),new Rectangle(0,0,(int)ecllpse_width *2, (int)ecllpse_height *2));
g.DrawEllipse(new Pen(new SolidBrush(Color.Black), 2) { DashStyle = DashStyle.Dot}, new Rectangle(0, 0, ecllpse_width * 2, ecllpse_height * 2));
g.DrawEllipse(new Pen(new SolidBrush(Color.Black), 4), new Rectangle((2 * ecllpse_width / 10), (2 * ecllpse_height / 10), (8 * ecllpse_width / 10) * 2, (8 * ecllpse_height / 10) * 2));
for (int i = 0; i < texts.Length; i++)
{
Matrix mtxSave = g.Transform;
float now_rotate = beginRotate + (Rotate * i);
Point p = GetCoordinate(13 * ecllpse_width / 20, 13 * ecllpse_height / 20, beginRotate + (Rotate * i));
Matrix mtxRotate = g.Transform;
p.X += ecllpse_width / 4;
p.Y += ecllpse_height / 4;
mtxRotate.RotateAt(beginRotate + (Rotate * i), new PointF(p.X + fontsize, p.Y + fontsize));
g.Transform = mtxRotate;
g.DrawString(texts[i].ToString(), new Font("Arial", fontsize), new SolidBrush(Color.Black), p);
g.Transform = mtxSave;
}
}
return map;
}
}
}
页面cs代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using yangzhanglib;
namespace yangzhang
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Clear();
Response.CacheControl = "no-cache";
Response.ContentType = "image/jpeg";
using (System.Drawing.Bitmap map = DrawString.DrawText("北京开天科技有限公司样品章"))
{
byte[] bytes;
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
System.Drawing.Imaging.ImageCodecInfo[] icis = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
System.Drawing.Imaging.ImageCodecInfo ici = null;
foreach (System.Drawing.Imaging.ImageCodecInfo i in icis)
{
if (i.MimeType == "image/jpeg")
{
ici = i;
}
}
System.Drawing.Imaging.EncoderParameters ep = new System.Drawing.Imaging.EncoderParameters(1);
ep.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)90);
map.Save(ms, ici, ep);
bytes = ms.ToArray();
ms.Close();
ms.Dispose();
}
Response.OutputStream.Write(bytes, 0, bytes.Length);
}
}
}
}
设计页面代码
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="yangzhang._Default" %>
------解决思路----------------------
绘制印章: 给定椭圆的中心,两个半径和文字所跨的角度来绘制。
先求总的弧长,然后均分,每个字所占据的弧长相等。
难点在于如何求弧长和角度的对应关系,我采取的办法是先求出一个对应表:从最小角度到最大角度,每0.5度递增,求出各段弧长累加即得到对应表。 由弧长查角度的时候,从表中找到该弧长所在的闭区间,就得到对应的角度。
剩下的就都很简单了