一、SkiaSharp 简介
SkiaSharp 是一个强大的跨平台 2D 图形库,它基于 Google 的 Skia 图形引擎,为 .NET 开发者提供了丰富的图形处理和绘制功能。借助 SkiaSharp,开发者可以在 Windows、macOS、Linux 等多种操作系统以及桌面、移动设备上创建精美的图形应用。
二、SkiaSharp 主要功能及示例代码
(一)基本图形绘制
1. 点和线
SkiaSharp 允许我们绘制单个点或一系列连续的点,同时还能绘制直线、折线等。我们可以设置线的宽度、颜色、样式(如实线、虚线)等属性。
using SkiaSharp;
// 创建一个新的 SKSurface 对象
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
// 清除画布
canvas.Clear(SKColors.White);
// 创建画笔
SKPaint paint = new SKPaint
{
Color = SKColors.Black,
StrokeWidth = 5,
Style = SKPaintStyle.Stroke
};
// 绘制点
canvas.DrawPoint(100, 100, paint);
// 绘制直线
canvas.DrawLine(200, 100, 300, 200, paint);
// 设置线样式为虚线
paint.PathEffect = SKPathEffect.CreateDash(new float[] { 10, 5 }, 0);
canvas.DrawLine(400, 100, 500, 200, paint);
// 保存图像
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("points_and_lines.png"))
{
data.SaveTo(stream);
}
}
2. 矩形
可以绘制普通矩形、圆角矩形,并且能对矩形进行填充或仅绘制边框。
using SkiaSharp;
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
canvas.Clear(SKColors.White);
SKPaint paint = new SKPaint
{
Color = SKColors.Red,
Style = SKPaintStyle.Stroke,
StrokeWidth = 5
};
// 绘制普通矩形
SKRect rect = new SKRect(100, 100, 300, 300);
canvas.DrawRect(rect, paint);
// 绘制圆角矩形
paint.Style = SKPaintStyle.Fill;
paint.Color = SKColors.Blue;
canvas.DrawRoundRect(rect, 20, 20, paint);
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("rectangles.png"))
{
data.SaveTo(stream);
}
}
3. 圆形和椭圆
可绘制标准圆形以及不同长短轴比例的椭圆,同样支持填充和描边操作。
using SkiaSharp;
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
canvas.Clear(SKColors.White);
SKPaint paint = new SKPaint
{
Color = SKColors.Green,
Style = SKPaintStyle.Stroke,
StrokeWidth = 5
};
// 绘制圆形
canvas.DrawCircle(200, 200, 100, paint);
// 绘制椭圆
paint.Style = SKPaintStyle.Fill;
paint.Color = SKColors.Yellow;
SKRect ovalRect = new SKRect(400, 100, 600, 300);
canvas.DrawOval(ovalRect, paint);
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("circles_and_ovals.png"))
{
data.SaveTo(stream);
}
}
4. 弧形和扇形
可以根据指定的起始角度和扫过角度绘制弧形和扇形,常用于绘制饼图、进度条等场景。
using SkiaSharp;
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
canvas.Clear(SKColors.White);
SKPaint paint = new SKPaint
{
Color = SKColors.Purple,
Style = SKPaintStyle.Stroke,
StrokeWidth = 5
};
SKRect arcRect = new SKRect(200, 200, 400, 400);
// 绘制弧形
canvas.DrawArc(arcRect, 0, 90, false, paint);
// 绘制扇形
paint.Style = SKPaintStyle.Fill;
canvas.DrawArc(arcRect, 180, 90, true, paint);
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("arcs_and_sectors.png"))
{
data.SaveTo(stream);
}
}
(二)路径绘制
1. 自定义形状
通过创建 SKPath
对象,我们可以定义复杂的自定义形状,例如多边形、不规则曲线等。
using SkiaSharp;
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
canvas.Clear(SKColors.White);
SKPaint paint = new SKPaint
{
Color = SKColors.Orange,
Style = SKPaintStyle.Stroke,
StrokeWidth = 5
};
SKPath path = new SKPath();
path.MoveTo(100, 100);
path.LineTo(200, 200);
path.LineTo(300, 100);
path.Close();
canvas.DrawPath(path, paint);
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("custom_path.png"))
{
data.SaveTo(stream);
}
}
2. 路径操作
支持对路径进行合并、相交、相减等布尔操作,从而创建更复杂的图形组合。
using SkiaSharp;
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
canvas.Clear(SKColors.White);
SKPaint paint = new SKPaint
{
Color = SKColors.Brown,
Style = SKPaintStyle.Fill
};
SKPath path1 = new SKPath();
path1.AddCircle(200, 200, 100);
SKPath path2 = new SKPath();
path2.AddRect(150, 150, 250, 250);
SKPath combinedPath = new SKPath();
combinedPath.Op(path1, path2, SKPathOp.Intersect);
canvas.DrawPath(combinedPath, paint);
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("path_operation.png"))
{
data.SaveTo(stream);
}
}
(三)文本绘制
1. 基本文本渲染
能够在画布上指定位置绘制文本,并设置字体、字号、颜色、对齐方式等属性。
using SkiaSharp;
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
canvas.Clear(SKColors.White);
SKPaint paint = new SKPaint
{
Color = SKColors.Black,
TextSize = 30,
Typeface = SKTypeface.FromFamilyName("Arial")
};
canvas.DrawText("Hello, SkiaSharp!", 100, 100, paint);
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("text_rendering.png"))
{
data.SaveTo(stream);
}
}
2. 文本布局
支持多行文本的布局,自动处理换行、缩进等。
using SkiaSharp;
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
canvas.Clear(SKColors.White);
SKPaint paint = new SKPaint
{
Color = SKColors.Black,
TextSize = 20,
Typeface = SKTypeface.FromFamilyName("Arial")
};
string multiLineText = "This is a multi-line text example.\nIt will be automatically wrapped.";
SKRect bounds = new SKRect(100, 100, 400, 400);
canvas.DrawText(multiLineText, bounds, paint);
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("text_layout.png"))
{
data.SaveTo(stream);
}
}
(四)图像和位图处理
1. 图像加载和保存
可以从文件、流或内存中加载常见格式(如 PNG、JPEG)的图像,也能将绘制结果保存为图像文件。
using SkiaSharp;
// 加载图像
using (SKBitmap loadedBitmap = SKBitmap.Decode("input.png"))
using (SKCanvas canvas = new SKCanvas(loadedBitmap))
{
// 在图像上绘制一些内容
SKPaint paint = new SKPaint
{
Color = SKColors.Red,
TextSize = 50
};
canvas.DrawText("Watermark", 100, 100, paint);
// 保存修改后的图像
using (SKData data = loadedBitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("output.png"))
{
data.SaveTo(stream);
}
}
2. 位图操作
对位图进行像素级别的操作,如获取和设置像素颜色、调整亮度、对比度、灰度化、色彩转换等,还可以进行图像的缩放、旋转、裁剪等变换操作。
using SkiaSharp;
using (SKBitmap bitmap = SKBitmap.Decode("input.png"))
{
// 灰度化
for (int y = 0; y < bitmap.Height; y++)
{
for (int x = 0; x < bitmap.Width; x++)
{
SKColor color = bitmap.GetPixel(x, y);
byte gray = (byte)((color.Red + color.Green + color.Blue) / 3);
SKColor grayColor = new SKColor(gray, gray, gray, color.Alpha);
bitmap.SetPixel(x, y, grayColor);
}
}
// 保存灰度化后的图像
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("grayscale.png"))
{
data.SaveTo(stream);
}
}
(五)颜色和渐变
1. 颜色处理
支持各种颜色模式,如 RGB、RGBA、HSV 等,可以方便地创建和操作颜色对象。
using SkiaSharp;
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
canvas.Clear(SKColors.White);
// 创建 RGB 颜色
SKColor rgbColor = new SKColor(255, 0, 0);
SKPaint paint = new SKPaint
{
Color = rgbColor,
Style = SKPaintStyle.Fill
};
canvas.DrawRect(new SKRect(100, 100, 300, 300), paint);
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("color_handling.png"))
{
data.SaveTo(stream);
}
}
2. 渐变填充
可以创建线性渐变、径向渐变和锥形渐变,并将其应用到图形的填充中。
using SkiaSharp;
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
canvas.Clear(SKColors.White);
SKPoint startPoint = new SKPoint(100, 100);
SKPoint endPoint = new SKPoint(300, 300);
SKColor[] colors = { SKColors.Red, SKColors.Yellow };
SKShader shader = SKShader.CreateLinearGradient(startPoint, endPoint, colors, null, SKShaderTileMode.Clamp);
SKPaint paint = new SKPaint
{
Shader = shader,
Style = SKPaintStyle.Fill
};
canvas.DrawRect(new SKRect(100, 100, 300, 300), paint);
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("gradient_fill.png"))
{
data.SaveTo(stream);
}
}
(六)变换和矩阵操作
1. 平移、旋转和缩放
通过矩阵变换可以对绘制的图形进行平移、旋转和缩放操作。
using SkiaSharp;
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
canvas.Clear(SKColors.White);
SKPaint paint = new SKPaint
{
Color = SKColors.Blue,
Style = SKPaintStyle.Fill
};
SKMatrix matrix = SKMatrix.MakeTranslation(200, 200);
matrix = matrix.PostConcat(SKMatrix.MakeRotationDegrees(45));
matrix = matrix.PostConcat(SKMatrix.MakeScale(2, 2));
canvas.SetMatrix(matrix);
canvas.DrawRect(new SKRect(-50, -50, 50, 50), paint);
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("transformations.png"))
{
data.SaveTo(stream);
}
}
2. 自定义变换
可以创建自定义的变换矩阵,实现更复杂的变形效果。
using SkiaSharp;
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
canvas.Clear(SKColors.White);
SKPaint paint = new SKPaint
{
Color = SKColors.Green,
Style = SKPaintStyle.Fill
};
SKMatrix customMatrix = new SKMatrix
{
ScaleX = 1.5f,
SkewY = 0.5f,
TransX = 100,
TransY = 200
};
canvas.SetMatrix(customMatrix);
canvas.DrawRect(new SKRect(-50, -50, 50, 50), paint);
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("custom_transformation.png"))
{
data.SaveTo(stream);
}
}
(七)阴影和特效
1. 阴影绘制
为图形添加阴影效果,增强图形的立体感和层次感。可以使用 SKPaint
的 ImageFilter
属性结合 SKImageFilter.CreateDropShadow
方法来实现。
using SkiaSharp;
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
canvas.Clear(SKColors.White);
SKPaint paint = new SKPaint
{
Color = SKColors.Black,
Style = SKPaintStyle.Fill
};
// 创建阴影滤镜
paint.ImageFilter = SKImageFilter.CreateDropShadow(
dx: 10,
dy: 10,
sigmaX: 5,
sigmaY: 5,
color: SKColors.Gray,
mode: SKDropShadowImageFilterShadowMode.DrawShadowAndForeground
);
// 绘制圆形,此时圆形会带有阴影
canvas.DrawCircle(400, 300, 100, paint);
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("shadow_example.png"))
{
data.SaveTo(stream);
}
}
在上述代码中,SKImageFilter.CreateDropShadow
方法的参数含义如下:
dx
和dy
:分别表示阴影在 X 轴和 Y 轴方向上的偏移量。sigmaX
和sigmaY
:控制阴影的模糊程度,值越大,阴影越模糊。color
:阴影的颜色。mode
:指定是只绘制阴影、只绘制前景图形还是两者都绘制。
2. 模糊和滤镜
应用模糊、锐化、色彩调整等滤镜效果,提升图像的视觉质量。下面以高斯模糊为例进行说明。
using SkiaSharp;
// 加载原始图像
using (SKBitmap sourceBitmap = SKBitmap.Decode("input.png"))
{
using (SKSurface surface = SKSurface.Create(new SKImageInfo(sourceBitmap.Width, sourceBitmap.Height)))
{
SKCanvas canvas = surface.Canvas;
// 创建模糊滤镜
SKImageFilter blurFilter = SKImageFilter.CreateBlur(
sigmaX: 5,
sigmaY: 5,
quality: SKFilterQuality.High
);
SKPaint paint = new SKPaint
{
ImageFilter = blurFilter
};
// 在画布上绘制应用滤镜后的图像
canvas.DrawBitmap(sourceBitmap, 0, 0, paint);
// 获取处理后的图像
using (SKImage outputImage = surface.Snapshot())
using (SKData data = outputImage.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("blurred_output.png"))
{
data.SaveTo(stream);
}
}
}
在这个示例中,SKImageFilter.CreateBlur
方法用于创建高斯模糊滤镜,sigmaX
和 sigmaY
控制模糊的强度,quality
指定模糊的质量。
(八)图形混合模式
支持多种图形混合模式,如正常、叠加、柔光等,通过不同的混合模式可以将多个图形或图像进行组合,创造出独特的视觉效果。
using SkiaSharp;
using (SKBitmap bitmap = new SKBitmap(800, 600))
using (SKCanvas canvas = new SKCanvas(bitmap))
{
canvas.Clear(SKColors.White);
// 绘制第一个圆形
SKPaint paint1 = new SKPaint
{
Color = SKColors.Red,
Style = SKPaintStyle.Fill
};
canvas.DrawCircle(200, 300, 100, paint1);
// 设置混合模式为叠加
SKPaint paint2 = new SKPaint
{
Color = SKColors.Blue,
Style = SKPaintStyle.Fill,
BlendMode = SKBlendMode.Overlay
};
// 绘制第二个圆形,与第一个圆形重叠部分会应用混合模式
canvas.DrawCircle(300, 300, 100, paint2);
using (SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 100))
using (System.IO.FileStream stream = System.IO.File.OpenWrite("blend_mode_example.png"))
{
data.SaveTo(stream);
}
}
在上述代码中,SKBlendMode.Overlay
是一种混合模式,它会将两个图形的颜色进行叠加处理,产生独特的视觉效果。SkiaSharp 还支持许多其他的混合模式,如 SKBlendMode.Normal
(正常模式)、SKBlendMode.SoftLight
(柔光模式)等。
(九)硬件加速和性能优化
SkiaSharp 支持利用 GPU 进行硬件加速,提高图形绘制的性能,尤其是在处理复杂图形和高分辨率图像时表现出色。同时,它还提供了一些性能优化的策略和方法,如使用缓存、批量绘制等。
1. 使用硬件加速
在 Xamarin.Android 项目中,可以通过创建 SKGLSurfaceView
来启用 OpenGL 硬件加速。以下是一个简单的示例:
using Android.App;
using Android.OS;
using Android.Views;
using SkiaSharp;
using SkiaSharp.Views.Android;
namespace SkiaSharpHardwareAcceleration
{
[Activity(Label = "SkiaSharpHardwareAcceleration", MainLauncher = true)]
public class MainActivity : Activity
{
private SKGLSurfaceView skiaView;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
skiaView = new SKGLSurfaceView(this);
skiaView.PaintSurface += OnPaintSurface;
SetContentView(skiaView);
}
private void OnPaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
SKCanvas canvas = e.Surface.Canvas;
canvas.Clear(SKColors.White);
SKPaint paint = new SKPaint
{
Color = SKColors.Black,
StrokeWidth = 5
};
canvas.DrawLine(100, 100, 300, 300, paint);
}
}
}
在这个示例中,SKGLSurfaceView
利用 OpenGL 进行硬件加速,提升了图形绘制的性能。
2. 使用缓存
对于一些经常使用的图形元素,如字体、画笔等,可以进行缓存,避免重复创建。
private static SKPaint cachedPaint;
public void DrawSomething(SKCanvas canvas)
{
if (cachedPaint == null)
{
cachedPaint = new SKPaint
{
Color = SKColors.Red,
TextSize = 30
};
}
canvas.DrawText("Cached Text", 100, 100, cachedPaint);
}
通过缓存 SKPaint
对象,减少了每次绘制时创建新对象的开销,提高了性能。
(十)跨平台支持
SkiaSharp 可以在多种操作系统(如 Windows、macOS、Linux)和设备(如桌面、移动设备)上运行,并且可以与不同的 .NET 应用程序框架(如 .NET Core、Xamarin)集成,方便开发者创建跨平台的图形应用。以下是一个在 Xamarin.Forms 中使用 SkiaSharp 的简单示例:
1. 创建 Xamarin.Forms 项目
首先,创建一个新的 Xamarin.Forms 项目。
2. 安装 SkiaSharp 相关 NuGet 包
在项目中安装 SkiaSharp
、SkiaSharp.Views.Forms
等相关 NuGet 包。
3. 创建自定义 SkiaSharp 视图
using SkiaSharp;
using SkiaSharp.Views.Forms;
using Xamarin.Forms;
namespace SkiaSharpXamarinFormsExample
{
public class CustomSkiaView : SKCanvasView
{
protected override void OnPaintSurface(SKPaintSurfaceEventArgs e)
{
base.OnPaintSurface(e);
SKCanvas canvas = e.Surface.Canvas;
canvas.Clear(SKColors.White);
SKPaint paint = new SKPaint
{
Color = SKColors.Blue,
Style = SKPaintStyle.Fill
};
canvas.DrawCircle(100, 100, 50, paint);
}
}
}
4. 在 XAML 中使用自定义视图
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SkiaSharpXamarinFormsExample"
x:Class="SkiaSharpXamarinFormsExample.MainPage">
<local:CustomSkiaView />
</ContentPage>
通过以上步骤,我们可以在 Xamarin.Forms 应用中使用 SkiaSharp 进行图形绘制,并且这个应用可以在 Android、iOS 等多个平台上运行。
SkiaSharp 提供了丰富的功能和强大的性能,无论是简单的图形绘制还是复杂的图像处理,都能轻松应对。通过合理运用这些功能,开发者可以创建出高质量的跨平台图形应用。
李枭龙2025-01-13 15:23
AI生成文章:请以上所有知识进行深入分析,确定主要知识点,为每个知识点撰写详细说明并附上具有代表性且带有清晰注释的代码示例,接着根据内容拟定一个准确反映文档核心的标题,最后严格按照 Markdown 格式进行排版,确保文档规范美观,以满足初学者学习使用的需求。
李枭龙2024-09-05 22:04
X Lucas