### Install SkiaSharp.Extended Core Utilities
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/index.md
Install the core utilities package for SkiaSharp.Extended using the .NET CLI.
```bash
dotnet add package SkiaSharp.Extended
```
--------------------------------
### Quick Start: Create and Interpolate Paths
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/path-interpolation.md
Defines start and end paths (square and star) and creates an SKPathInterpolation object to get a path at a specific transition point (0.5).
```csharp
using SkiaSharp;
using SkiaSharp.Extended;
// Define your start and end paths
var square = SKGeometry.CreateSquarePath(100);
var star = SKGeometry.CreateRegularStarPath(100, 40, 5);
// Create the interpolation
var interpolation = new SKPathInterpolation(square, star);
// Get paths at any point in the transition (0 to 1)
var halfway = interpolation.Interpolate(0.5f);
```
--------------------------------
### Complete Migration Example: Before (SkiaSharp.Extended.Svg)
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/svg-migration.md
A complete C# code example demonstrating the usage of SkiaSharp.Extended.Svg for loading and drawing SVGs within a MAUI application. This serves as the 'before' state for migration.
```csharp
using SkiaSharp;
using SkiaSharp.Extended.Svg;
using SkiaSharp.Views.Maui;
using SkiaSharp.Views.Maui.Controls;
namespace MyApp
{
public partial class MyPage : ContentPage
{
private SKSvg? svg;
private void LoadSvg()
{
svg = new SKSvg();
using var stream = FileSystem.OpenAppPackageFileAsync("image.svg").Result;
svg.Load(stream);
}
private void OnPaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
var canvas = e.Surface.Canvas;
canvas.Clear(SKColors.White);
if (svg?.Picture != null)
{
canvas.DrawPicture(svg.Picture);
}
}
}
}
```
--------------------------------
### Complete Confetti Example
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/confetti.md
A comprehensive example demonstrating how to configure multiple aspects of an SKConfettiSystem, including emitter, colors, shapes, velocity, and lifetime, for a celebratory effect.
```csharp
void CelebrateAchievement()
{
confettiView.Systems.Add(new SKConfettiSystem
{
Emitter = SKConfettiEmitter.Burst(150),
EmitterBounds = SKConfettiEmitterBounds.Center,
Colors = { Colors.Gold, Colors.Orange, Colors.Yellow },
Shapes =
{
new SKConfettiSquareShape(),
new SKConfettiCircleShape()
},
MinimumInitialVelocity = 150,
MaximumInitialVelocity = 350,
Lifetime = 4.0,
FadeOut = true
});
}
```
--------------------------------
### Complete Migration Example: After (Svg.Skia)
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/svg-migration.md
A complete C# code example demonstrating the usage of Svg.Skia for loading and drawing SVGs within a MAUI application. This shows the 'after' state post-migration, highlighting the minimal API changes.
```csharp
using SkiaSharp;
using Svg.Skia; // Changed this line
using SkiaSharp.Views.Maui;
using SkiaSharp.Views.Maui.Controls;
namespace MyApp
{
public partial class MyPage : ContentPage
{
private SKSvg? svg;
private void LoadSvg()
{
svg = new SKSvg();
using var stream = FileSystem.OpenAppPackageFileAsync("image.svg").Result;
svg.Load(stream); // Same API!
}
private void OnPaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
var canvas = e.Surface.Canvas;
canvas.Clear(SKColors.White);
if (svg?.Picture != null)
{
canvas.DrawPicture(svg.Picture); // Same API!
}
}
}
}
```
--------------------------------
### Install SkiaSharp.Extended MAUI Controls
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/index.md
Install the MAUI controls package for SkiaSharp.Extended, which includes the core utilities, using the .NET CLI.
```bash
dotnet add package SkiaSharp.Extended.UI.Maui
```
--------------------------------
### Package Version Conflicts Example
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/svg-migration.md
An example of how to align SkiaSharp-related package versions in a .NET project file to resolve conflicts during migration.
```xml
```
--------------------------------
### Usage Pattern: Loading Indicator
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/path-interpolation.md
Example of morphing between a circle and a square to create a loading animation.
```csharp
// Morph between simple shapes for a loading animation
var circle = new SKPath();
circle.AddCircle(0, 0, 50);
var square = SKGeometry.CreateSquarePath(80);
var loading = new SKPathInterpolation(circle, square);
```
--------------------------------
### Update NuGet Packages
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/svg-migration.md
Remove the old SkiaSharp.Extended.Svg package and install the Svg.Skia package using the .NET CLI.
```bash
# Remove the old package
dotnet remove package SkiaSharp.Extended.Svg
# Add Svg.Skia
dotnet add package Svg.Skia
```
--------------------------------
### API Response with BlurHash
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/blurhash.md
Example of including a pre-computed BlurHash in an API response alongside image URLs and dimensions.
```json
{
"imageUrl": "https://example.com/photo.jpg",
"blurHash": "LjPsbRxG%gx^aJxuM|W=?^X8Mxn$",
"width": 1920,
"height": 1080
}
```
--------------------------------
### Trigger a Confetti Burst
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/confetti.md
Initiate a confetti burst by adding an SKConfettiSystem to the SKConfettiView's Systems collection. This example configures a burst of 100 particles from the center.
```csharp
confettiView.Systems.Add(new SKConfettiSystem
{
Emitter = SKConfettiEmitter.Burst(100),
EmitterBounds = SKConfettiEmitterBounds.Center
});
```
--------------------------------
### Animation Example: MorphingShape Class
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/path-interpolation.md
A class to manage the animation progress of a shape morph. It updates the progress over time and reverses direction at the ends (0 and 1).
```csharp
public class MorphingShape
{
private readonly SKPathInterpolation interpolation;
private float progress = 0f;
private float direction = 1f;
public MorphingShape(SKPath from, SKPath to)
{
interpolation = new SKPathInterpolation(from, to);
}
public void Update(float deltaTime)
{
progress += deltaTime * direction;
if (progress >= 1f || progress <= 0f)
direction *= -1; // Reverse at ends
}
public void Draw(SKCanvas canvas, SKPaint paint)
{
var path = interpolation.Interpolate(progress);
canvas.DrawPath(path, paint);
}
}
```
--------------------------------
### MAUI XAML Usage of BlurHashConverter
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/blurhash.md
Example of how to use the BlurHashConverter in MAUI XAML to bind an image source to a BlurHash string.
```xml
```
--------------------------------
### Usage Pattern: Icon Transitions
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/path-interpolation.md
Demonstrates creating a smooth transition between two icon paths, such as play and pause, based on an animation progress value.
```csharp
// Smooth transition between UI states (play → pause)
var playIcon = CreatePlayIconPath();
var pauseIcon = CreatePauseIconPath();
var transition = new SKPathInterpolation(playIcon, pauseIcon);
var currentIcon = transition.Interpolate(animationProgress);
```
--------------------------------
### Customization: Pre-calculating for Performance
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/path-interpolation.md
Shows how to call Prepare() on an SKPathInterpolation object to pre-calculate point mappings for faster subsequent Interpolate() calls.
```csharp
var interpolation = new SKPathInterpolation(from, to);
interpolation.Prepare(); // Pre-calculate point mappings
// Now Interpolate() calls are faster
for (float t = 0; t <= 1; t += 0.1f)
{
var path = interpolation.Interpolate(t);
}
```
--------------------------------
### Compare Images Using File Paths
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Demonstrates comparing two images directly from their file paths using the SKPixelComparer.Compare method.
```csharp
Compare("a.png", "b.png")
```
--------------------------------
### Offsetting a Path to a Specific Center
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/geometry.md
Demonstrates how to position a path created at the origin to a desired center point using the Offset method.
```csharp
var path = SKGeometry.CreateRegularStarPath(50, 20, 5);
path.Offset(centerX, centerY);
canvas.DrawPath(path, paint);
```
--------------------------------
### Include Raw Assets in .NET MAUI Project
Source: https://github.com/mono/skiasharp.extended/blob/main/samples/SkiaSharpDemo/Resources/Raw/AboutAssets.txt
This XML snippet shows how to configure your .csproj file to include all files in the Resources\Raw directory and its subdirectories as MauiAssets. The LogicalName ensures the file is deployed with its original path and name.
```xml
```
--------------------------------
### Configure Pixel Comparison Options
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Sets up SKPixelComparerOptions to customize comparison behavior, including per-channel tolerance and alpha channel comparison. Per-channel tolerance is enabled by default.
```csharp
var options = new SKPixelComparerOptions
{
TolerancePerChannel = true, // Check each channel independently (default: true)
CompareAlpha = true // Include alpha channel in comparison (default: false)
};
var result = SKPixelComparer.Compare(expected, actual, options);
```
--------------------------------
### Tolerance-Based Comparison with Options
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Applies tolerance-based pixel comparison while also utilizing custom SKPixelComparerOptions for advanced control.
```csharp
// Tolerance-based with options
var result = SKPixelComparer.Compare(expected, actual, tolerance: 10, options);
```
--------------------------------
### Load Lottie Animations from Different Sources
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/lottie.md
Load Lottie animations programmatically from app resources, a URL, or a stream by creating an appropriate SKLottieImageSource object.
```csharp
// From app resources (recommended)
lottieView.Source = new SKFileLottieImageSource { File = "animation.json" };
// From a URL
lottieView.Source = new SKUriLottieImageSource { Uri = new Uri("https://...") };
// From a stream
lottieView.Source = new SKStreamLottieImageSource { Stream = myStream };
```
--------------------------------
### Compare SKBitmaps
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Illustrates comparing two SKBitmap objects using the SKPixelComparer.Compare method.
```csharp
Compare(bitmapA, bitmapB)
```
--------------------------------
### Compare SKImages
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Shows how to compare two SKImage objects using the SKPixelComparer.Compare method.
```csharp
Compare(imageA, imageB)
```
--------------------------------
### Compare Two Images
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Compares two image files and returns a detailed result object containing various difference metrics. Ensure the image files exist and are accessible.
```csharp
using SkiaSharp;
using SkiaSharp.Extended;
var result = SKPixelComparer.Compare("expected.png", "actual.png");
Console.WriteLine($"Total pixels: {result.TotalPixels}");
Console.WriteLine($"Error pixels: {result.ErrorPixelCount}");
Console.WriteLine($"Error percentage: {result.ErrorPixelPercentage:P2}");
Console.WriteLine($"Absolute error: {result.AbsoluteError}");
Console.WriteLine($"RMSE: {result.RootMeanSquaredError:F4}");
Console.WriteLine($"PSNR: {result.PeakSignalToNoiseRatio:F2} dB");
```
--------------------------------
### Compare SKPixmaps
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Demonstrates comparing two SKPixmap objects using the SKPixelComparer.Compare method.
```csharp
Compare(pixmapA, pixmapB)
```
--------------------------------
### Create a Regular Star Path
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/geometry.md
Generates an SKPath for a regular star. Specify outer and inner radii, and the number of points.
```csharp
using SkiaSharp;
using SkiaSharp.Extended;
// Create a 5-pointed star
var starPath = SKGeometry.CreateRegularStarPath(
outerRadius: 100,
innerRadius: 40,
points: 5);
// Draw it on a canvas
canvas.DrawPath(starPath, paint);
```
--------------------------------
### Create a Star Path with Different Points
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/geometry.md
Generates an SKPath for a regular star. Use different inner and outer radii to control the star's appearance.
```csharp
// Classic 5-pointed star
var star5 = SKGeometry.CreateRegularStarPath(
outerRadius: 50,
innerRadius: 20,
points: 5);
// Star of David (6-pointed)
var star6 = SKGeometry.CreateRegularStarPath(
outerRadius: 50,
innerRadius: 30,
points: 6);
```
--------------------------------
### Loading SVG from Stream
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/svg-migration.md
Demonstrates loading an SVG from a stream using the SKSvg class. The API for loading SVGs remains the same between SkiaSharp.Extended.Svg and Svg.Skia.
```csharp
// Both old and new code look the same!
var svg = new SKSvg();
using (var stream = GetType().Assembly.GetManifestResourceStream(resourceId))
{
if (stream != null)
{
svg.Load(stream);
}
}
```
--------------------------------
### Handle Lottie Animation Lifecycle Events
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/lottie.md
Subscribe to animation lifecycle events like 'AnimationLoaded', 'AnimationFailed', and 'AnimationCompleted' to react to the animation's state changes. Note that 'AnimationCompleted' only fires for finite animations.
```csharp
lottieView.AnimationLoaded += (s, e) =>
{
Console.WriteLine($"Loaded! Duration: {lottieView.Duration}");
};
lottieView.AnimationFailed += (s, e) =>
{
Console.WriteLine($"Failed to load animation");
};
lottieView.AnimationCompleted += (s, e) =>
{
Console.WriteLine("Animation finished playing");
};
```
--------------------------------
### Accessing Deployed Raw Assets in .NET MAUI
Source: https://github.com/mono/skiasharp.extended/blob/main/samples/SkiaSharpDemo/Resources/Raw/AboutAssets.txt
This C# code demonstrates how to load and read the content of a raw asset file that has been deployed with your .NET MAUI application. Ensure the asset is correctly included using the MauiAsset build action.
```csharp
async Task LoadMauiAsset()
{
using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
using var reader = new StreamReader(stream);
var contents = reader.ReadToEnd();
}
```
--------------------------------
### Update Using Statements
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/svg-migration.md
Replace the old SkiaSharp.Extended.Svg namespace with the new Svg.Skia namespace in your C# code.
```csharp
// OLD - Remove this
using SkiaSharp.Extended.Svg;
// NEW - Add this
using Svg.Skia;
```
--------------------------------
### Compare Images with Tolerance for Minor Differences
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Compares images while allowing for minor differences using a per-pixel tolerance or an RMSE threshold. Useful for tests with potential platform-specific variations.
```csharp
[Fact]
public void UI_MatchesBaseline_WithTolerance()
{
using var actual = CaptureScreenshot();
using var expected = SKImage.FromEncodedData("baselines/screen.png");
// Option 1: Use per-pixel tolerance to ignore minor differences
var result = SKPixelComparer.Compare(expected, actual, tolerance: 10);
Assert.Equal(0, result.ErrorPixelCount);
// Option 2: Use RMSE threshold (like .NET MAUI VisualTestUtils)
var result2 = SKPixelComparer.Compare(expected, actual);
Assert.True(result2.NormalizedRootMeanSquaredError < 0.005,
$"NRMSE too high: {result2.NormalizedRootMeanSquaredError:F4}");
}
```
--------------------------------
### Compare Pixels with Per-Channel Tolerance
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Compares two images and counts pixels where any channel's difference exceeds the specified tolerance. Channels within tolerance are ignored for all metrics.
```csharp
// Ignore channels where the individual difference is 10 or less
var result = SKPixelComparer.Compare(expected, actual, tolerance: 10);
Console.WriteLine($"Pixels exceeding tolerance: {result.ErrorPixelCount}");
```
--------------------------------
### Control Lottie Animation Playback Programmatically
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/lottie.md
Manage the animation's playback state and progress using C# code. Set 'IsAnimationEnabled' to false to pause and true to resume. You can also jump to a specific 'Progress' point or check 'IsComplete'.
```csharp
// Pause the animation
lottieView.IsAnimationEnabled = false;
// Resume
lottieView.IsAnimationEnabled = true;
// Jump to specific progress
lottieView.Progress = TimeSpan.FromSeconds(1.5);
// Check if complete
if (lottieView.IsComplete)
{
// Animation finished
}
```
--------------------------------
### Compare Images for Visual Regression Testing
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Compares two images and asserts that there are no differing pixels. Suitable for use in test suites to catch unintended rendering changes.
```csharp
[Fact]
public void ChartRendering_MatchesBaseline()
{
using var actual = RenderChart(testData);
using var expected = SKImage.FromEncodedData("baselines/chart.png");
var result = SKPixelComparer.Compare(expected, actual);
Assert.Equal(0, result.ErrorPixelCount);
}
```
--------------------------------
### Mask-Based Comparison with Options
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Performs mask-based pixel comparison using SKPixelComparer.Compare, incorporating custom SKPixelComparerOptions.
```csharp
// Mask-based with options
var result = SKPixelComparer.Compare(expected, actual, mask, options);
```
--------------------------------
### Create a Regular Polygon Path
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/geometry.md
Generates an SKPath for a regular polygon. Specify the radius and the number of points (sides).
```csharp
// Pentagon (5 sides)
var pentagon = SKGeometry.CreateRegularPolygonPath(radius: 50, points: 5);
// Hexagon (6 sides)
var hexagon = SKGeometry.CreateRegularPolygonPath(radius: 50, points: 6);
// Octagon (8 sides)
var octagon = SKGeometry.CreateRegularPolygonPath(radius: 50, points: 8);
```
--------------------------------
### Encode Image to BlurHash
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/blurhash.md
Encodes a SKBitmap into a BlurHash string. Use 4x3 components as a good default for most images.
```csharp
using SkiaSharp;
using SkiaSharp.Extended;
using var bitmap = SKBitmap.Decode("photo.jpg");
string hash = SKBlurHash.Serialize(bitmap, 4, 3);
// Returns something like: "LjPsbRxG%gx^aJxuM|W=?^X8Mxn$"
```
--------------------------------
### Decode BlurHash to Placeholder Bitmap
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/blurhash.md
Decodes a BlurHash string into a SKBitmap. A placeholder size of 32x32 is usually sufficient.
```csharp
var placeholder = SKBlurHash.DeserializeBitmap(hash, 32, 32);
// Use this blurred bitmap while the real image loads
```
--------------------------------
### Confetti Emitter Patterns
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/confetti.md
Configure how particles are emitted using SKConfettiEmitter. Options include instant bursts, continuous streams, or infinite emissions with specified rates.
```csharp
// Instant explosion - all particles at once
Emitter = SKConfettiEmitter.Burst(100);
// Continuous stream - 50 particles per second, for 3 seconds
Emitter = SKConfettiEmitter.Stream(50, 3);
// Infinite - 30 particles per second, forever
Emitter = SKConfettiEmitter.Infinite(30);
```
--------------------------------
### Draw Basic Shapes Using Canvas Extensions
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/geometry.md
Convenient methods to draw basic shapes like squares, triangles, polygons, and stars directly onto a canvas using SkiaSharp.Extended.
```csharp
using SkiaSharp;
using SkiaSharp.Extended;
// Square
canvas.DrawSquare(cx: 50, cy: 50, side: 40, paint);
// Triangle (by radius)
canvas.DrawTriangle(cx: 150, cy: 50, radius: 30, paint);
// Regular polygon
canvas.DrawRegularPolygon(cx: 250, cy: 50, radius: 30, points: 6, paint);
// Star
canvas.DrawStar(cx: 350, cy: 50, outerRadius: 30, innerRadius: 12, points: 5, paint);
```
--------------------------------
### Generate Difference Image
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Generates a full-color image visualizing per-channel differences between two images. Useful for understanding the magnitude and distribution of differences.
```csharp
using var diff = SKPixelComparer.GenerateDifferenceImage("expected.png", "actual.png");
// Each pixel's R, G, B values represent the absolute channel differences
using var data = diff.Encode(SKEncodedImageFormat.Png, 100);
File.WriteAllBytes("diff-image.png", data.ToArray());
```
--------------------------------
### Compare Images with Tolerance Mask
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Compares two images using an optional tolerance mask to ignore minor differences. The mask must have the same dimensions as the images being compared.
```csharp
using var expected = SKImage.FromEncodedData("expected.png");
using var actual = SKImage.FromEncodedData("actual.png");
using var mask = SKImage.FromEncodedData("tolerance-mask.png");
var result = SKPixelComparer.Compare(expected, actual, mask);
```
--------------------------------
### Customization: Max Segment Length
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/path-interpolation.md
Demonstrates creating SKPathInterpolation with different maxSegmentLength values to control curve smoothness and performance.
```csharp
// Default (5 units) - good balance of quality and performance
var interpolation = new SKPathInterpolation(from, to);
// Smoother curves (smaller segments)
var smooth = new SKPathInterpolation(from, to, maxSegmentLength: 2f);
// Faster performance (larger segments)
var fast = new SKPathInterpolation(from, to, maxSegmentLength: 10f);
```
--------------------------------
### SPA Redirect Logic
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/404.html
This JavaScript code redirects users directly navigating to a Blazor sample sub-page. It encodes the path and query string to restore the correct route in the Blazor router.
```javascript
(function () {
var l = window.location;
var pathParts = l.pathname.split('/');
var sampleIdx = pathParts.indexOf('sample');
if (sampleIdx !== -1 && sampleIdx < pathParts.length - 1 && pathParts[sampleIdx + 1] !== '') {
var basePath = pathParts.slice(0, sampleIdx + 1).join('/');
var remaining = pathParts.slice(sampleIdx + 1).join('/').replace(/&/g, '~and~');
l.replace(
l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
basePath + '/?/' + remaining +
(l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') +
l.hash
);
}
})();
```
--------------------------------
### Decode BlurHash with Custom Punch
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/blurhash.md
Decodes a BlurHash string into a SKBitmap with adjustable contrast. A punch value greater than 1.0 increases vibrancy.
```csharp
// Default punch (1.0)
var normal = SKBlurHash.DeserializeBitmap(hash, 32, 32);
// More vibrant (1.5)
var vibrant = SKBlurHash.DeserializeBitmap(hash, 32, 32, punch: 1.5f);
```
--------------------------------
### Compare Pixels with Summed Tolerance Mode
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Compares two images using summed tolerance mode, where the total difference across all RGB channels must exceed the tolerance to count as an error. This mode is configured via SKPixelComparerOptions.
```csharp
// Summed: ignore pixels where the total RGB difference is 15 or less
var options = new SKPixelComparerOptions { TolerancePerChannel = false };
var result = SKPixelComparer.Compare(expected, actual, tolerance: 15, options);
```
--------------------------------
### Confetti Physics Properties
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/confetti.md
Configure the physical properties of confetti particles, including their size and mass, which affects how they fall and respond to gravity.
```csharp
Physics =
{
new SKConfettiPhysics { Size = 10, Mass = 0.5 }, // Small, light
new SKConfettiPhysics { Size = 20, Mass = 1.0 }, // Medium
new SKConfettiPhysics { Size = 30, Mass = 2.0 } // Large, heavy (falls faster)
}
```
--------------------------------
### Blazor URL Parameter Handling
Source: https://github.com/mono/skiasharp.extended/blob/main/samples/SkiaSharpDemo.Blazor/wwwroot/index.html
This JavaScript code snippet modifies the browser's history to correctly handle URL parameters, specifically replacing '~and~' with '&' for proper parsing.
```javascript
(function (l) { if (l.search[1] === '/') { var decoded = l.search.slice(1).split('&').map(function (s) { return s.replace(/~and~/g, '&'); }).join('?'); window.history.replaceState(null, null, l.pathname.slice(0, -1) + decoded + l.hash); } }(window.location));
```
--------------------------------
### Register SkiaSharp Handler in MAUI
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/index.md
Register the SkiaSharp handler in your .NET MAUI application's MauiProgram.cs file to enable SkiaSharp functionality.
```csharp
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp()
.UseSkiaSharp(); // Add this line
return builder.Build();
}
```
--------------------------------
### Calculate Geometric Properties
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/geometry.md
Utility methods for geometric calculations, including finding a point on a circle and calculating polygon area.
```csharp
// Get a point on a circle
var point = SKGeometry.CirclePoint(radius: 100, radians: Math.PI / 4);
// Calculate polygon area
var points = new[] { new SKPoint(0, 0), new SKPoint(100, 0), new SKPoint(50, 100) };
var area = SKGeometry.Area(points);
```
--------------------------------
### Compare Pixels Including Alpha Channel
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Compares images including the alpha channel by setting CompareAlpha to true in SKPixelComparerOptions. This affects error calculations and normalization of metrics.
```csharp
var options = new SKPixelComparerOptions { CompareAlpha = true };
var result = SKPixelComparer.Compare(expected, actual, options);
Console.WriteLine($"Channels compared: {result.ChannelCount}"); // 4
Console.WriteLine($"MAE: {result.MeanAbsoluteError}"); // Normalized over RGBA
```
--------------------------------
### Control Path Direction
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/geometry.md
Set the winding order (Clockwise or CounterClockwise) for generated paths. This is useful for path operations.
```csharp
// Clockwise (default)
var cwPath = SKGeometry.CreateSquarePath(50, SKPathDirection.Clockwise);
// Counter-clockwise
var ccwPath = SKGeometry.CreateSquarePath(50, SKPathDirection.CounterClockwise);
```
--------------------------------
### GitHub Pages SPA Redirect Script
Source: https://github.com/mono/skiasharp.extended/blob/main/samples/SkiaSharpDemo.Blazor/wwwroot/404.html
This JavaScript code converts the URL path into a query string for index.html to enable SPA routing on GitHub Pages. It calculates the number of segments in the base href and reconstructs the URL with the path as a query parameter.
```javascript
var segmentCount = 2;
var l = window.location;
l.replace( l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') + l.pathname.split('/').slice(0, 1 + segmentCount).join('/') + '/?/' + l.pathname.slice(1).split('/').slice(segmentCount).join('/').replace(/&/g, '~and~') + (l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') + l.hash );
```
--------------------------------
### Generate Difference Mask
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Generates a black-and-white mask image highlighting differences between two images. White pixels indicate differences, and black pixels indicate matching areas. The generated mask is saved as 'diff-mask.png'.
```csharp
using var mask = SKPixelComparer.GenerateDifferenceMask("expected.png", "actual.png");
// Encode and save the mask
using var data = mask.Encode(SKEncodedImageFormat.Png, 100);
File.WriteAllBytes("diff-mask.png", data.ToArray());
```
--------------------------------
### Add SKLottieView to XAML
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/lottie.md
Include the SKLottieView in your XAML markup to display an animation. Set the 'Source' property to the animation JSON file and optionally configure 'RepeatCount', 'WidthRequest', and 'HeightRequest'.
```xml
```
--------------------------------
### MAUI Value Converter for BlurHash
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/blurhash.md
A custom IValueConverter for MAUI to decode BlurHash strings directly in XAML bindings. It allows setting the desired width and height for the placeholder.
```csharp
using System.Globalization;
using SkiaSharp;
using SkiaSharp.Extended;
using SkiaSharp.Views.Maui.Controls;
public class BlurHashConverter : IValueConverter
{
public int Width { get; set; } = 32;
public int Height { get; set; } = 32;
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is string hash && !string.IsNullOrEmpty(hash))
{
var bitmap = SKBlurHash.DeserializeBitmap(hash, Width, Height);
return (SKBitmapImageSource)bitmap;
}
return null;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
=> throw new NotImplementedException();
}
```
--------------------------------
### Generate Difference Mask on Comparison Failure
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Generates and saves a difference mask when an image comparison fails. This mask aids in diagnosing the specific changes that occurred.
```csharp
if (result.ErrorPixelCount > 0)
{
using var diffMask = SKPixelComparer.GenerateDifferenceMask(expected, actual);
using var encoded = diffMask.Encode(SKEncodedImageFormat.Png, 100);
File.WriteAllBytes("test-output/diff-mask.png", encoded.ToArray());
}
```
--------------------------------
### Confetti Particle Lifecycle
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/confetti.md
Manage the lifespan of confetti particles and enable fading effects before they disappear. The `IsComplete` property indicates when all particles have finished their lifecycle.
```csharp
var system = new SKConfettiSystem
{
Lifetime = 3.0, // Particles live for 3 seconds
FadeOut = true // Gradually fade before disappearing
};
// Handle completion
confettiView.IsComplete // true when all particles are gone
```
--------------------------------
### Configure Lottie Animation Repeat Modes
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/lottie.md
Control how the Lottie animation repeats using the 'RepeatCount' and 'RepeatMode' properties in XAML. 'RepeatCount' defines the number of plays (0 for once, -1 for infinite), and 'RepeatMode' can be 'Restart' or 'Reverse' for ping-pong effect.
```xml
```
--------------------------------
### Confetti Motion Control - Velocity and Spin
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/confetti.md
Control the initial speed, speed limit, and rotation of confetti particles. This allows for dynamic launch effects and spin animations.
```csharp
var system = new SKConfettiSystem
{
// Initial launch speed range
MinimumInitialVelocity = 100,
MaximumInitialVelocity = 300,
// Speed limit
MaximumVelocity = 500,
// Spin rate
MinimumRotationVelocity = -90,
MaximumRotationVelocity = 90
};
```
--------------------------------
### Add SKConfettiView to XAML
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/confetti.md
Include the SKConfettiView control in your XAML markup to display confetti effects. Ensure the SkiaSharp.Extended.UI.Maui namespace is correctly imported.
```xml
```
--------------------------------
### Draw Shapes Directly on Canvas
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/geometry.md
Utilizes canvas extension methods to draw various shapes without explicitly creating SKPath objects. Requires SkiaSharp.Extended.
```csharp
using SkiaSharp;
using SkiaSharp.Extended;
// Draw shapes directly on a canvas
canvas.DrawStar(100, 100, outerRadius: 50, innerRadius: 20, points: 5, paint);
canvas.DrawRegularPolygon(200, 100, radius: 40, points: 6, paint);
canvas.DrawTriangle(300, 100, radius: 40, paint);
```
--------------------------------
### Generate Mask with Summed Tolerance Mode
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/pixel-comparer.md
Generates a difference mask using summed tolerance mode, where the sum of channel differences is compared against the tolerance. Pixels are either fully counted as errors or fully excluded.
```csharp
// Mask with sum-based semantics
var options = new SKPixelComparerOptions { TolerancePerChannel = false };
var result = SKPixelComparer.Compare(expected, actual, mask, options);
```
--------------------------------
### Drawing SVG on Canvas
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/svg-migration.md
Illustrates how to draw an SVG picture onto a SkiaSharp canvas. This code snippet shows the calculation for scaling the SVG to fit the canvas dimensions.
```csharp
// Drawing the SVG picture
if (svg?.Picture != null)
{
canvas.Clear(SKColors.White);
// Calculate scaling to fit canvas
var canvasMin = Math.Min(width, height);
var svgMax = Math.Max(svg.Picture.CullRect.Width, svg.Picture.CullRect.Height);
var scale = canvasMin / svgMax;
var matrix = SKMatrix.CreateScale(scale, scale);
canvas.DrawPicture(svg.Picture, matrix);
}
```
--------------------------------
### Custom Confetti Shapes
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/confetti.md
Define the shapes of confetti particles using built-in shapes like circles and squares, or create custom shapes using paths or a custom SKConfettiShape implementation.
```csharp
Shapes =
{
new SKConfettiCircleShape(),
new SKConfettiSquareShape(),
new SKConfettiOvalShape { HeightRatio = 0.5 },
new SKConfettiRectShape { HeightRatio = 0.3 }
}
```
```csharp
Shapes = { new SKConfettiPathShape(SKGeometry.CreateRegularStarPath(20, 10, 5)) }
```
```csharp
public class HeartShape : SKConfettiShape
{
protected override void OnDraw(SKCanvas canvas, SKPaint paint, float size)
{
using var path = new SKPath();
// Draw heart shape...
canvas.DrawPath(path, paint);
}
}
```
--------------------------------
### Customize SKLottieView Control Template
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/lottie.md
Override the control template of SKLottieView to customize the rendering surface. You can use either SKCanvasView (software rendering) or SKGLView (GPU-accelerated rendering) by naming the drawing surface PART_DrawingSurface.
```xml
```
--------------------------------
### Confetti Motion Control - Launch Direction
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/confetti.md
Specify the angle range for particle emission to control the direction and spread of the confetti. This is useful for creating focused or dispersed effects.
```csharp
// Full 360° explosion (default)
StartAngle = 0;
EndAngle = 360;
// Upward cone from top emitter
EmitterBounds = SKConfettiEmitterBounds.Top;
StartAngle = 45;
EndAngle = 135;
```
--------------------------------
### Custom Confetti Colors
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/confetti.md
Customize the color palette for confetti particles by providing a list of SKColor objects. This can be done in C# code or directly in XAML.
```csharp
// Custom color palette
var system = new SKConfettiSystem
{
Colors = { Colors.Red, Colors.Gold, Colors.Blue, Colors.Green }
};
```
```xml
```
--------------------------------
### Confetti Emitter Bounds
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/confetti.md
Define the area from which particles are emitted using SKConfettiEmitterBounds. This controls the origin of the confetti, such as the center, top, or a specific point.
```csharp
// From the center of the view
EmitterBounds = SKConfettiEmitterBounds.Center;
// From the top edge (falling down)
EmitterBounds = SKConfettiEmitterBounds.Top;
// From a specific point
EmitterBounds = SKConfettiEmitterBounds.Point(100, 200);
// From both sides
confettiView.Systems.Add(new SKConfettiSystem { EmitterBounds = SKConfettiEmitterBounds.Left });
confettiView.Systems.Add(new SKConfettiSystem { EmitterBounds = SKConfettiEmitterBounds.Right });
```
--------------------------------
### Confetti Motion Control - Gravity
Source: https://github.com/mono/skiasharp.extended/blob/main/docs/docs/confetti.md
Adjust the gravity vector to simulate different environmental effects, such as standard downward gravity, upward drift, or wind effects.
```csharp
// Standard gravity (particles fall down)
Gravity = new Point(0, 100);
// Upward drift
Gravity = new Point(0, -50);
// Diagonal wind effect
Gravity = new Point(50, 100);
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.