翻转绘制文本/字符串的 GraphicsPath

2023-11-21

我的文本类中有这个方法,但我似乎无法翻转整个文本。
我正在使用矩阵来变换GraphicsPath用于绘制字符串。

这是我使用@Jimi 的答案后的代码:

    public LayerClass DrawString(LayerClass.Type _text, string text, RectangleF rect, Font _fontStyle, Brush brush, float angle, PaintEventArgs e)
    {
        using (StringFormat string_format = new StringFormat())
        {
            SizeF stringSize = e.Graphics.MeasureString(text, _fontStyle);
            rect.Location = new PointF(Shape.center.X - (rect.Width / 2), Shape.center.Y - (rect.Height / 2));
            GraphicsContainer gc = e.Graphics.BeginContainer();
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
            //e.Graphics.DrawRectangle(Pens.Red, Rectangle.Round(rect));

            RectangleF r = new RectangleF(rect.Location, rect.Size);
            GraphicsPath path = new GraphicsPath();
            if (text == "" || text == " ")
                path.Dispose(); //Disposes the path to prevent OutOfMemoryExcetption
            else
            {
                path.AddString(text, _fontStyle.FontFamily, Convert.ToInt32(_fontStyle.Style), _fontStyle.Height, new Point(0,0), string_format);
                RectangleF text_rectf = path.GetBounds();
                PointF[] target_pts = {
                            new PointF(r.Left, r.Top),
                            new PointF(r.Right, r.Top),
                            new PointF(r.Left, r.Bottom)};
                //e.Graphics.DrawRectangle(Pens.Red, Rectangle.Round(r));
                using (Matrix m = new Matrix(text_rectf, target_pts)) 
                using (Matrix rotate = new Matrix())
                using (Matrix FlipXMatrix = new Matrix(-1, 0, 0, 1, 0, 0)) 
                using (Matrix FlipYMatrix = new Matrix(1, 0, 0, -1, 0, 0))
                using (Matrix TransformMatrix = new Matrix())
                {
                    TransformMatrix.Multiply(m);
                    m.RotateAt(angle, new PointF(0 + (stringSize.Width / 2), +(r.Height * 2)));
                    rotate.RotateAt(angle, new PointF(r.X, r.Y));
                    TransformMatrix.Multiply(rotate);
                    if (flipped)
                    {
                        TransformMatrix.Multiply(FlipXMatrix);
                    }
                    path.Transform(TransformMatrix);

                    if (flipY)
                    {
                        TransformMatrix.Multiply(FlipYMatrix);
                        path.Transform(TransformMatrix);
                    }

                    //Checks if the user wants the text filled or outlined
                    if (!isOutlined)
                        e.Graphics.FillPath(Brushes.Red, path);
                    else
                        e.Graphics.DrawPath(Pens.Red, path);
                } 
            }
        e.Graphics.EndContainer(gc);
        }
        this._Text = text;
        this._TextRect = rect;
        this.brush = brush;
        this._Angle = angle;
        return new LayerClass(_text, this, text, rect);
    }

现在的问题是,它超出了图片框的中心。


有一个更简单的方法flip a Graphics object.
创建一个Matrix这是结果矩阵乘法需要应用于指定对象的所有转换。

矩阵变换可以应用于图形路径对象或Graphics目的。或两者兼而有之,当需要顺序执行多个转换时。

互联网System.Drawing.Drawing2DMatrix 类没有预先构建的Flip(镜像)变换,但是这个 Matrix 结构已经众所周知(我不确定这就是 Matrix 类中没有特定方法的原因):

| 1 | 0 | 0 |       |-1 | 0 | 0 |       | 1 | 0 | 0 |
| 0 | 1 | 0 |       | 0 | 1 | 0 |       | 0 |-1 | 0 |
| 0 | 0 | 1 |       | 0 | 0 | 1 |       | 0 | 0 | 1 |

   Identity         Mirror X-Axis       Mirror Y-Axis
    Matrix              Matrix             Matrix

您可以注意到(文档中也有报告)第三列始终相同,因此,在构建新矩阵时,第三列值是隐含的并由 Matrix 类初始化提供,因此我们仅指定前 2 列。

重要提示,直接来自 Matrix 类文档:

Caution:
复合变换的顺序很重要。一般来说,旋转,然后缩放,然后平移与 缩放,然后旋转,然后平移。类似地,矩阵的阶数 乘法很重要。一般来说,ABC与BAC不一样

绘制在 a 上的字符串的示例Panel使用 GraphicsPath.AddString() method.
两个矩阵变换被添加到GraphicsPath object:
a Flip-X and a Flip-Y,它们使用组合Matrix.Multiply() method:

The Flip-X and Flip-Y构建的矩阵包括X and Y翻译,应用于每个的第三行Matrix。 翻译值由以下因素决定Canvas方面。
例如,Flip-X矩阵:

With a [Canvas].Width = 100 =>:
旋转元件:X轴以原点为中心旋转180°(-1弧度)Point(0, 0).
翻译元素: 翻译X位置100右侧的图形单位(正值)。

| -1  |  0  |  0  |
|  0  |  1  |  0  |
| 100 |  0  |  1  |

   Mirror X-Axis
  Translate X +100
      Matrix 

效果的视觉表示。
代码中引用的控件与您在此处看到的相同(如果您需要重现它)。

Matrix Flip

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;

bool flipX = false;
bool flipY = false;
bool outlined = false;
float sampleFontEmSize = 28f;
string sampleText = "Sample Text to Flip";
FontFamily sampleFont = new FontFamily("Segoe UI");

private void panel1_Paint(object sender, PaintEventArgs e)
{
    Panel panel = sender as Panel;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    using (var path = new GraphicsPath())
    using (var format = new StringFormat(StringFormatFlags.NoClip | StringFormatFlags.NoWrap))
    {
        format.Alignment = StringAlignment.Center;
        format.LineAlignment = StringAlignment.Center;
        path.AddString(sampleText, sampleFont, (int)FontStyle.Regular, sampleFontEmSize, panel.ClientRectangle, format);

        using (var flipXMatrix = new Matrix(-1, 0, 0, 1, panel.Width, 0))
        using (var flipYMatrix = new Matrix(1, 0, 0, -1, 0, panel.Height))
        using (var transformMatrix = new Matrix())
        {
            if (flipX) {
                transformMatrix.Multiply(flipXMatrix);
            }
            if (flipY) {
                transformMatrix.Multiply(flipYMatrix);
            }
            path.Transform(transformMatrix);
            //Or e.Graphics.Transform = TransformMatrix;

            if (outlined) {
                e.Graphics.DrawPath(Pens.LawnGreen, path);
            }
            else {
                e.Graphics.FillPath(Brushes.Orange, path);
            }
        }
    }
}

private void btnFlipX_Click(object sender, EventArgs e)
{
    flipX = !flipX;
    panel1.Invalidate();
}

private void btnFlipY_Click(object sender, EventArgs e)
{
    flipY = !flipY;
    panel1.Invalidate();
}

private void chkOutlined_CheckedChanged(object sender, EventArgs e)
{
    outlined = chkOutlined.Checked;
    panel1.Invalidate();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

翻转绘制文本/字符串的 GraphicsPath 的相关文章

  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • 如何在我的应用程序中使用 Windows Key

    Like Windows Key E Opens a new Explorer Window And Windows Key R Displays the Run command 如何在应用程序的 KeyDown 事件中使用 Windows
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • 使用 C# 在 WinRT 中获取可用磁盘空间

    DllImport kernel32 dll SetLastError true static extern bool GetDiskFreeSpaceEx string lpDirectoryName out ulong lpFreeBy
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • c# Asp.NET MVC 使用FileStreamResult下载excel文件

    我需要构建一个方法 它将接收模型 从中构建excel 构建和接收部分完成没有问题 然后使用内存流导出 让用户下载它 不将其保存在服务器上 我是 ASP NET 和 MVC 的新手 所以我找到了指南并将其构建为教程项目 public File
  • HttpClient 像浏览器一样请求

    当我通过 HttpClient 类调用网站 www livescore com 时 我总是收到错误 500 可能服务器阻止了来自 HttpClient 的请求 1 还有其他方法可以从网页获取html吗 2 如何设置标题来获取html内容 当
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • 初始化变量的不同方式

    在 C 中初始化变量有多种方法 int z 3 与 int 相同z 3 Is int z z 3 same as int z z 3 您可以使用 int z z 3 Or just int z 3 Or int z 3 Or int z i
  • 将 System.Windows.Forms.Keys 序列转换为 Char

    有没有办法转换由 Keys 枚举表示的击键序列 即System Windows Forms Keys 在一个字符中 例如 Keys Oem4进而Keys A产生 char 它一定存在于 WinAPI 中的某个地方 因为当我在文本框中按下按键
  • 将日期参数传递给对 MVC 操作的 ajax 调用的安全方法

    我有一个 MVC 操作 它的参数之一是DateTime如果我通过 17 07 2012 它会抛出一个异常 指出参数为空但不能有空值 但如果我通过01 07 2012它被解析为Jan 07 2012 我将日期传递给 ajax 调用DD MM
  • EPPlus Excel 更改单元格颜色

    我正在尝试将给定单元格的颜色设置为另一个单元格的颜色 该单元格已在模板中着色 但worksheet Cells row col Style Fill BackgroundColor似乎没有get财产 是否可以做到这一点 或者我是否必须在互联
  • 作为字符串的动态属性名称

    使用 DocumentDB 创建新文档时 我想设置属性名称动态地 目前我设置SomeProperty 像这样 await client CreateDocumentAsync dbs db colls x new SomeProperty
  • char指针或char变量的默认值是什么[重复]

    这个问题在这里已经有答案了 下面是我尝试打印 char 变量和指针的默认值 值的代码 但无法在控制台上看到它 它是否有默认值或只是无法读取 ASCII 范围 include
  • 已过时 - OpenCV 的错误模式

    我正在使用 OpenCV 1 进行一些图像处理 并且对 cvSetErrMode 函数 它是 CxCore 的一部分 感到困惑 OpenCV 具有三种错误模式 叶 调用错误处理程序后 程序终止 Parent 程序没有终止 但错误处理程序被调
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 窗体最大化时自动缩放子控件

    有没有办法在最大化屏幕或更改分辨率时使 Windows 窗体上的所有内容自动缩放 我发现手动缩放它是正确的 但是当切换分辨率时我每次都必须更改它 this AutoScaleDimensions new System Drawing Siz
  • 更改显示的 DPI 缩放大小使 Qt 应用程序的字体大小渲染得更大

    我使用 Qt 创建了一些 GUI 应用程序 我的 GUI 应用程序包含按钮和单选按钮等控件 当我运行应用程序时 按钮内的按钮和字体看起来正常 当我将显示器的 DPI 缩放大小从 100 更改为 150 或 200 时 无论分辨率如何 控件的

随机推荐

  • 失败时自动再次尝试 AJAX 请求

    我看到你可以指定如果 ajax 请求失败一般要做什么 是否可以让它在某种循环中重试 以便它在停止之前至少尝试 x 次 我之前使用过这段代码 ajaxSetup error function alert error 这将适用于所有 AJAX
  • 在 5.0 中打开项目后无法在 Xcode 4.6 中打开项目

    我在 Xcode 5 中打开了错误版本的项目 现在 Xcode 4 6 在尝试打开该项目时崩溃了 我只在 Xcode 5 中更改了一个 xib 文件 并使用 Xcode 5 在 IB 中打开了 xib 并在 Interface Builde
  • MATLAB 中的 SVM 可视化

    在 Matlab 中执行 SVM 训练后 如何可视化 SVM 分类 到目前为止 我只用以下方法训练了 SVM Labels are 1 or 1 groundTruth Ytrain d xtrain model svmtrain grou
  • 如何创建 JSON 数组?

    你好 我想创建一个 JSON 数组 我尝试过使用 JSONArray jArray new JSONArray while itr hasNext int objId itr next jArray put objId odao getOb
  • 带参数的 Java Webstart

    我可以启动一个Java网络启动具有一组参数的应用程序就像使用 标签配置小程序一样 Thanks 是的 您可以 下面显示了一个示例
  • HTML5/JS - 启动多个网络工作者

    我目前正在编写一个程序 我必须处理巨大的数组 但是我可以拆分这些数组 我现在的计划是 在不同的网络工作者中处理数组 然而 我从未与他们合作过 并且确实有几个问题 1 我将如何运行多个网络工作者 我尝试了一个看起来像这样的 for 循环 fo
  • Angular 如何测试@HostListener

    我有以下指令 当应用于输入元素时 它会检查字符并在禁止字符时调用 PreventDefault Directive selector cdtPreventInput export class PreventInputDirective im
  • 从google帐户获取用户名、头像

    我正在开发一个使用 GoogleAccountCredential 登录 上传和下载文件到 GoogleDrive 的模块 我想让谷歌帐户的用户名 姓氏和头像显示在我的登录功能上 I ve try GoogleAccountCredenti
  • 使 ASP.NET WCF 将字典转换为 JSON,省略“Key”和“Value”标签

    这是我的困境 我正在使用 RESTful ASP NET 服务 尝试获取一个函数来返回以下格式的 JSON 字符串 Test1Key Test1Value Test2Key Test2Value Test3Key Test3Value 但我
  • Python变量是指针吗?或者说,它们是什么?

    据我所知 Python 中的变量只是指针 根据这条规则 我可以假设此代码片段的结果 i 5 j i j 3 print i 将会3 但我得到了一个令我意想不到的结果 那就是5 此外 我的 Python 书确实介绍了这个示例 i 1 2 3
  • 不需要的双导航栏

    当我点击屏幕时 我使导航栏 顶部栏 出现 消失 并且也位于背景图像的顶部 它有效 但有一个问题 我突然有两个导航栏 首先 有一个名为 后退 的后退按钮 当我按 后退 时 它会弹出一个新的导航栏 其中有一个名为 Vinene 的后退按钮 这是
  • glClear(GL_COLOR_BUFFER_BIT) 后 OpenGL 无效帧缓冲区操作;

    每次我打电话后glClear GL COLOR BUFFER BIT 我收到 OpenGL 错误 无效的帧缓冲区操作 通话似乎工作正常 没有任何问题 我打电话glClear GL COLOR BUFFER BIT 第一件事在 paintGL
  • 这个规范的集群示例是如何工作的?

    当必须通过文件系统同步程序 shell脚本 时 我发现了一种flock基于的解决方案是受到推崇的 也应该工作on NFS 在脚本中使用的规范示例 来自http linux die net man 1 flock is flock s 200
  • C# 中的 URL Slugify 算法?

    所以我搜索并浏览了slug标记 SO 并只找到两个引人注目的解决方案 C 中的 Slugify 和字符转写 如何在 C 中将上标或下标转换为普通文本 这只是问题的部分解决方案 我可以自己手动编写代码 但令我惊讶的是还没有解决方案 那么 C
  • 大约持续 2 秒后出现“设备上没有剩余空间”的信息EMR m1.large 实例上有 10 GB 数据

    当我使用 m1 large 作为作业流要创建的 hadoop 实例的实例类型来运行 Amazon EMR 作业时 我收到错误 设备上没有剩余空间 该工作产生约 最大 10 GB 数据 因为 m1 large 实例的容量应该为 420GB 2
  • 有没有办法使用 EF Core 映射复杂类型

    EF Core 不支持复杂类型映射 如果我有一个对象 例如 public class Entity public string StringProp get set public SubEntity NestedEntity get set
  • 如何获取当前用户目录?

    使用这个 Environment GetFolderPath Environment SpecialFolder ApplicationData 我得到这个输出 C Documents and Settings USER Applicati
  • GIT:在新/脏/开发分支中将更改提交到旧/安全分支,而不检出或丢失未暂存的数据

    在开始进行实验性开发之前 我创建了一个新分支 我通常会忘记这一点 这不是问题 但现在我提前做了 从那时起我已经更新了3个文件 2 中只是实验性更改 我不想将其提交到安全分支 在 1 中只是安全 较小的 更改 我绝对希望将其提交到安全分支 我
  • 在 PostgreSQL 中将 bytea 表示为单个整数的最简单方法是什么?

    我有一个bytea包含 14 字节数据的列 14 个字节的最后 3 个字节包含数据的 CRC 码 我想将 CRC 提取为单个整数以存储在新列中 我该怎么做呢 为了澄清这一点 下面是在 Java 中执行此操作的一种方法 int crc raw
  • 翻转绘制文本/字符串的 GraphicsPath

    我的文本类中有这个方法 但我似乎无法翻转整个文本 我正在使用矩阵来变换GraphicsPath用于绘制字符串 这是我使用 Jimi 的答案后的代码 public LayerClass DrawString LayerClass Type t