当前位置: 代码迷 >> C# >> c# 作图内切于椭圆的文字,求代码或思路
  详细解决方案

c# 作图内切于椭圆的文字,求代码或思路

热度:87   发布时间:2016-05-05 04:35:44.0
c# 绘制内切于椭圆的文字,求代码或思路
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度递增,求出各段弧长累加即得到对应表。 由弧长查角度的时候,从表中找到该弧长所在的闭区间,就得到对应的角度。
剩下的就都很简单了
  相关解决方案