【问题标题】:Character appears like white box when calling method DrawString调用方法 DrawString 时字符显示为白框
【发布时间】:2012-06-23 07:08:12
【问题描述】:

我有一个很好的问题要问你。我搜索了所有的 Google 和 MSDN 并没有找到任何东西。

我正在尝试做一个程序,将字体导出为每个字符的单个 PNG 图像。我目前正在使用新的 Windows 字体 Segoe UI Symbol 对其进行测试。请注意,我知道字体许可条款,我不会在互联网上分发该字体。

好吧,当我调用 DrawString 方法时,真正的问题正在发生,Graphics 的成员。我将 unicode 整数值转换为 char,然后转换为字符串。我已经尝试使用char.ConvertFromUtf32()Convert.ToChar() 将整数转换为char。

程序在 26 个字符期间运行良好(从 57344 = 0xE000 开始),当我使用数值时问题不会出现,直到 57370。在此之后,没有一个数字不是用白框字符写的。

经过一番搜索,我发现Font 构造函数的重载,其属性为gdiCharset,并尝试将其值用作2,但没有任何反应。

我在下面为您显示源代码。请,如果有人可以帮助我,我会很高兴。

更新 当我使用转义序列时(例如 "\uE1FF" 而不是 char 转换它可以工作!但我不知道如何在 for 循环中制作转义序列。

        Font segoe = new Font("Segoe UI Symbol", 800, FontStyle.Regular, GraphicsUnit.Pixel, 2);

        Bitmap bmedidor = new Bitmap(1000, 1000, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        Graphics gmedidor = Graphics.FromImage(bmedidor);
        // This line below doesn't matter, see the method DrawString
        Size tamanho = gmedidor.MeasureString(char.ConvertFromUtf32(57344).ToString(), segoe).ToSize();

        int[] reducoes = new int[6] {512, 256, 128, 64, 32, 16};
        string caminho = "C:\\InoMetro";


        for (int u = 57344; u < 57896; u++)
        {
            Bitmap caractere = new Bitmap(tamanho.Width, tamanho.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            Graphics criador = Graphics.FromImage(caractere);

            criador.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            criador.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            criador.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            criador.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            // Here we have the problem
            criador.DrawString(Convert.ToChar(u).ToString(), segoe, new SolidBrush(Color.Black), new PointF(0, 0));

            for (int r = 0; r < reducoes.Length; r++)
            {
                int taR = reducoes[r];

                Bitmap reducao = new Bitmap(taR, taR, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                Graphics redutor = Graphics.FromImage(reducao);

                redutor.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                redutor.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                redutor.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                redutor.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

                redutor.DrawImage(caractere, 0, 0, taR, taR);
                reducao.Save(caminho + "\\" + taR.ToString() + "\\" + u.ToString() + ".png", System.Drawing.Imaging.ImageFormat.Png);

            }

        }

【问题讨论】:

    标签: c# .net gdi


    【解决方案1】:

    U+E000-U+F8FF(十进制57344-63743)为Private Use Area characters

    大多数字体(包括 Segoe UI Symbol)不为该范围内的任何代码点提供字形,因此典型的后备行为是字体渲染器显示白色框 () 或黑色菱形中的问号(�) 当被要求绘制这些代码点之一时。

    Windows 8 上的 Segoe UI Symbol 仅定义 U+E000-U+E019 的字形,然后不提供 U+E01A-U+E051 的字形;这就是从 57370 (0xE01A) 到 57425 (0xE051) 显示白框的原因。

    【讨论】:

    • 我的系统(Windows 7 SP1 x64)上该范围内的每个代码点都有一个白框。您系统上的 charmap 是否显示 Segoe UI Symbol 具有该范围内的代码点字形?
    • 最可能的解释(我现在无法测试)是 Windows 8 附带的 Segoe UI Symbol 版本包含 26 个私人使用字符(在 U+E000-U+E01A)。对于任何其他代码点,将显示一个白框,因为字体不包含这些字符。你期待的是什么?
    • 对不起,我想我不清楚解释...我的字体版本中的字符 U+F013 之前都有字形,但是用 GDI 编写时,它只能工作到 57370。
    • 在 Windows 8 上,Segoe UI 符号包含 U+E000-U+E019、U+E052、U+E070-U+E072、U+E07D-U+E1EB、U+E200- 的字形E236 等等。定义的字形不连续,并且有很多没有字形的代码点。 (例如,在 U+E026A-U+F005 之间没有字形。)具体来说,针对您的问题,U+E01A-U+E051(十进制 57370-57425)没有字形,将在你的程序。
    • 所以,我想我没想到循环会导出所有字符。我将尝试导出所有循环并选择您的最佳答案:) 无论如何,谢谢。
    猜你喜欢
    • 2016-07-28
    • 1970-01-01
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 2015-12-23
    • 1970-01-01
    相关资源
    最近更新 更多