Freigeben über


Integrieren von Text und Grafiken

Erfahren Sie, wie Sie die Größe der gerenderten Textzeichenfolge bestimmen, um Text in SkiaSharp-Grafiken zu integrieren.

In diesem Artikel wird veranschaulicht, wie Sie Text messen, den Text auf eine bestimmte Größe skalieren und Text in andere Grafiken integrieren:

Text umgeben von Rechtecke

Dieses Bild enthält auch ein abgerundetes Rechteck. Die SkiaSharp-Klasse Canvas enthält DrawRect Methoden zum Zeichnen eines Rechtecks und DrawRoundRect methoden zum Zeichnen eines Rechtecks mit abgerundeten Ecken. Mit diesen Methoden kann das Rechteck als SKRect Wert oder auf andere Weise definiert werden.

Die Seite "Rahmentext " zentriert eine kurze Textzeichenfolge auf der Seite und umgibt sie in einen Rahmen, der aus einem Paar abgerundeter Rechtecke besteht. Die FramedTextPage Klasse zeigt, wie sie fertig ist.

In SkiaSharp verwenden Sie die SKPaint Klasse zum Festlegen von Text- und Schriftartattributen, sie können aber auch zum Abrufen der gerenderten Textgröße verwenden. Der Anfang des folgenden PaintSurface Ereignishandlers ruft zwei verschiedene MeasureText Methoden auf. Der erste MeasureText Aufruf weist ein einfaches string Argument auf und gibt die Pixelbreite des Texts basierend auf den aktuellen Schriftartattributen zurück. Das Programm berechnet dann eine neue TextSize Eigenschaft des SKPaint Objekts basierend auf dieser gerenderten Breite, der aktuellen TextSize Eigenschaft und der Breite des Anzeigebereichs. Diese Berechnung soll so festgelegt TextSize werden, dass die Textzeichenfolge bei 90 % der Bildschirmbreite gerendert werden soll:

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);
    ...
}

Der zweite MeasureText Aufruf weist ein SKRect Argument auf, sodass er sowohl eine Breite als auch eine Höhe des gerenderten Texts abruft. Die Height Eigenschaft dieses SKRect Werts hängt vom Vorhandensein von Großbuchstaben, Aufsteigenden und Absteigenden in der Textzeichenfolge ab. Für die Textzeichenfolgen "mom", "cat" und "dog" werden beispielsweise unterschiedliche Height Werte gemeldet.

Die Left Eigenschaften Top der SKRect Struktur geben die Koordinaten der oberen linken Ecke des gerenderten Texts an, wenn der Text durch einen DrawText Aufruf mit X- und Y-Positionen von 0 angezeigt wird. Wenn dieses Programm beispielsweise auf einem i Telefon 7 Simulator ausgeführt wird, TextSize wird dem Wert 90,6254 als Ergebnis der Berechnung nach dem ersten Aufruf zugewiesenMeasureText. Der SKRect vom zweiten Aufruf MeasureText abgerufene Wert weist die folgenden Eigenschaftswerte auf:

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

Denken Sie daran, dass die X- und Y-Koordinaten, die Sie an die DrawText Methode übergeben, die linke Seite des Texts an der Basislinie angeben. Der Top Wert gibt an, dass der Text 68 Pixel über dieser Basislinie erweitert und (68 von 88) 20 Pixel unter der Basislinie subtrahiert. Der Left Wert 6 gibt an, dass der Text sechs Pixel rechts neben dem X-Wert im DrawText Aufruf beginnt. Dies ermöglicht den normalen Abstand zwischen Zeichen. Wenn Sie den Text in der oberen linken Ecke der Anzeige anzeigen möchten, übergeben Sie die Negativen dieser Left Werte Top als X- und Y-Koordinaten von DrawText, in diesem Beispiel –6 und 68.

Die SKRect Struktur definiert mehrere praktische Eigenschaften und Methoden, von denen einige im Re Standard der des PaintSurface Handlers verwendet werden. Die MidX Werte geben MidY die Koordinaten der Mitte des Rechtecks an. (Im i Telefon 7-Beispiel sind diese Werte 338,4107 und –24.) Der folgende Code verwendet diese Werte für die einfachste Berechnung von Koordinaten, um Text auf der Anzeige zu zentrieren:

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);
    ...
}

Die SKImageInfo Infostruktur definiert auch eine Rect Eigenschaft vom TypSKRect, sodass Sie diese auch berechnen und yText wie folgt berechnen xText können:

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

Der PaintSurface Handler endet mit zwei Aufrufen von DrawRoundRect, die beide Argumente SKRecterfordern. Dieser SKRect Wert basiert auf dem SKRect aus der MeasureText Methode abgerufenen Wert, kann aber nicht identisch sein. Zunächst muss es etwas größer sein, damit das abgerundete Rechteck nicht über die Ränder des Texts gezeichnet wird. Zweitens muss es im Raum verschoben werden, damit die Left Werte Top der oberen linken Ecke entsprechen, an der das Rechteck positioniert werden soll. Diese beiden Aufgaben werden durch die Offset definierten Methoden und Inflate Methoden erreicht:SKRect

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);
}

Danach ist der re Standard der der Methode direkt vorwärts. Es erstellt ein weiteres SKPaint Objekt für die Rahmen und ruft zweimal auf DrawRoundRect . Der zweite Aufruf verwendet ein Rechteck, das um weitere 10 Pixel aufgeblasen wird. Der erste Aufruf gibt einen Eckradius von 20 Pixeln an. Die zweite hat einen Eckradius von 30 Pixeln, sodass sie parallel erscheinen:

Dreifacher Screenshot der Seite

Sie können Ihr Smartphone oder Simulator seitwärts drehen, um den Text und die Framegröße zu sehen.

Wenn Sie nur Text auf dem Bildschirm zentrieren müssen, können Sie ihn ungefähr ausführen, ohne den Text zu messen. Legen Sie stattdessen die TextAlign Eigenschaft des SKPaint Enumerationselements SKTextAlign.Centerfest. Die X-Koordinate, die Sie in der DrawText Methode angeben, gibt dann an, wo die horizontale Mitte des Texts positioniert ist. Wenn Sie den Mittelpunkt des Bildschirms an die DrawText Methode übergeben, wird der Text horizontal zentriert und fast vertikal zentriert, da die Basislinie vertikal zentriert ist.

Text kann ähnlich wie jedes andere grafische Objekt behandelt werden. Eine einfache Option besteht darin, die Gliederung der Textzeichen anzuzeigen:

Dreifacher Screenshot der Seite

Dies erfolgt einfach durch Ändern der normalen Style Eigenschaft des SKPaint Objekts von der Standardeinstellung von SKPaintStyle.Fill "in" in SKPaintStyle.Stroke", und durch Angeben einer Strichbreite. Der PaintSurface Handler der Seite "Gliederungstext " zeigt, wie dies geschieht:

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);
}

Ein weiteres gängiges grafisches Objekt ist die Bitmap. Das ist ein großes Thema, das im Abschnitt SkiaSharp Bitmaps ausführlich behandelt wird, aber der nächste Artikel, Bitmap Basics in SkiaSharp, bietet eine kurze Einführung.