SkiaTransparência nítida
Como você viu, a SKPaint
classe inclui uma Color
propriedade do tipo SKColor
. SKColor
inclui um canal alfa, para que qualquer coisa que você colorir com um SKColor
valor pode ser parcialmente transparente.
Alguma transparência foi demonstrada no artigo Basic Animation in SkiaSharp . Este artigo se aprofunda um pouco mais na transparência para combinar vários objetos em uma única cena, uma técnica às vezes conhecida como mistura. Técnicas de mistura mais avançadas são discutidas nos artigos da seção SkiaSharp shaders .
Você pode definir o nível de transparência ao criar uma cor pela primeira vez usando o construtor de quatro parâmetros SKColor
:
SKColor (byte red, byte green, byte blue, byte alpha);
Um valor alfa de 0 é totalmente transparente e um valor alfa de 0xFF é totalmente opaco. Os valores entre esses dois extremos criam cores parcialmente transparentes.
Além disso, define um método útil WithAlpha
que cria uma nova cor a partir de uma cor existente, SKColor
mas com o nível alfa especificado:
SKColor halfTransparentBlue = SKColors.Blue.WithAlpha(0x80);
O uso de texto parcialmente transparente é demonstrado na página Código Mais Código no exemplo. Esta página desvanece duas cadeias de caracteres de texto incorporando transparência nos SKColor
valores:
public class CodeMoreCodePage : ContentPage
{
SKCanvasView canvasView;
bool isAnimating;
Stopwatch stopwatch = new Stopwatch();
double transparency;
public CodeMoreCodePage ()
{
Title = "Code More Code";
canvasView = new SKCanvasView();
canvasView.PaintSurface += OnCanvasViewPaintSurface;
Content = canvasView;
}
protected override void OnAppearing()
{
base.OnAppearing();
isAnimating = true;
stopwatch.Start();
Device.StartTimer(TimeSpan.FromMilliseconds(16), OnTimerTick);
}
protected override void OnDisappearing()
{
base.OnDisappearing();
stopwatch.Stop();
isAnimating = false;
}
bool OnTimerTick()
{
const int duration = 5; // seconds
double progress = stopwatch.Elapsed.TotalSeconds % duration / duration;
transparency = 0.5 * (1 + Math.Sin(progress * 2 * Math.PI));
canvasView.InvalidateSurface();
return isAnimating;
}
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
const string TEXT1 = "CODE";
const string TEXT2 = "MORE";
using (SKPaint paint = new SKPaint())
{
// Set text width to fit in width of canvas
paint.TextSize = 100;
float textWidth = paint.MeasureText(TEXT1);
paint.TextSize *= 0.9f * info.Width / textWidth;
// Center first text string
SKRect textBounds = new SKRect();
paint.MeasureText(TEXT1, ref textBounds);
float xText = info.Width / 2 - textBounds.MidX;
float yText = info.Height / 2 - textBounds.MidY;
paint.Color = SKColors.Blue.WithAlpha((byte)(0xFF * (1 - transparency)));
canvas.DrawText(TEXT1, xText, yText, paint);
// Center second text string
textBounds = new SKRect();
paint.MeasureText(TEXT2, ref textBounds);
xText = info.Width / 2 - textBounds.MidX;
yText = info.Height / 2 - textBounds.MidY;
paint.Color = SKColors.Blue.WithAlpha((byte)(0xFF * transparency));
canvas.DrawText(TEXT2, xText, yText, paint);
}
}
}
O transparency
campo é animado para variar de 0 a 1 e voltar novamente em um ritmo senoidal. A primeira cadeia de texto é exibida com um valor alfa calculado subtraindo o transparency
valor de 1:
paint.Color = SKColors.Blue.WithAlpha((byte)(0xFF * (1 - transparency)));
O WithAlpha
método define o componente alfa em uma cor existente, que aqui é SKColors.Blue
. A segunda cadeia de caracteres de texto usa um valor alfa calculado a partir do transparency
próprio valor:
paint.Color = SKColors.Blue.WithAlpha((byte)(0xFF * transparency));
A animação alterna entre as duas palavras, instando o usuário a "codificar mais" (ou talvez solicitando "mais código"):
No artigo anterior sobre Noções básicas de bitmap no SkiaSharp, você viu como exibir bitmaps usando um dos DrawBitmap
métodos do SKCanvas
. Todos os DrawBitmap
métodos incluem um SKPaint
objeto como o último parâmetro. Por padrão, esse parâmetro é definido como null
e você pode ignorá-lo.
Como alternativa, você pode definir a Color
propriedade desse SKPaint
objeto para exibir um bitmap com algum nível de transparência. A definição de um nível de transparência na Color
propriedade de SKPaint
permite que você entre e diminua bitmaps ou dissolva um bitmap em outro.
A transparência de bitmap é demonstrada na página Dissolver bitmap. O arquivo XAML instancia um SKCanvasView
e um Slider
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
x:Class="SkiaSharpFormsDemos.Effects.BitmapDissolvePage"
Title="Bitmap Dissolve">
<StackLayout>
<skia:SKCanvasView x:Name="canvasView"
VerticalOptions="FillAndExpand"
PaintSurface="OnCanvasViewPaintSurface" />
<Slider x:Name="progressSlider"
Margin="10"
ValueChanged="OnSliderValueChanged" />
</StackLayout>
</ContentPage>
O arquivo code-behind carrega dois recursos de bitmap. Esses bitmaps não têm o mesmo tamanho, mas têm a mesma proporção:
public partial class BitmapDissolvePage : ContentPage
{
SKBitmap bitmap1;
SKBitmap bitmap2;
public BitmapDissolvePage()
{
InitializeComponent();
// Load two bitmaps
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream(
"SkiaSharpFormsDemos.Media.SeatedMonkey.jpg"))
{
bitmap1 = SKBitmap.Decode(stream);
}
using (Stream stream = assembly.GetManifestResourceStream(
"SkiaSharpFormsDemos.Media.FacePalm.jpg"))
{
bitmap2 = SKBitmap.Decode(stream);
}
}
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
canvasView.InvalidateSurface();
}
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
// Find rectangle to fit bitmap
float scale = Math.Min((float)info.Width / bitmap1.Width,
(float)info.Height / bitmap1.Height);
SKRect rect = SKRect.Create(scale * bitmap1.Width,
scale * bitmap1.Height);
float x = (info.Width - rect.Width) / 2;
float y = (info.Height - rect.Height) / 2;
rect.Offset(x, y);
// Get progress value from Slider
float progress = (float)progressSlider.Value;
// Display two bitmaps with transparency
using (SKPaint paint = new SKPaint())
{
paint.Color = paint.Color.WithAlpha((byte)(0xFF * (1 - progress)));
canvas.DrawBitmap(bitmap1, rect, paint);
paint.Color = paint.Color.WithAlpha((byte)(0xFF * progress));
canvas.DrawBitmap(bitmap2, rect, paint);
}
}
}
A Color
propriedade do SKPaint
objeto é definida como dois níveis alfa complementares para os dois bitmaps. Ao usar SKPaint
com bitmaps, não importa qual seja o Color
restante do valor. Tudo o que importa é o canal alfa. O código aqui simplesmente chama o WithAlpha
método no valor padrão da Color
propriedade.
Movendo as Slider
dissoluções entre um bitmap e outro:
Nos últimos artigos, você viu como usar o SkiaSharp para desenhar texto, círculos, elipses, retângulos arredondados e bitmaps. A próxima etapa é SkiaSharp Lines and Paths no qual você aprenderá a desenhar linhas conectadas em um caminho gráfico.