Поделиться через


Интеграция текста и графики

Узнайте, как определить размер отрисоченной текстовой строки для интеграции текста с графикой SkiaSharp

В этой статье показано, как измерять текст, масштабировать текст до определенного размера и интегрировать текст с другими рисунками:

Текст, окруженный прямоугольниками

Это изображение также включает округленный прямоугольник. Класс SkiaSharp Canvas включает DrawRect методы рисования прямоугольника и DrawRoundRect методов для рисования прямоугольника с закругленными углами. Эти методы позволяют прямоугольнику определяться как SKRect значение или другими способами.

Страница "Кадрированный текст " центрирует короткую текстовую строку на странице и окружает ее кадром, состоящим из пары округленных прямоугольников. В FramedTextPage классе показано, как это сделать.

В SkiaSharp класс используется SKPaint для задания атрибутов текста и шрифта, но его также можно использовать для получения отрисованного размера текста. В начале следующего PaintSurface обработчика событий вызывается два разных MeasureText метода. Первый MeasureText вызов имеет простой string аргумент и возвращает ширину пикселя текста на основе текущих атрибутов шрифта. Затем программа вычисляет новое TextSize свойство SKPaint объекта на основе этой отрисовки ширины, текущего TextSize свойства и ширины области отображения. Это вычисление предназначено для задания TextSize , чтобы текстовая строка отображалась в 90 % ширины экрана:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    SKImageInfo info = args.Info;
    SKSurface surface = args.Surface;
    SKCanvas canvas = surface.Canvas;

    canvas.Clear();

    string str = "Hello SkiaSharp!";

    // Create an SKPaint object to display the text
    SKPaint textPaint = new SKPaint
    {
        Color = SKColors.Chocolate
    };

    // Adjust TextSize property so text is 90% of screen width
    float textWidth = textPaint.MeasureText(str);
    textPaint.TextSize = 0.9f * info.Width * textPaint.TextSize / textWidth;

    // Find the text bounds
    SKRect textBounds = new SKRect();
    textPaint.MeasureText(str, ref textBounds);
    ...
}

Второй MeasureText вызов имеет SKRect аргумент, поэтому он получает как ширину, так и высоту отрисованного текста. Height Свойство этого SKRect значения зависит от наличия прописных букв, возрастающих и нисходящих значений в текстовой строке. Для текстовых строк "мама", "кошка" и "собака", например, отображаются разные Height значения.

И LeftTop свойства SKRect структуры указывают координаты левого верхнего угла отрисованного текста, если текст отображается вызовом DrawText с позициями X и Y 0. Например, когда эта программа выполняется на симуляторе i Телефон 7, TextSize назначается значение 90,6254 в результате вычисления после первого вызоваMeasureText. Значение SKRect , полученное из второго вызова MeasureText , имеет следующие значения свойств:

  • Left = 6
  • Top = –68
  • Width = 664.8214
  • Height = 88;

Помните, что координаты X и Y, которые передаются DrawText методу, указывают левую сторону текста на базовом уровне. Значение Top указывает, что текст расширяется на 68 пикселей выше базового плана и (вычитая 68 из 88) 20 пикселей ниже базового плана. Значение Left 6 указывает, что текст начинается шесть пикселей справа от значения X в вызове DrawText . Это позволяет нормально выполнять интервалы между символами. Если вы хотите отобразить текст в левом верхнем углу экрана, передайте отрицательные значения в LeftTop виде координат DrawTextX и Y в этом примере –6 и 68.

Структура SKRect определяет несколько удобных свойств и методов, некоторые из которых используются в оставшейся части обработчика PaintSurface . И MidXMidY значения указывают координаты центра прямоугольника. (В примере i Телефон 7 эти значения : 338,4107 и –24.) Следующий код использует эти значения для простого вычисления координат для центра текста на дисплее:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    ...
    // Calculate offsets to center the text on the screen
    float xText = info.Width / 2 - textBounds.MidX;
    float yText = info.Height / 2 - textBounds.MidY;

    // And draw the text
    canvas.DrawText(str, xText, yText, textPaint);
    ...
}

Структура SKImageInfo сведений также определяет Rect свойство типа SKRect, поэтому вы также можете вычислить xText и yText , как показано ниже.

float xText = info.Rect.MidX - textBounds.MidX;
float yText = info.Rect.MidY - textBounds.MidY;

Обработчик PaintSurface завершается двумя вызовами DrawRoundRect, для которых требуются аргументы SKRect. Это SKRect значение основано на значении SKRect , полученном MeasureText из метода, но оно не может быть таким же. Во-первых, он должен быть немного больше, чтобы округленный прямоугольник не рисовал по краям текста. Во-вторых, он должен быть смещен в пространстве, чтобы Left и Top значения соответствовали верхнему левому углу, где прямоугольник должен быть расположен. Эти два задания выполняются с помощью методов, Inflate определенных следующими способами OffsetSKRect:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    ...
    // Create a new SKRect object for the frame around the text
    SKRect frameRect = textBounds;
    frameRect.Offset(xText, yText);
    frameRect.Inflate(10, 10);

    // Create an SKPaint object to display the frame
    SKPaint framePaint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        StrokeWidth = 5,
        Color = SKColors.Blue
    };

    // Draw one frame
    canvas.DrawRoundRect(frameRect, 20, 20, framePaint);

    // Inflate the frameRect and draw another
    frameRect.Inflate(10, 10);
    framePaint.Color = SKColors.DarkBlue;
    canvas.DrawRoundRect(frameRect, 30, 30, framePaint);
}

После этого оставшаяся часть метода прямо вперед. Он создает еще один SKPaint объект для границ и вызывает DrawRoundRect дважды. Во втором вызове используется прямоугольник, забитый еще на 10 пикселей. Первый вызов задает радиус угла в 20 пикселей. Второй имеет угловой радиус 30 пикселей, поэтому они, кажется, параллельны:

Тройной снимок экрана страницы

Вы можете повернуть телефон или симулятор в сторону, чтобы увидеть текст и кадр увеличение размера.

Если вам нужно только центрировать текст на экране, это можно сделать примерно без измерения текста. Вместо этого задайте TextAlign свойство SKPaint элемента SKTextAlign.Centerперечисления. Координата X, указанная в методе DrawText , указывает, где расположен горизонтальный центр текста. Если вы передаете середину экрана DrawText методу, текст будет горизонтально центрирован и почти по вертикали, так как базовый план будет по вертикали по центру.

Текст можно рассматривать так же, как и любой другой графический объект. Одним из простых вариантов является отображение контура текстовых символов:

Снимок тройного экрана страницы

Это можно сделать, просто изменив обычное Style свойство SKPaint объекта с его значения SKPaintStyle.FillSKPaintStyle.Strokeпо умолчанию и указав ширину штриха. Обработчик PaintSurface страницы "Контурированный текст" показывает, как это сделать:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    SKImageInfo info = args.Info;
    SKSurface surface = args.Surface;
    SKCanvas canvas = surface.Canvas;

    canvas.Clear();

    string text = "OUTLINE";

    // Create an SKPaint object to display the text
    SKPaint textPaint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        StrokeWidth = 1,
        FakeBoldText = true,
        Color = SKColors.Blue
    };

    // Adjust TextSize property so text is 95% of screen width
    float textWidth = textPaint.MeasureText(text);
    textPaint.TextSize = 0.95f * info.Width * textPaint.TextSize / textWidth;

    // Find the text bounds
    SKRect textBounds = new SKRect();
    textPaint.MeasureText(text, ref textBounds);

    // Calculate offsets to center the text on the screen
    float xText = info.Width / 2 - textBounds.MidX;
    float yText = info.Height / 2 - textBounds.MidY;

    // And draw the text
    canvas.DrawText(text, xText, yText, textPaint);
}

Другим общим графическим объектом является растровое изображение. Это большая тема, подробно описанная в разделе SkiaSharp Bitmaps, но следующая статья, Bitmap Basics in SkiaSharp, содержит краткое введение.