#c# #.net #system.drawing #drawing2d
#c# #.net #system.drawing #drawing2d
Вопрос:
Я столкнулся с проблемой, связанной с тем, что при рисовании текста и основных графических операций рисования не было надлежащего размещения и качества, когда матрица рисования имеет большие значения смещения. Я пробовал параметры number 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 Обратите внимание, что текст выглядит намного лучше, и что штрихи идеально выровнены с заполненными кругами, а также красными квадратами.
Можно ли что-нибудь сделать, чтобы он правильно отображал его с большей матрицей?
Комментарии:
1. Интересно, может ли GDI обрабатывать такие большие значения, и удивлен, что он вообще дал какие-либо результаты. Почему вы хотите сделать такую вещь и на растровом изображении 256×256 тоже???
2. Для обработки координат плитки карты Google на ближайшем уровне масштабирования. Итак, единственный способ справиться с этим — выполнить настройку смещения самостоятельно, а не с помощью матрицы преобразования?
3. GDI использует 32-разрядные значения с плавающей запятой для внутренней математики. То же, что и float в программе C #. Точность довольно ограничена, максимум 6 значащих цифр при выполнении любой математики. Обратите внимание, что 17494176 уже далеко за пределами этого, ошибка округления выводит материал из строя. Вам придется писать более умный код.