Affichage segmenté des bitmaps SkiaSharp
L’objet SkiaSharp SKCanvas
définit une méthode nommée DrawBitmapNinePatch
et deux méthodes nommées DrawBitmapLattice
qui sont très similaires. Ces deux méthodes restituent une bitmap à la taille d’un rectangle de destination, mais au lieu d’étirer uniformément la bitmap, elles affichent des parties de la bitmap dans ses dimensions de pixels et étendent d’autres parties de la bitmap afin qu’elle corresponde au rectangle :
Ces méthodes sont généralement utilisées pour le rendu des bitmaps qui font partie d’objets d’interface utilisateur tels que des boutons. Lors de la conception d’un bouton, vous souhaitez généralement que la taille d’un bouton soit basée sur le contenu du bouton, mais vous souhaitez probablement que la bordure du bouton soit la même largeur, quel que soit le contenu du bouton. C’est une application idéale de DrawBitmapNinePatch
.
DrawBitmapNinePatch
est un cas particulier, DrawBitmapLattice
mais c’est plus facile des deux méthodes à utiliser et à comprendre.
Affichage de neuf correctifs
Conceptuellement, DrawBitmapNinePatch
divise une bitmap en neuf rectangles :
Les rectangles aux quatre coins sont affichés dans leurs tailles de pixels. Comme l’indiquent les flèches, les autres zones situées sur les bords de la bitmap sont étirées horizontalement ou verticalement vers la zone du rectangle de destination. Le rectangle au centre est étiré horizontalement et verticalement.
S’il n’y a pas suffisamment d’espace dans le rectangle de destination pour afficher les quatre angles de leurs dimensions de pixels, ils sont réduits à la taille disponible et rien, mais les quatre angles sont affichés.
Pour diviser une bitmap en ces neuf rectangles, il est uniquement nécessaire de spécifier le rectangle dans le centre. Voici la syntaxe de la DrawBitmapNinePatch
méthode :
canvas.DrawBitmapNinePatch(bitmap, centerRectangle, destRectangle, paint);
Le rectangle central est relatif à la bitmap. Il s’agit d’une SKRectI
valeur (la version entière de SKRect
) et toutes les coordonnées et tailles sont exprimées en unités de pixels. Le rectangle de destination est relatif à l’aire d’affichage. L'argument paint
est obligatoire.
La page Nine Patch Display dans l’exemple utilise d’abord un constructeur statique pour créer une propriété statique publique de type SKBitmap
:
public partial class NinePatchDisplayPage : ContentPage
{
static NinePatchDisplayPage()
{
using (SKCanvas canvas = new SKCanvas(FiveByFiveBitmap))
using (SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Red,
StrokeWidth = 10
})
{
for (int x = 50; x < 500; x += 100)
for (int y = 50; y < 500; y += 100)
{
canvas.DrawCircle(x, y, 40, paint);
}
}
}
public static SKBitmap FiveByFiveBitmap { get; } = new SKBitmap(500, 500);
···
}
Deux autres pages de cet article utilisent cette même bitmap. La bitmap est carrée de 500 pixels et se compose d’un tableau de 25 cercles, de la même taille, chacun occupant une zone carrée de 100 pixels :
Le constructeur d’instance du programme crée un SKCanvasView
PaintSurface
gestionnaire qui utilise DrawBitmapNinePatch
pour afficher l’image bitmap étirée sur toute sa surface d’affichage :
public class NinePatchDisplayPage : ContentPage
{
···
public NinePatchDisplayPage()
{
Title = "Nine-Patch Display";
SKCanvasView canvasView = new SKCanvasView();
canvasView.PaintSurface += OnCanvasViewPaintSurface;
Content = canvasView;
}
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
SKRectI centerRect = new SKRectI(100, 100, 400, 400);
canvas.DrawBitmapNinePatch(FiveByFiveBitmap, centerRect, info.Rect);
}
}
Le centerRect
rectangle englobe le tableau central de 16 cercles. Les cercles dans les coins sont affichés dans leurs dimensions de pixels, et tout le reste est étiré en conséquence :
La page UWP se trouve à 500 pixels de large, et affiche donc les lignes supérieures et inférieures sous la forme d’une série de cercles de même taille. Sinon, tous les cercles qui ne se trouvent pas dans les coins sont étirés pour former des points de suspension.
Pour un affichage étrange d’objets constitués d’une combinaison de cercles et de points de suspension, essayez de définir le rectangle central afin qu’il chevauche les lignes et les colonnes de cercles :
SKRectI centerRect = new SKRectI(150, 150, 350, 350);
Affichage en treillis
Les deux DrawBitmapLattice
méthodes sont similaires à DrawBitmapNinePatch
, mais elles sont généralisées pour un nombre quelconque de divisions horizontales ou verticales. Ces divisions sont définies par des tableaux d’entiers correspondant aux pixels.
La DrawBitmapLattice
méthode avec des paramètres pour ces tableaux d’entiers ne semble pas fonctionner. La DrawBitmapLattice
méthode avec un paramètre de type SKLattice
fonctionne, et c’est celle utilisée dans les exemples présentés ci-dessous.
La SKLattice
structure définit quatre propriétés :
XDivs
, tableau d’entiersYDivs
, tableau d’entiersFlags
, tableau de , type d’énumérationSKLatticeFlags
Bounds
de typeNullable<SKRectI>
pour spécifier un rectangle source facultatif dans la bitmap
Le XDivs
tableau divise la largeur de la bitmap en bandes verticales. La première bande s’étend de pixel 0 à gauche à XDivs[0]
. Cette bande est rendue dans sa largeur de pixels. La deuxième bande s’étend de XDivs[0]
jusqu’à XDivs[1]
, et est étirée. La troisième bande s’étend de XDivs[1]
vers XDivs[2]
et est rendue dans sa largeur de pixels. La dernière bande s’étend du dernier élément du tableau au bord droit de la bitmap. Si le tableau a un nombre pair d’éléments, il est affiché dans sa largeur de pixels. Sinon, c’est étiré. Le nombre total de bandes verticales est un plus que le nombre d’éléments du tableau.
Le YDivs
tableau est similaire. Elle divise la hauteur du tableau en bandes horizontales.
Ensemble, le tableau et YDivs
le XDivs
tableau divisent la bitmap en rectangles. Le nombre de rectangles est égal au produit du nombre de bandes horizontales et du nombre de bandes verticales.
Selon la documentation Skia, le Flags
tableau contient un élément pour chaque rectangle, d’abord la ligne supérieure des rectangles, puis la deuxième ligne, etc. Le Flags
tableau est de type SKLatticeFlags
, énumération avec les membres suivants :
Default
avec la valeur 0Transparent
avec la valeur 1
Toutefois, ces drapeaux ne semblent pas fonctionner comme ils sont censés, et il est préférable de les ignorer. Mais ne définissez pas la Flags
propriété sur null
. Définissez-le sur un tableau de SKLatticeFlags
valeurs suffisamment grand pour englober le nombre total de rectangles.
La page Lattice Nine Patch utilise DrawBitmapLattice
pour imiter DrawBitmapNinePatch
. Il utilise la même bitmap créée dans NinePatchDisplayPage
:
public class LatticeNinePatchPage : ContentPage
{
SKBitmap bitmap = NinePatchDisplayPage.FiveByFiveBitmap;
public LatticeNinePatchPage ()
{
Title = "Lattice Nine-Patch";
SKCanvasView canvasView = new SKCanvasView();
canvasView.PaintSurface += OnCanvasViewPaintSurface;
Content = canvasView;
}
`
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
SKLattice lattice = new SKLattice();
lattice.XDivs = new int[] { 100, 400 };
lattice.YDivs = new int[] { 100, 400 };
lattice.Flags = new SKLatticeFlags[9];
canvas.DrawBitmapLattice(bitmap, lattice, info.Rect);
}
}
Les propriétés et YDivs
les XDivs
propriétés sont définies sur des tableaux de seulement deux entiers, en divisant l’image bitmap en trois bandes horizontalement et verticalement : de pixel 0 à pixel 100 (rendu dans la taille des pixels), de pixel 100 à pixel 400 (étiré) et de pixel 400 à pixel 500 (taille de pixel). Ensemble, XDivs
et YDivs
définissez un total de 9 rectangles, qui correspond à la taille du Flags
tableau. Il suffit de créer le tableau pour créer un tableau de SKLatticeFlags.Default
valeurs.
L’affichage est identique au programme précédent :
La page Affichage de lattice divise la bitmap en 16 rectangles :
public class LatticeDisplayPage : ContentPage
{
SKBitmap bitmap = NinePatchDisplayPage.FiveByFiveBitmap;
public LatticeDisplayPage()
{
Title = "Lattice Display";
SKCanvasView canvasView = new SKCanvasView();
canvasView.PaintSurface += OnCanvasViewPaintSurface;
Content = canvasView;
}
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
SKLattice lattice = new SKLattice();
lattice.XDivs = new int[] { 100, 200, 400 };
lattice.YDivs = new int[] { 100, 300, 400 };
int count = (lattice.XDivs.Length + 1) * (lattice.YDivs.Length + 1);
lattice.Flags = new SKLatticeFlags[count];
canvas.DrawBitmapLattice(bitmap, lattice, info.Rect);
}
}
Les XDivs
tableaux et YDivs
les tableaux sont légèrement différents, ce qui rend l’affichage moins symétrique que les exemples précédents :
Dans les images iOS et Android sur la gauche, seuls les plus petits cercles sont rendus dans leurs tailles de pixels. Tout le reste est étiré.
La page Affichage de lattice généralise la création du Flags
tableau, ce qui vous permet d’expérimenter XDivs
et YDivs
plus facilement. En particulier, vous souhaiterez voir ce qui se passe lorsque vous définissez le premier élément du XDivs
tableau sur YDivs
0.