Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 自动调整字体大小以适应矩形_C#_.net_Fonts - Fatal编程技术网

C# 自动调整字体大小以适应矩形

C# 自动调整字体大小以适应矩形,c#,.net,fonts,C#,.net,Fonts,如何在.NET 4.5/C中创建适合指定矩形的自适应大小字体 我根据字符串长度调整大小,字符串越长,fontsize越小,但效果不太好,如果字符串太长,文本就会变得很小。这种方法的问题是,如果我更改矩形大小,所有字体大小都不再合适。使用,您可以测量字符串的大小,以便计算所需的内容 来自MSDN的样本 private void MeasureStringMin(PaintEventArgs e) { // Set up string. string measureString

如何在.NET 4.5/C中创建适合指定矩形的自适应大小字体

我根据字符串长度调整大小,字符串越长,fontsize越小,但效果不太好,如果字符串太长,文本就会变得很小。这种方法的问题是,如果我更改矩形大小,所有字体大小都不再合适。

使用,您可以测量字符串的大小,以便计算所需的内容

来自MSDN的样本

private void MeasureStringMin(PaintEventArgs e)
{

    // Set up string. 
    string measureString = "Measure String";
    Font stringFont = new Font("Arial", 16);

    // Measure string.
    SizeF stringSize = new SizeF();
    stringSize = e.Graphics.MeasureString(measureString, stringFont);

    // Draw rectangle representing size of string.
    e.Graphics.DrawRectangle(new Pen(Color.Red, 1), 0.0F, 0.0F, stringSize.Width, stringSize.Height);

    // Draw string to screen.
    e.Graphics.DrawString(measureString, stringFont, Brushes.Black, new PointF(0, 0));
}

已经有一段时间了,但我遇到了这个问题。 MSDN提供了一个带有GetAdjustedFont方法的示例来帮助执行此过程:

(不知羞耻地从……偷来)


我也需要类似的东西。我创建了一些代码,以满足在定义的矩形内绘制文本的需要,该矩形具有几个自动字体大小选项(请参见DrawMethod enum)。它还支持使用和不使用自动字体大小的自动扭曲。我的解决方案受上述答案启发。 确保添加WindowsBase和PresentationCore程序集

DrawTextToBitmap.cs

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ReportPrepare
{
    class TextDrawing
    {
        public enum DrawMethod
        {
            AutosizeAccordingToText, // create the smallest bitmap needed to draw the text without word warp
            AutoFitInConstantRectangleWithoutWarp, // draw text with the biggest font possible while not exceeding rectangle dimensions, without word warp
            AutoWarpInConstantRectangle, // draw text in rectangle while performing word warp. font size is a constant input. drawing may exceed bitmap rectangle.
            AutoFitInConstantRectangleWithWarp // draw text with the biggest font possible while not exceeding rectangle dimensions, with word warp
        }

        private static void SetGraphicsHighQualityForTextRendering(Graphics g)
        {
            // The smoothing mode specifies whether lines, curves, and the edges of filled areas use smoothing (also called antialiasing). One exception is that path gradient brushes do not obey the smoothing mode. Areas filled using a PathGradientBrush are rendered the same way (aliased) regardless of the SmoothingMode property.
            g.SmoothingMode = SmoothingMode.AntiAlias;

            // The interpolation mode determines how intermediate values between two endpoints are calculated.
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;

            // Use this property to specify either higher quality, slower rendering, or lower quality, faster rendering of the contents of this Graphics object.
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;

            // This one is important
            g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
        }

        public static Size MeasureDrawTextBitmapSize(string text, Font font)
        {
            Bitmap bmp = new Bitmap(1, 1);
            using (Graphics g = Graphics.FromImage(bmp))
            {
                SizeF size = g.MeasureString(text, font);
                return new Size((int)(Math.Ceiling(size.Width)), (int)(Math.Ceiling(size.Height)));
            }

        }

        public static int GetMaximumFontSizeFitInRectangle(string text, Font font, RectangleF rectanglef, bool isWarp, int MinumumFontSize=6, int MaximumFontSize=1000)
        {
            Font newFont;
            Rectangle rect = Rectangle.Ceiling(rectanglef);

            for (int newFontSize = MinumumFontSize; ; newFontSize++)
            {
                newFont = new Font(font.FontFamily, newFontSize, font.Style);

                List<string> ls = WarpText(text, newFont, rect.Width);

                StringBuilder sb = new StringBuilder();
                if (isWarp)
                {
                    for (int i = 0; i < ls.Count; ++i)
                    {
                        sb.Append(ls[i] + Environment.NewLine);
                    }
                }
                else
                {
                    sb.Append(text);
                }

                Size size = MeasureDrawTextBitmapSize(sb.ToString(), newFont);
                if (size.Width > rectanglef.Width || size.Height > rectanglef.Height)
                {
                    return (newFontSize - 1);
                }
                if (newFontSize >= MaximumFontSize)
                {
                    return (newFontSize - 1);
                }

            }

        }

        public static List<string> WarpText(string text, Font font, int lineWidthInPixels)
        {
            string[] originalLines = text.Split(new string[] { " " }, StringSplitOptions.None);

            List<string> wrappedLines = new List<string>();

            StringBuilder actualLine = new StringBuilder();
            double actualWidthInPixels = 0;

            foreach (string str in originalLines)
            {
                Size size = MeasureDrawTextBitmapSize(str, font);

                actualLine.Append(str + " ");
                actualWidthInPixels += size.Width;

                if (actualWidthInPixels > lineWidthInPixels)
                {
                    actualLine =  actualLine.Remove(actualLine.ToString().Length - str.Length - 1, str.Length);
                    wrappedLines.Add(actualLine.ToString());
                    actualLine.Clear();
                    actualLine.Append(str + " ");
                    actualWidthInPixels = size.Width;
                }
            }

            if (actualLine.Length > 0)
            {
                wrappedLines.Add(actualLine.ToString());
            }

            return wrappedLines;
        }

        public static Bitmap DrawTextToBitmap(string text, Font font, Color color, DrawMethod mode, RectangleF rectanglef)
        {
            StringFormat drawFormat = new StringFormat();
            Bitmap bmp;
            switch (mode)
            {
                case DrawMethod.AutosizeAccordingToText:
                    {
                        Size size = MeasureDrawTextBitmapSize(text, font);

                        if (size.Width == 0 || size.Height == 0)
                        {
                            bmp = new Bitmap(1, 1);
                        }
                        else
                        {
                            bmp = new Bitmap(size.Width, size.Height);
                        }

                        using (Graphics g = Graphics.FromImage(bmp))
                        {
                            SetGraphicsHighQualityForTextRendering(g);

                            g.DrawString(text, font, new SolidBrush(color), 0, 0);

                            return bmp;
                        }

                    }
                case DrawMethod.AutoWarpInConstantRectangle:
                    {
                        Rectangle rect =  Rectangle.Ceiling(rectanglef);
                        bmp = new Bitmap(rect.Width,rect.Height);

                        if (rect.Width == 0 || rect.Height == 0)
                        {
                            bmp = new Bitmap(1, 1);
                        }
                        else
                        {
                            bmp = new Bitmap(rect.Width, rect.Height);
                        }

                        using (Graphics g = Graphics.FromImage(bmp))
                        {
                            SetGraphicsHighQualityForTextRendering(g);

                            g.DrawString(text, font, new SolidBrush(color), rectanglef, drawFormat);

                            return bmp;
                        }

                    }
                case DrawMethod.AutoFitInConstantRectangleWithoutWarp:
                    {
                        Rectangle rect = Rectangle.Ceiling(rectanglef);

                        bmp = new Bitmap(rect.Width, rect.Height);

                        if (rect.Width == 0 || rect.Height == 0)
                        {
                            bmp = new Bitmap(1, 1);
                        }
                        else
                        {
                            bmp = new Bitmap(rect.Width, rect.Height);
                        }

                        using (Graphics g = Graphics.FromImage(bmp))
                        {
                            int fontSize = GetMaximumFontSizeFitInRectangle(text, font, rectanglef, false);

                            SetGraphicsHighQualityForTextRendering(g);

                            g.DrawString(text, new Font(font.FontFamily, fontSize,font.Style, GraphicsUnit.Point), new SolidBrush(color), rectanglef, drawFormat);


                            return bmp;
                        }

                    }
                case DrawMethod.AutoFitInConstantRectangleWithWarp:
                    {
                        Rectangle rect = Rectangle.Ceiling(rectanglef);

                        if (rect.Width == 0 || rect.Height == 0)
                        {
                            bmp = new Bitmap(1, 1);
                        }
                        else
                        {
                            bmp = new Bitmap(rect.Width, rect.Height);
                        }

                        using (Graphics g = Graphics.FromImage(bmp))
                        {
                            int fontSize = GetMaximumFontSizeFitInRectangle(text, font, rectanglef, true);

                            SetGraphicsHighQualityForTextRendering(g);

                            g.DrawString(text, new Font(font.FontFamily, fontSize, font.Style, GraphicsUnit.Point), new SolidBrush(color), rectanglef, drawFormat);


                            return bmp;
                        }

                    }
            }
            return null;

        }



    }
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


// add WindowsBase and PresentationCore assemblies

namespace ReportPrepare
{
    public partial class Form1 : Form
    {
        PictureBox picbox = new PictureBox();
        int i = 0;
        Timer t = new Timer();

        public Form1()
        {
            InitializeComponent();


            this.Controls.Add(picbox);
            picbox.Dock = DockStyle.Fill;

            t.Interval = 5000;
            t.Tick += t_Tick;
            t.Enabled = true;

            this.Shown += Form1_Shown;
            this.SizeChanged += Form1_SizeChanged;

            this.Size = new Size(812, 400);

            this.StartPosition = FormStartPosition.CenterScreen;

        }

        void Form1_Shown(object sender, EventArgs e)
        {
            DrawText();
        }

        void t_Tick(object sender, EventArgs e)
        {
            i++;
            if (i > 3)
            {
                i = 0;
            }
            DrawText();
        }


        private void DrawText()
        {

            // text and font
            string text = "one two three four five six seven eight nine ten eleven twelve";

            Font font = new System.Drawing.Font("Arial", 30, FontStyle.Regular, GraphicsUnit.Point);

            switch (i)
            {
                case 0:
                    picbox.Image = TextDrawing.DrawTextToBitmap(text, font, Color.Red, TextDrawing.DrawMethod.AutosizeAccordingToText, new RectangleF(0, 0, picbox.Width, picbox.Height));
                    break;
                case 1:
                    picbox.Image = TextDrawing.DrawTextToBitmap(text, font, Color.Red, TextDrawing.DrawMethod.AutoFitInConstantRectangleWithoutWarp, new RectangleF(0, 0, picbox.Width, picbox.Height));
                    break;
                case 2:
                    picbox.Image = TextDrawing.DrawTextToBitmap(text, font, Color.Red, TextDrawing.DrawMethod.AutoWarpInConstantRectangle, new RectangleF(0, 0, picbox.Width, picbox.Height));
                    break;
                case 3:
                    picbox.Image = TextDrawing.DrawTextToBitmap(text, font, Color.Red, TextDrawing.DrawMethod.AutoFitInConstantRectangleWithWarp, new RectangleF(0, 0, picbox.Width, picbox.Height));
                    break;
            }
            this.Text = ((TextDrawing.DrawMethod)(i)).ToString() + "                      Please resize window size by mouse to see drawing methods differences";

        }

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            t.Enabled = false;
            t.Enabled = true;
            DrawText();
        }





    }
}

该示例每5秒自动在图形模式之间切换一次。picturebox停靠在主窗体内。调整窗体大小可向用户显示绘图模式之间的差异

您可以用任何字体大小(例如16)测量字符串宽度,然后您可以这样计算所需的字体大小:

fontSize = (previouslyMeasuredFontSize * targetWidthOfString) / previouslyMeasuredStringWidth;

你试过什么吗?请阅读,现在我有一个基于字符串长度的调整大小,字符串越长,字体大小越小,但效果不太好。。。您使用它作为基础,因为将需要一些迭代(基于简单规则,例如减少0.1或更复杂的规则,例如,除以之前大小的一半,如果合适-尝试增加,等等)和一些逻辑,可以在
MeasureStringMin
(如果文本可以多行显示)。
fontSize = (previouslyMeasuredFontSize * targetWidthOfString) / previouslyMeasuredStringWidth;