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:
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
= 6Top
= –68Width
= 664.8214Height
= 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 SKRect
erfordern. 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:
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.Center
fest. 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:
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.