LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

【C#】SkiaSharp 图像缩放技术深入解析

admin
2025年9月3日 21:19 本文热度 26

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

Nuget 安装包

SkiaSharp
SkiaSharp.Views.WindowsForms

基本缩放方法

等比例缩放

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, 00);
            }

            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()))
            {
                returnnew Bitmap(stream);
            }
        }

    }
}

指定缩放质量

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

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(00, targetWidth, targetHeight),
                                           new SKRect(00, 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()))
            {
                returnnew Bitmap(stream);
            }
        }
    }
}

高级缩放技术

保持图像清晰度的缩放

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(00, originalImage.Width, originalImage.Height),
            new SKRect(00, targetWidth, targetHeight), 
            new SKPaint 
            { 
                FilterQuality = SKFilterQuality.High 
            }
        );
    }

    return scaledBitmap;
}

缩放实践建议

性能与质量平衡

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

异常处理

public SKBitmap SafeScaleImage(SKBitmap originalImage, int targetWidth, int targetHeight)
{
    // 检查输入有效性
    if (originalImage == null)
        thrownew ArgumentNullException(nameof(originalImage));

    if (targetWidth <= 0 || targetHeight <= 0)
        thrownew ArgumentException("目标尺寸必须为正数");

    try
    {
        return ScaleImageWithFilter(
            originalImage, 
            targetWidth, 
            targetHeight, 
            SKFilterQuality.Medium
        );
    }
    catch (Exception ex)
    {
        // 记录错误或返回原图
        Console.WriteLine($"图像缩放失败:{ex.Message}");
        return originalImage;
    }
}

总结

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


阅读原文:原文链接


该文章在 2025/9/4 14:39:27 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved