2

当绘图矩阵具有较大的偏移值时,我遇到了绘图文本和基本图形绘图操作没有正确放置和质量的问题。我尝试了数字 SmoothMode、InterpolationMode 和 TextRenderingHint 选项,但没有成功。

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

public void RenderImageClosePointDrawing()
    {
        float x = 68336, y = 99460;            
        PointF anchorPoint = new PointF(17494176, 25461836);
        PointF anchorPoint2= new PointF(17494076, 25461836);
        string textLabel = "9318";
        float textFontSize = 20;
        float symbolsize = 34;
        string fontFamly = "Arial";

        Bitmap bitmap = new Bitmap(256, 256);
        using (Graphics graphics = Graphics.FromImage(bitmap))
        {
            graphics.SmoothingMode = SmoothingMode.HighQuality;                
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

            graphics.Transform = new Matrix(1, 0, 0, 1, -x * 256, -y * 256);

            //Draw the circle
            Pen polyPen = new Pen(new SolidBrush(Color.Black), 2);
            Brush polyBrush = new SolidBrush(Color.Teal);
            graphics.DrawEllipse(polyPen, anchorPoint.X, anchorPoint.Y, symbolsize, symbolsize);
            graphics.FillEllipse(polyBrush, anchorPoint.X, anchorPoint.Y, symbolsize, symbolsize);
            RectangleF drawnArea = new RectangleF(anchorPoint.X, anchorPoint.Y, symbolsize, symbolsize);

            Pen polyPen2 = new Pen(new SolidBrush(Color.Black), 1);
            Brush polyBrush2 = new SolidBrush(Color.Teal);
            graphics.DrawEllipse(polyPen2, anchorPoint2.X, anchorPoint2.Y, symbolsize, symbolsize);
            graphics.FillEllipse(polyBrush2, anchorPoint2.X, anchorPoint2.Y, symbolsize, symbolsize);
            RectangleF drawnArea2 = new RectangleF(anchorPoint2.X, anchorPoint2.Y, symbolsize, symbolsize);

            Pen polyPen3 = new Pen(new SolidBrush(Color.Red), 1);
            graphics.DrawRectangle(polyPen3, drawnArea.X, drawnArea.Y, drawnArea.Width, drawnArea.Height);
            graphics.DrawRectangle(polyPen3, drawnArea2.X, drawnArea2.Y, drawnArea2.Width, drawnArea2.Height);

            //Draw the text
            Pen textOutlinePen = new Pen(new SolidBrush(Color.Orange), (float)4);
            textOutlinePen.EndCap = LineCap.Round;
            textOutlinePen.LineJoin = LineJoin.Round;
            textOutlinePen.MiterLimit = 0;
            Brush textFillBrush = new SolidBrush(Color.Teal);
            FontFamily textFontFamily = new FontFamily(fontFamly);

            PointF textAnchor = new PointF(anchorPoint.X, anchorPoint.Y);

            ShiftTextAnchor_NW(textLabel, textFontSize, ref drawnArea, textFontFamily, ref textAnchor);

            var textPath = new GraphicsPath();
            textPath.AddString(textLabel,
                            textFontFamily,
                            (int)FontStyle.Bold,
                            textFontSize,
                            textAnchor,
                            new StringFormat()
                        );
            graphics.DrawPath(textOutlinePen, textPath);
            graphics.FillPath(textFillBrush, textPath);



            //Draw the text2
            Pen textOutlinePen2 = new Pen(new SolidBrush(Color.Orange), (float)1);
            textOutlinePen.EndCap = LineCap.Round;
            textOutlinePen.LineJoin = LineJoin.Round;
            textOutlinePen.MiterLimit = 0;

            PointF textAnchor2 = new PointF(anchorPoint2.X, anchorPoint2.Y);

            ShiftTextAnchor_NW(textLabel, textFontSize, ref drawnArea2, textFontFamily, ref textAnchor2);

            var textPath2 = new GraphicsPath();
            textPath2.AddString(textLabel,
                            textFontFamily,
                            (int)FontStyle.Bold,
                            textFontSize,
                            textAnchor2,
                            new StringFormat()
                        );
            graphics.DrawPath(textOutlinePen2, textPath2);
            graphics.FillPath(textFillBrush, textPath2);

        }
        bitmap.Save(@"C:\ClosePointDrawing.png", ImageFormat.Png);
    }

private static void ShiftTextAnchor_NW(string textLabel, float textFontSize, ref RectangleF drawnArea, FontFamily textFontFamily, ref PointF textAnchor)
    {
        GraphicsPath tempPath = new GraphicsPath();
        tempPath.AddString(
                textLabel,
                textFontFamily,
                (int)FontStyle.Bold,
                textFontSize,
                textAnchor,
                new StringFormat()
            );
        var textBounds = tempPath.GetBounds();
        var offsetX = textBounds.X - textAnchor.X;
        var offsetY = textBounds.Y - textAnchor.Y;

        textAnchor = new PointF(drawnArea.Left - (textBounds.Width + offsetX), drawnArea.Top - (textBounds.Height + offsetY));
    }      

当您运行此代码时,您将获得以下输出:ClosePointDrawing.png

您会注意到文本看起来不太好(有些失真),并且当使用 1 像素笔划时,圆圈周围的黑色笔触轮廓仅与其蓝绿色填充的圆圈正确对齐,左侧的那个圆圈. 右边的一个使用 2 像素的笔画。您还会看到红色方块没有与蓝绿色圆圈对齐,它们应该完全封装它。

现在,如果您更改代码中的前几个值,使其不使用大偏移量,如下所示: float x = 0, y = 0; PointF anchorPoint = new PointF(150, 50); PointF anchorPoint2 = new PointF(50, 50);

您将得到以下输出:ClosePointDrawing2.png 请注意,文本看起来好多了,笔触与实心圆圈和红色方块完美对齐。

有什么可以做的,以便它可以用更大的矩阵正确渲染它?

4

0 回答 0