翻转绘制文本/字符串的GraphicsPath [英] Flip the GraphicsPath that draws the text/string
问题描述
我的文本类中有此方法,我似乎无法翻转整个文本.
我正在使用矩阵转换用于绘制字符串的GraphicsPath
.
I have this method in my Text Class and I can't seem to flip the whole text.
I am using a Matrix to transform the GraphicsPath
which is used to draw the string.
这是我使用@Jimi的答案以来的代码:
Here's the code since I used @Jimi's answer:
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);
}
现在的问题是,它超出了图片框的中心.
Now the problem is, it goes out the center of the picturebox.
推荐答案
有一种更简单的方法 flip Graphics
对象.
创建一个矩阵,它是
There is a simpler way to flip a Graphics
object.
Create a Matrix which is the result of the Matrix multiplication of all the transformations that need to be applied to the specified object.
A Matrix transformation can be applied to either the GraphicsPath object or the Graphics
object. Or both, when multiple transformation need to be performed sequentially.
.Net System.Drawing.Drawing2D
Matrix类没有预构建的Flip
(镜像)转换,但是这种Matrix结构已经众所周知(我不确定这是为什么没有Matrix类中的特定方法):
The .Net System.Drawing.Drawing2D
Matrix class does not have a pre-built Flip
(mirroring) transformation, but this Matrix structure is already well known (I'm not sure this is the reason why there isn't a specific method in the Matrix class):
| 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时,隐含第三列值并由Matrix类初始化提供,因此我们仅指定前2列中的元素.
You can notice (it's also reported in the Docs) that the 3rd column is always the same, therefore, when building a new Matrix, the 3rd column values are implied and are provided by the Matrix class initialization, so we specify just the elements in the first 2 columns.
重要注释,直接来自Matrix类Docs:
Important note, straight from the Matrix class Docs:
警告:
复合转换的顺序很重要.通常,先旋转,然后缩放,然后平移与 缩放,然后旋转,然后平移.同样,矩阵的阶数 乘法很重要.一般来说,ABC与BAC是不同的
Caution:
The order of a composite transformation is important. In general, rotate, then scale, then translate is not the same as scale, then rotate, then translate. Similarly, the order of matrix multiplication is important. In general, ABC is not the same as BAC
使用
将两个Matrix转换添加到GraphicsPath
对象:
Flip-X
和Flip-Y
,它们使用Matrix.Multiply()
方法结合在一起:
An example of a string drawn on a Panel
using the GraphicsPath.AddString() method.
Two Matrix transformations are added to the GraphicsPath
object:
a Flip-X
and a Flip-Y
, which are combined using the Matrix.Multiply()
method:
Flip-X
和Flip-Y
矩阵的构建包括对每个Matrix
的第三行的X
和Y
转换.
翻译值由 Canvas 尺寸确定.
例如,Flip-X
矩阵:
The Flip-X
and Flip-Y
Matrices are built including the X
and Y
translations, applied to the 3rd row of each Matrix
.
The translation values are determined by the Canvas dimensions.
For example, the Flip-X
Matrix:
带有[Canvas].Width = 100 =>
:
旋转元素:在原点Point(0, 0)
上将X轴旋转180°(-1弧度).
翻译元素:将X
位置100
图形单位向右平移(正值).
With a [Canvas].Width = 100 =>
:
Rotation Element : Rotate the X-Axis 180° (-1 radians) on the origin Point(0, 0)
.
Translate Element: Translate the X
Position 100
Graphics Units to the right (positive value).
| -1 | 0 | 0 |
| 0 | 1 | 0 |
| 100 | 0 | 1 |
Mirror X-Axis
Translate X +100
Matrix
效果的视觉表示.
代码中引用的控件与您在此处看到的控件相同(如果需要重现).
A visual representation of the effect.
The Controls referenced in the code are the same you can see here (if you need to reproduce it).
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();
}
这篇关于翻转绘制文本/字符串的GraphicsPath的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!