2025-11-19
C#
00

目录

Nuget 安装包
基本缩放方法
等比例缩放
指定缩放质量
高级缩放技术
保持图像清晰度的缩放
缩放实践建议
性能与质量平衡
异常处理
总结

SkiaSharp 提供了多种强大的图像缩放方法,可以满足不同场景下的图像处理需求。本文将详细探讨 SkiaSharp 中图像缩放的各种技术和最佳实践。

Nuget 安装包

C#
SkiaSharp SkiaSharp.Views.WindowsForms

基本缩放方法

等比例缩放

C#
using System.Windows.Forms; using SkiaSharp; namespace AppImageScaling { public partial class Form1 : Form { private SKBitmap originalImage; public Form1() { InitializeComponent(); } private void btnLoad_Click(object sender, EventArgs e) { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.Filter = "Image Files|*.bmp;*.jpg;*.jpeg;*.png;*.gif"; if (openFileDialog.ShowDialog() == DialogResult.OK) { originalImage = SKBitmap.Decode(openFileDialog.FileName); SKBitmap scaledImage = ScaleImageProportionally(originalImage, 400); pic.Image = BitmapFromSKBitmap(scaledImage); } } } public SKBitmap ScaleImageProportionally(SKBitmap originalImage, int targetWidth) { // 计算等比例缩放的高度 float aspectRatio = (float)originalImage.Height / originalImage.Width; int targetHeight = (int)(targetWidth * aspectRatio); // 创建缩放后的位图 SKBitmap scaledBitmap = new SKBitmap(targetWidth, targetHeight); // 使用高质量缩放 using (SKCanvas canvas = new SKCanvas(scaledBitmap)) { canvas.SetMatrix(SKMatrix.CreateScale( (float)targetWidth / originalImage.Width, (float)targetHeight / originalImage.Height )); // 绘制原始图像 canvas.DrawBitmap(originalImage, 0, 0); } return scaledBitmap; } private Bitmap BitmapFromSKBitmap(SKBitmap skBitmap) { using (var image = SKImage.FromBitmap(skBitmap)) using (var data = image.Encode(SKEncodedImageFormat.Png, 100)) using (var stream = new System.IO.MemoryStream(data.ToArray())) { return new Bitmap(stream); } } } }

image.png

指定缩放质量

SkiaSharp 提供多种缩放滤波器,可以根据不同需求选择:

C#
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using SkiaSharp; namespace AppImageScaling { public partial class Form2 : Form { private SKBitmap originalImage; public Form2() { InitializeComponent(); } private void btnLoad_Click(object sender, EventArgs e) { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.Filter = "Image Files|*.bmp;*.jpg;*.jpeg;*.png;*.gif"; if (openFileDialog.ShowDialog() == DialogResult.OK) { originalImage = SKBitmap.Decode(openFileDialog.FileName); int targetWidth = 400; int targetHeight = (int)((float)originalImage.Height / originalImage.Width * targetWidth); SKFilterQuality filterQuality = GetFilterQuality(cboQuality.SelectedItem.ToString()); SKBitmap scaledImage = ScaleImageWithFilter(originalImage, targetWidth, targetHeight, filterQuality); pic.Image = BitmapFromSKBitmap(scaledImage); } } } public SKBitmap ScaleImageWithFilter(SKBitmap originalImage, int targetWidth , int targetHeight, SKFilterQuality filterQuality) { // 创建目标位图 SKBitmap scaledBitmap = new SKBitmap(targetWidth, targetHeight); using (SKCanvas canvas = new SKCanvas(scaledBitmap)) { // 创建绘制对象并设置过滤质量 using (var paint = new SKPaint()) { paint.FilterQuality = filterQuality; // 通过指定目标点和目标尺寸来绘制原始图像到目标位图 canvas.DrawBitmap(originalImage, new SKRect(0, 0, targetWidth, targetHeight), new SKRect(0, 0, originalImage.Width, originalImage.Height), paint); } } return scaledBitmap; } private SKFilterQuality GetFilterQuality(string quality) { return quality switch { "Low" => SKFilterQuality.Low, "Medium" => SKFilterQuality.Medium, "High" => SKFilterQuality.High, _ => SKFilterQuality.None, }; } private Bitmap BitmapFromSKBitmap(SKBitmap skBitmap) { using (var image = SKImage.FromBitmap(skBitmap)) using (var data = image.Encode(SKEncodedImageFormat.Png, 100)) using (var stream = new System.IO.MemoryStream(data.ToArray())) { return new Bitmap(stream); } } } }

image.png

高级缩放技术

保持图像清晰度的缩放

C#
public SKBitmap ScaleImageWithSharpness(SKBitmap originalImage, float scaleFactor) { // 计算目标尺寸 int targetWidth = (int)(originalImage.Width * scaleFactor); int targetHeight = (int)(originalImage.Height * scaleFactor); // 创建高清缩放位图 SKBitmap scaledBitmap = new SKBitmap(targetWidth, targetHeight); using (SKCanvas canvas = new SKCanvas(scaledBitmap)) { // 使用高质量插值 canvas.DrawBitmap(originalImage, new SKRect(0, 0, originalImage.Width, originalImage.Height), new SKRect(0, 0, targetWidth, targetHeight), new SKPaint { FilterQuality = SKFilterQuality.High } ); } return scaledBitmap; }

缩放实践建议

性能与质量平衡

  • 对于缩略图,使用 SKFilterQuality.Low
  • 对于高质量展示,使用 SKFilterQuality.High
  • 大幅缩放时,考虑分步缩放以保持图像质量

异常处理

C#
public SKBitmap SafeScaleImage(SKBitmap originalImage, int targetWidth, int targetHeight) { // 检查输入有效性 if (originalImage == null) throw new ArgumentNullException(nameof(originalImage)); if (targetWidth <= 0 || targetHeight <= 0) throw new ArgumentException("目标尺寸必须为正数"); try { return ScaleImageWithFilter( originalImage, targetWidth, targetHeight, SKFilterQuality.Medium ); } catch (Exception ex) { // 记录错误或返回原图 Console.WriteLine($"图像缩放失败:{ex.Message}"); return originalImage; } }

总结

SkiaSharp 提供了灵活且强大的图像缩放功能,能够通过选择合适的缩放方法和质量滤波器,在性能与图像质量之间实现良好平衡。在使用过程中,需要注意几个关键技巧:保持图像的纵横比以避免变形,根据需求选择适当的缩放质量以优化视觉效果,妥善处理边界情况以确保输出的准确性,同时权衡性能开销以满足实际应用的需求。这些策略有助于高效地实现高质量的图像缩放。

本文作者:技术老小子

本文链接:

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