使用SkiaSharp在C#中如何生成图像

 更新时间:2025年01月07日 09:51:54   作者:坐井观老天  
本文介绍了如何使用SkiaSharp库在C#中生成和处理图像,通过创建一个空白图像并绘制一个正方形,我们展示了如何使用SkiaSharp的基本功能,如创建画布、绘制图形和保存图像

使用SkiaSharp在C#中生成图像

在本文中,我们将学习如何使用 SkiaSharp 在 C# 中生成图像。

什么是 SkiaSharp?

SkiaSharp 库是一个适用于 .NET 平台的跨平台 2D 图形 API,它基于 Google 的 Skia Graphics 库,后者是一个用于绘制文本、几何图形和图像的综合库。该库是 Google Chrome、ChromeOS、Android 和 Flutter 等各种 Google 产品中使用的图形引擎。

在本文中,我们将探索使用 SkiaSharp 创建一个空白图像,然后在创建的图像中间绘制一个正方形。

让我们首先在终端上导航到我们的项目目录来导入 NuGet 包:

创建图像

接下来,让我们创建一个ImageService静态类,在其中定义一些辅助方法,首先创建一个空白图像

public static SKBitmap CreateBlankImage(int width, int height)
{
    var bitmap = new SKBitmap(width, height);
    using var canvas = new SKCanvas(bitmap);
    canvas.Clear(SKColors.White);

    return bitmap;
}

这里我们看到了静态方法的定义CreateBlankImage(),它接受width和height作为参数并返回一个bitmap类型SKBitmap,它代表 SkiaSharp 中的图像。

我们首先使用SKBitmap给定的width和创建一个对象height。然后,我们SKCanvas使用初始化一个新对象SKBitmap。这样,我们将画布链接到位图。该类SKCanvas表示 SkiaSharp 中的画布或绘图表面。它提供绘制图形、文本和图像的方法。

当我们最初创建位图时,其像素数据由未定义的随机值组成。在使用构造函数将位图附加到画布时SKCanvas(),我们创建了一种操作图像像素数据的方法。如果没有画布,位图将保持未初始化的随机值。

请注意,SKCanvas对象是可丢弃的,因此添加了使用声明以确保正确清理。

接下来,我们使用方法清除整个画布SKCanvas.Clear(SKColor)。该Clear()方法将画布内的所有像素设置为单一颜色,在我们的例子中为SKColors.White。如果我们调用无参数重载,Clear()所有像素将设置为SKColor.Empty(#00000000)。

处理图像

现在,让我们创建一个方法在图像的中心绘制一个正方形:

public static void DrawSquareOnImage(SKBitmap bitmap, int squareSize, int startX, int startY)
{
    if (squareSize <= 0 || startX <= 0 || startY <= 0)
    { 
        throw new ArgumentException("Square size and coordinates must be greater than zero.");
    }
    using var canvas = new SKCanvas(bitmap);
    using var paint = new SKPaint();
    paint.Color = SKColors.Red;
    var square = new SKRect(startX, startY, startX + squareSize, startY + squareSize);
    canvas.DrawRect(square, paint);
}

这里我们定义了一个DrawSquareOnImage()方法,它将在提供的图像上绘制一个正方形。它有四个参数,即SKBitmap我们将在其上绘制的对象squareSize、startX和startY。squareSize表示我们将绘制的正方形的大小,而startX和startY表示正方形起点的 X 和 Y 坐标。

首先,我们验证所有int参数值都大于零。

接下来,我们创建一个新SKCanvas对象,用于在位图上进行绘制。之后,我们实例化一个新SKPaint对象并将其设置Color为SKColors.Red。我们使用SKPaint来定义绘制对象的样式和颜色信息:几何图形、文本和位图。

接下来,我们创建一个实例SKRect,该结构体包含一个矩形的四个坐标,在我们的例子中,矩形是一个正方形。最后,我们使用方法在画布上绘制正方形DrawRect(),该方法同时接受一个SKRect参数 ( square) 和一个SKPaint( paint) 参数。

保存图像

现在,让我们创建一个保存图像的方法:

public static void SaveImage(SKBitmap bitmap, string outputPath)
{
    using var stream = new FileStream(outputPath, FileMode.Create, FileAccess.Write);
    using var image = SKImage.FromBitmap(bitmap); 
    using var encodedImage = image.Encode(); 
    encodedImage.SaveTo(stream);
}

这里我们定义SaveImage()静态方法,它接受两个参数:bitmap和outputPath。

我们首先实例化一个FileStream用于创建文件的对象,设置FileModetoFileMode.Create来创建文件或覆盖文件(如果文件已存在),以及FileAccessto FileAccess.Write。

接下来,我们将位图转换为SKImage,然后调用无参数Encode()方法,该方法默认将我们的编码SKImage为PNG格式。然后我们最终将其保存到FileStream。

这些using声明确保每个可释放对象在使用后都会被调用Dispose()方法,以确保正确的资源管理。

生成样本图像

现在,让我们将之前创建的方法带入我们的Program类并创建一个新的图像:

string outputPath = @"outputImage.png";

int imageWidth = 400;
int imageHeight = 300;
int squareSize = 120;
int startX = (imageWidth - squareSize) / 2;
int startY = (imageHeight - squareSize) / 2;
var bitmap = ImageService.CreateBlankImage(imageWidth, imageHeight);
ImageService.DrawSquareOnImage(bitmap, squareSize, startX, startY);
ImageService.SaveImage(bitmap, outputPath);

Console.WriteLine("Image generated and saved successfully.");

我们指定目录的路径,用于outputImage.png保存生成的图像。我们所需的目录是包含我们.exe文件的文件夹,即我们的“net8.0”文件夹。

我们将imageWidth、imageHeight和squareSize分别设置为400px、300px和120px。

imageWidth接下来,我们通过提供和来计算正方形相对于 x 轴的起点squareSize。类似地,我们提供imageHeight和squareSize来计算正方形的 y 轴起点。

之后,我们CreateBlankImage()从ImageService类中调用方法,提供imageWidth和imageHeight来创建我们的bitmap。

创建图像后,我们调用DrawSquareOnImage()方法,提供我们的bitmap和我们之前计算的值:squareSize,startX,startY。这样,正方形就画在我们的 上了bitmap。

最后,我们将修改后的内容保存bitmap到我们之前定义的outputPath,并在控制台上打印确认消息。

让我们测试一下:

Image generated and saved successfully.

正如预期的那样,看到了一条成功消息。

看一下我们的图像:

总结

在本文中,我们通过示例操作一些图像,研究了如何使用 SkiaSharp 库在 C# 中生成和处理图像。

 .NET Core 应用程序中的图像上绘制图形和文本(4 个简单步骤)

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Unity之跑马灯抽奖效果单抽与连抽(附demo)

    Unity之跑马灯抽奖效果单抽与连抽(附demo)

    这篇文章主要介绍了Unity之跑马灯抽奖效果单抽与连抽,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • C# DatagridView常用操作汇总

    C# DatagridView常用操作汇总

    这篇文章主要介绍了C# DatagridView常用操作汇总,罗列了一些常用的用法与技巧,需要的朋友可以参考下
    2014-07-07
  • c#不使用系统api实现可以指定区域屏幕截屏功能

    c#不使用系统api实现可以指定区域屏幕截屏功能

    这篇文章主要介绍了不使用系统API通过纯c#实现屏幕指定区域截屏功能,截屏后还可以保存图象文件,大家参考使用吧
    2014-01-01
  • C#线程开发之System.Thread类详解

    C#线程开发之System.Thread类详解

    本文详细讲解了C#线程开发之System.Thread类,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • C#中this的使用实例分析

    C#中this的使用实例分析

    这篇文章主要介绍了C#中this的使用方法,this是C#程序设计中非常重要的一个关键字,本文以实例形式对此作出简单的用法分析,需要的朋友可以参考下
    2014-08-08
  • C#操作JSON(序列化与反序列化)的方法详解

    C#操作JSON(序列化与反序列化)的方法详解

    .net core提供了Json处理模块,在命名空间System.Text.Json中,本文将通过顶级语句,对C#的Json功能进行讲解,感兴趣的小伙伴可以了解一下
    2023-05-05
  • Unity平台模拟自动挡驾驶汽车

    Unity平台模拟自动挡驾驶汽车

    这篇文章主要为大家详细介绍了Unity平台模拟自动挡驾驶汽车,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • 基于C#开发中的那些编码问题(详谈)

    基于C#开发中的那些编码问题(详谈)

    下面小编就为大家分享一篇基于C#开发中的那些编码问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-11-11
  • ItemsControl 数据绑定的两种方式

    ItemsControl 数据绑定的两种方式

    这篇文章主要介绍了ItemsControl 数据绑定的两种方式,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-03-03
  • C#流类FileStream学习使用笔记

    C#流类FileStream学习使用笔记

    这篇文章主要介绍了C#流类FileStream学习使用笔记,本文直接给出示例代码,代码中每一步都有详细注释,需要的朋友可以参考下
    2015-06-06

最新评论