Udostępnij za pośrednictwem


Integrowanie tekstu i grafiki

Zobacz, jak określić rozmiar renderowanego ciągu tekstowego w celu zintegrowania tekstu z grafiką SkiaSharp

W tym artykule pokazano, jak mierzyć tekst, skalować tekst do określonego rozmiaru i integrować tekst z innymi grafikami:

Tekst otoczony prostokątami

Ten obraz zawiera również zaokrąglony prostokąt. Klasa SkiaSharp Canvas zawiera DrawRect metody narysowania prostokąta i DrawRoundRect metod rysowania prostokąta z zaokrąglonymi rogami. Metody te umożliwiają zdefiniowanie prostokąta SKRect jako wartości lub w inny sposób.

Strona Tekst ramkowy wyśrodkuje krótki ciąg tekstowy na stronie i otacza ją ramką składającą się z pary zaokrąglonych prostokątów. Klasa FramedTextPage pokazuje, jak to zrobić.

W usłudze SkiaSharp używasz SKPaint klasy do ustawiania atrybutów tekstu i czcionki, ale można jej również użyć do uzyskania renderowanego rozmiaru tekstu. Początek następującego PaintSurface programu obsługi zdarzeń wywołuje dwie różne MeasureText metody. Pierwsze MeasureText wywołanie ma prosty string argument i zwraca szerokość pikseli tekstu na podstawie bieżących atrybutów czcionki. Następnie program oblicza nową TextSize właściwość SKPaint obiektu na podstawie tej renderowanej szerokości, bieżącej TextSize właściwości i szerokości obszaru wyświetlania. To obliczenie ma zostać ustawione TextSize tak, aby ciąg tekstowy był renderowany na poziomie 90% szerokości ekranu:

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

Drugie MeasureText wywołanie ma SKRect argument, więc uzyskuje zarówno szerokość, jak i wysokość renderowanego tekstu. Właściwość Height tej SKRect wartości zależy od obecności wielkie litery, rosnąco i malejąco w ciągu tekstowym. Różne Height wartości są zgłaszane dla ciągów tekstowych "mama", "cat" i "dog", na przykład.

Właściwości Left i TopSKRect struktury wskazują współrzędne lewego górnego rogu renderowanego tekstu, jeśli tekst jest wyświetlany przez DrawText wywołanie pozycji X i Y 0. Na przykład gdy ten program jest uruchomiony w symulatorze i Telefon 7, TextSize jest przypisana wartość 90,6254 w wyniku obliczenia po pierwszym wywołaniu metody MeasureText. Wartość SKRect uzyskana z drugiego wywołania metody MeasureText ma następujące wartości właściwości:

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

Należy pamiętać, że współrzędne X i Y przekazywane do DrawText metody określają lewą stronę tekstu w punkcie odniesienia. Wartość Top wskazuje, że tekst rozszerza 68 pikseli powyżej tego punktu odniesienia i (odjęcie 68 z 88) 20 pikseli poniżej punktu odniesienia. Wartość Left 6 wskazuje, że tekst zaczyna się od sześciu pikseli po prawej stronie wartości X w wywołaniu DrawText . Umożliwia to normalne odstępy między znakami. Jeśli chcesz wyświetlić tekst w lewym górnym rogu ekranu, przekaż wartości ujemne DrawTexttych Left wartości jako Top współrzędne X i Y w tym przykładzie –6 i 68.

Struktura SKRect definiuje kilka przydatnych właściwości i metod, z których niektóre są używane w pozostałej części PaintSurface procedury obsługi. Wartości MidX i MidY wskazują współrzędne środka prostokąta. (W przykładzie i Telefon 7 te wartości to 338,4107 i –24). Poniższy kod używa tych wartości do najłatwiejszego obliczenia współrzędnych w celu wyśrodkowania tekstu na ekranie:

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

Struktura SKImageInfo informacji definiuje Rect również właściwość typu SKRect, aby można było również obliczyć xText i yText w następujący sposób:

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

Procedura obsługi kończy się dwoma PaintSurface wywołaniami metody DrawRoundRect, z których oba wymagają argumentów SKRect. Ta SKRect wartość jest oparta na wartości uzyskanej SKRectMeasureText z metody, ale nie może być taka sama. Po pierwsze, musi być nieco większy, aby zaokrąglony prostokąt nie rysował się na krawędziach tekstu. Po drugie, musi być przesunięty w przestrzeń, aby Left wartości i Top odpowiadały lewemu górnemu rogu, w którym prostokąt ma być umieszczony. Te dwa zadania są wykonywane za pomocą Offset metod i Inflate zdefiniowanych przez SKRectprogram :

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

Następnie pozostała część metody jest prosta. Tworzy kolejny SKPaint obiekt dla obramowań i wywołuje DrawRoundRect dwa razy. Drugie wywołanie używa prostokąta zawyżonego przez kolejne 10 pikseli. Pierwsze wywołanie określa promień rogu 20 pikseli. Drugi ma promień rogu wynoszący 30 pikseli, więc wydają się być równoległe:

Potrójny zrzut ekranu przedstawiający stronę Tekst ramkowy

Możesz obrócić telefon lub symulator w bok, aby zobaczyć rozmiar tekstu i ramki.

Jeśli potrzebujesz tylko wyśrodkować jakiś tekst na ekranie, możesz to zrobić w przybliżeniu bez mierzenia tekstu. Zamiast tego ustaw TextAlign właściwość elementu SKPaint członkowskiego wyliczenia SKTextAlign.Center. Współrzędna X określona w DrawText metodzie wskazuje, gdzie znajduje się poziomy środek tekstu. Jeśli przejdziesz punkt środkowy ekranu do DrawText metody, tekst zostanie wyśrodkowany w poziomie i prawie wyśrodkowany w pionie, ponieważ punkt odniesienia zostanie wyśrodkowany w pionie.

Tekst może być traktowany podobnie jak każdy inny obiekt graficzny. Jedną z prostych opcji jest wyświetlenie konturu znaków tekstowych:

Zrzut ekranu przedstawiający stronę Tekst konturowy

Jest to realizowane po prostu przez zmianę właściwości normalnej StyleSKPaint obiektu z jego domyślnego SKPaintStyle.Fill ustawienia na SKPaintStyle.Stroke, i przez określenie szerokości pociągnięcia. Procedura PaintSurface obsługi strony Tekst konturowy pokazuje, jak to zrobić:

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

Innym typowym obiektem graficznym jest mapa bitowa. Jest to obszerny temat szczegółowo opisany w sekcji Mapy bitowe SkiaSharp, ale następny artykuł Podstawy mapy bitowej w SkiaSharp zawiera krótkie wprowadzenie.