2025-11-19
C#
00

目录

Nuget 安装包
基本旋转方法
简单角度旋转
保持原始尺寸的旋转
高级旋转技巧
带插值的平滑旋转
注意事项
性能建议
结语

SkiaSharp 提供了强大的图像处理能力,其中图像旋转是最常用的操作之一。本文将深入探讨SkiaSharp中图像旋转的多种方法和技巧。

Nuget 安装包

C#
SkiaSharp SkiaSharp.Views.WindowsForms

基本旋转方法

简单角度旋转

C#
using System.Windows.Forms; using SkiaSharp; namespace AppRotation { public partial class Form1 : Form { private SKBitmap originalBitmap; private string currentImagePath; public Form1() { InitializeComponent(); } private void btnLoad_Click(object sender, EventArgs e) { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.Filter = "Image Files|*.png;*.jpg;*.jpeg;*.bmp;*.gif"; if (openFileDialog.ShowDialog() == DialogResult.OK) { currentImagePath = openFileDialog.FileName; using (var fileStream = new FileStream(currentImagePath, FileMode.Open)) { originalBitmap = SKBitmap.Decode(fileStream); UpdateRotatedImage(pic, tbAngle.Value); btnSave.Enabled = true; } } } } private void tbAngle_Scroll(object sender, EventArgs e) { lblAngle.Text = $"Rotation Angle: {tbAngle.Value}°"; if (originalBitmap != null) { UpdateRotatedImage(pic, tbAngle.Value); } } private void btnSave_Click(object sender, EventArgs e) { if (originalBitmap == null) return; using (SaveFileDialog saveFileDialog = new SaveFileDialog()) { saveFileDialog.Filter = "PNG Image|*.png|JPEG Image|*.jpg|BMP Image|*.bmp"; saveFileDialog.DefaultExt = "png"; saveFileDialog.AddExtension = true; if (saveFileDialog.ShowDialog() == DialogResult.OK) { using (SKBitmap rotatedBitmap = RotateImage(originalBitmap, tbAngle.Value)) { using (SKImage image = SKImage.FromBitmap(rotatedBitmap)) using (SKData data = image.Encode(SKEncodedImageFormat.Png, 100)) using (FileStream stream = new FileStream(saveFileDialog.FileName, FileMode.Create)) { data.SaveTo(stream); } } MessageBox.Show("Image saved successfully!", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } private void UpdateRotatedImage(PictureBox pic, int angle) { if (originalBitmap == null) return; using (SKBitmap rotatedBitmap = RotateImage(originalBitmap, angle)) { using (SKImage image = SKImage.FromBitmap(rotatedBitmap)) using (SKData data = image.Encode()) using (MemoryStream memStream = new MemoryStream()) { data.SaveTo(memStream); memStream.Position = 0; if (pic.Image != null) { pic.Image.Dispose(); } pic.Image = new Bitmap(memStream); } } } public SKBitmap RotateImage(SKBitmap originalBitmap, float angle) { // 创建一个新的位图,大小适应旋转后的图像 SKBitmap rotatedBitmap = new SKBitmap( (int)(Math.Abs(originalBitmap.Width * Math.Cos(angle * Math.PI / 180)) + Math.Abs(originalBitmap.Height * Math.Sin(angle * Math.PI / 180))), (int)(Math.Abs(originalBitmap.Width * Math.Sin(angle * Math.PI / 180)) + Math.Abs(originalBitmap.Height * Math.Cos(angle * Math.PI / 180))) ); using (SKCanvas canvas = new SKCanvas(rotatedBitmap)) { // Clear canvas with transparent background canvas.Clear(SKColors.Transparent); // 将画布中心移动到图像中心 canvas.Translate(rotatedBitmap.Width / 2f, rotatedBitmap.Height / 2f); // 旋转画布 canvas.RotateDegrees(angle); // 绘制原始图像,使其居中 canvas.DrawBitmap(originalBitmap, new SKPoint(-originalBitmap.Width / 2f, -originalBitmap.Height / 2f)); } return rotatedBitmap; } } }

image.png

保持原始尺寸的旋转

C#
public SKBitmap RotateImageInPlace(SKBitmap originalBitmap, float angle) { SKBitmap rotatedBitmap = new SKBitmap(originalBitmap.Width, originalBitmap.Height); using (SKCanvas canvas = new SKCanvas(rotatedBitmap)) { // 填充背景(可选) canvas.Clear(SKColors.Transparent); // 将画布中心移动到图像中心 canvas.Translate(originalBitmap.Width / 2f, originalBitmap.Height / 2f); // 旋转画布 canvas.RotateDegrees(angle); // 绘制原始图像,使其居中 canvas.DrawBitmap(originalBitmap, new SKPoint(-originalBitmap.Width / 2f, -originalBitmap.Height / 2f)); } return rotatedBitmap; }

image.png

高级旋转技巧

带插值的平滑旋转

C#
public SKBitmap SmoothRotateImage(SKBitmap originalBitmap, float angle) { // 创建一个新的位图,考虑旋转后的最大尺寸 SKBitmap rotatedBitmap = new SKBitmap( (int)(Math.Abs(originalBitmap.Width * Math.Cos(angle * Math.PI / 180)) + Math.Abs(originalBitmap.Height * Math.Sin(angle * Math.PI / 180))), (int)(Math.Abs(originalBitmap.Width * Math.Sin(angle * Math.PI / 180)) + Math.Abs(originalBitmap.Height * Math.Cos(angle * Math.PI / 180))) ); using (SKCanvas canvas = new SKCanvas(rotatedBitmap)) { // 使用高质量的插值模式 canvas.SetMatrix(SKMatrix.CreateRotationDegrees(angle, rotatedBitmap.Width / 2f, rotatedBitmap.Height / 2f)); // 使用双线性插值绘制图像 canvas.DrawBitmap(originalBitmap, new SKRect(0, 0, originalBitmap.Width, originalBitmap.Height), new SKRect(0, 0, rotatedBitmap.Width, rotatedBitmap.Height), new SKPaint { FilterQuality = SKFilterQuality.High }); } return rotatedBitmap; } ![image.png](https://www.otteach.cn/static/img/b93795dc6e5411af0bd1d7edc011c233.image.webp) ## 注意事项 - 旋转会改变图像的尺寸和质量 - 大角度旋转可能导致图像边缘出现锯齿 - 选择合适的插值模式可以提高旋转质量 ## 性能建议 - 对于频繁旋转,考虑重用 `SKCanvas` 和 `SKBitmap` - 使用 `SKFilterQuality` 平衡图像质量和性能 - 对于大图像,考虑异步处理 ## 结语 SkiaSharp 提供了灵活且强大的图像旋转功能。通过合理使用旋转方法,可以轻松实现各种图像处理需求。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!