当前位置: 首页 > article >正文

C#实现图片缩略图生成:多种模式详解与实践

C#实现图片缩略图生成:多种模式详解与实践

在图像处理的场景中,生成图片缩略图是一项常见且实用的功能。无论是搭建图片展示网站,还是开发本地图片管理工具,按需生成合适尺寸的缩略图,能够有效减少图片传输和显示所需的资源,提升用户体验。本文将基于一段 C# 代码,详细介绍如何在 C# 中实现图片缩略图的生成,并支持多种不同的缩放模式。

一、代码整体结构

代码主要包含了三个核心部分:枚举类型ThumbnailMode用于定义缩略图生成模式,类ThumbnailOptions封装生成缩略图所需的参数,类Thumbnail则负责具体的缩略图生成逻辑。

1. 定义缩略图生成模式枚举

public enum ThumbnailMode
{Cut,Hw,H,W,
}

ThumbnailMode枚举定义了四种不同的缩略图生成模式:

  • Cut:指定高宽裁减(不变形)。该模式会根据目标宽高比例和原图宽高比例进行计算,对原图进行裁剪,以保证生成的缩略图符合指定尺寸且不会变形。
  • Hw:指定高宽缩放(可能变形)。直接按照给定的目标宽度和高度对原图进行缩放,不考虑原图的宽高比例,可能导致图片拉伸变形。
  • W:指定宽,高按比例。根据给定的目标宽度,按照原图的宽高比例自动计算出对应的高度,从而生成等比例缩放的缩略图。
  • H:指定高,宽按比例。与W模式类似,根据给定的目标高度,按照原图的宽高比例自动计算出对应的宽度。

2. 封装缩略图生成参数类

public class ThumbnailOptions
{/// <summary>/// 缩略图宽度/// </summary>public int Width { get; set; }/// <summary>/// 缩略图高度/// </summary>public int Height { get; set; }/// <summary>/// 生成缩略图的方式/// </summary>public ThumbnailMode Mode { get; set; }
}

ThumbnailOptions类用于封装生成缩略图所需的参数,包括目标宽度Width、目标高度Height以及选择的生成模式Mode。通过将这些参数封装在一个类中,使得在调用生成缩略图的方法时,参数传递更加清晰和便捷。

3. 实现缩略图生成类

[SupportedOSPlatform("windows")]
internal class Thumbnail
{/// <summary>/// 生成缩略图/// </summary>/// <param name="options">参数</param>/// <return> image</return>public static SystemImage Generate(SystemImage original, ThumbnailOptions options){var towidth = options.Width;var toheight = options.Height;var x = 0;var y = 0;var ow = original.Width;var oh = original.Height;switch (options.Mode){case ThumbnailMode.Hw:  //指定高宽缩放(可能变形)                break;case ThumbnailMode.W:   //指定宽,高按比例                    toheight = original.Height * options.Width/ original.Width;break;case ThumbnailMode.H:   //指定高,宽按比例towidth = original.Width * options.Height/ original.Height;break;default: //指定高宽裁减(不变形)                if ((double)original.Width / original.Height > towidth / (double)toheight){oh = original.Height;ow = original.Height * towidth / toheight;y = 0;x = (original.Width - ow) / 2;}else{ow = original.Width;oh = original.Width * options.Height / towidth;x = 0;y = (original.Height - oh) / 2;}break;}//新建一个bmp图片var bitmap = new Bitmap(towidth, toheight);//新建一个画板var g = Graphics.FromImage(bitmap);//设置高质量插值法g.InterpolationMode = InterpolationMode.High;//设置高质量,低速度呈现平滑程度g.SmoothingMode = SmoothingMode.HighQuality;//清空画布并以透明背景色填充g.Clear(Color.Transparent);//在指定位置并且按指定大小绘制原图片的指定部分g.DrawImage(original, new Rectangle(0, 0, towidth, toheight), new Rectangle(x, y, ow, oh), GraphicsUnit.Pixel);return bitmap;}
}

Thumbnail类包含一个静态方法Generate,用于根据传入的原图和生成参数,生成对应的缩略图。方法的参数original为原始图片对象,options为包含目标尺寸和生成模式的参数对象。

二、生成缩略图的核心逻辑

Generate方法中,首先获取目标宽度towidth和目标高度toheight,以及原图的宽度ow和高度oh。然后根据选择的ThumbnailMode模式,执行不同的计算逻辑来确定最终的裁剪或缩放尺寸。

switch (options.Mode)
{case ThumbnailMode.Hw:  //指定高宽缩放(可能变形)               break;case ThumbnailMode.W:   //指定宽,高按比例                   toheight = original.Height * options.Width / original.Width;break;case ThumbnailMode.H:   //指定高,宽按比例towidth = original.Width * options.Height / original.Height;break;default: //指定高宽裁减(不变形)               if ((double)original.Width / original.Height > towidth / (double)toheight){oh = original.Height;ow = original.Height * towidth / toheight;y = 0;x = (original.Width - ow) / 2;}else{ow = original.Width;oh = original.Width * options.Height / towidth;x = 0;y = (original.Height - oh) / 2;}break;
}
  • Hw模式:由于直接按照给定的宽高进行缩放,在这部分代码中未做特殊处理,后续绘制时会直接使用传入的目标宽高。
  • W模式:根据原图的宽高比例,计算出与目标宽度对应的高度,确保图片在缩放过程中保持比例。
  • H模式:与W模式类似,根据原图比例计算出与目标高度对应的宽度。
  • Cut模式:通过比较原图和目标图的宽高比例,确定需要裁剪的区域。如果原图宽高比大于目标宽高比,说明原图更 “宽”,则保持高度不变,计算出对应的宽度,并确定水平方向的裁剪偏移量x;反之,如果原图宽高比小于目标宽高比,说明原图更 “高”,则保持宽度不变,计算出对应的高度,并确定垂直方向的裁剪偏移量y

确定好裁剪或缩放的尺寸后,接下来使用System.Drawing命名空间下的类来创建新的图片对象和绘图上下文,并进行图片绘制:

//新建一个bmp图片
var bitmap = new Bitmap(towidth, toheight);
//新建一个画板
var g = Graphics.FromImage(bitmap);
//设置高质量插值法
g.InterpolationMode = InterpolationMode.High;
//设置高质量,低速度呈现平滑程度
g.SmoothingMode = SmoothingMode.HighQuality;
//清空画布并以透明背景色填充
g.Clear(Color.Transparent);
//在指定位置并且按指定大小绘制原图片的指定部分
g.DrawImage(original, new Rectangle(0, 0, towidth, toheight), new Rectangle(x, y, ow, oh), GraphicsUnit.Pixel);
return bitmap;

创建一个指定尺寸的Bitmap对象作为缩略图,获取其绘图上下文Graphics对象。通过设置InterpolationModeSmoothingMode,可以提升图片缩放时的质量,使生成的缩略图更加平滑。清空画布后,使用DrawImage方法将原图的指定部分绘制到新的缩略图中,最后返回生成的缩略图对象。

三、使用示例

以下是一个简单的使用示例,展示如何调用上述代码生成缩略图:

using System;
using System.Drawing;
class Program
{static void Main(){// 加载原始图片var originalImage = Image.FromFile("path/to/your/original/image.jpg");// 创建缩略图生成参数对象var options = new ThumbnailOptions{Width = 200,Height = 200,Mode = ThumbnailMode.Cut};// 生成缩略图var thumbnail = Thumbnail.Generate(originalImage, options);// 保存缩略图thumbnail.Save("path/to/save/thumbnail.jpg");// 释放资源originalImage.Dispose();thumbnail.Dispose();}
}

在上述示例中,首先通过Image.FromFile方法加载原始图片,然后创建ThumbnailOptions对象并设置目标尺寸和生成模式,接着调用Thumbnail.Generate方法生成缩略图,最后将缩略图保存到指定路径,并释放相关资源。

四、总结

通过上述代码和讲解,我们了解了如何在 C# 中基于System.Drawing库实现图片缩略图的生成,并支持多种不同的缩放和裁剪模式。在实际项目中,我们可以根据具体需求选择合适的模式来生成高质量的缩略图。需要注意的是,代码中使用了[SupportedOSPlatform("windows")]特性,表明该代码仅适用于 Windows 操作系统,如果需要在其他平台上运行,可能需要考虑使用其他图像处理库或进行相应的适配。希望本文对你在 C# 图像处理方面有所帮助,如果你有任何疑问或改进建议,欢迎在评论区交流!

上述博客全面解析了缩略图生成代码。若你觉得某些部分需要补充,或有新的展示需求,欢迎随时和我说。

相关文章:

C#实现图片缩略图生成:多种模式详解与实践

C#实现图片缩略图生成&#xff1a;多种模式详解与实践 在图像处理的场景中&#xff0c;生成图片缩略图是一项常见且实用的功能。无论是搭建图片展示网站&#xff0c;还是开发本地图片管理工具&#xff0c;按需生成合适尺寸的缩略图&#xff0c;能够有效减少图片传输和显示所需…...

Linux下基本指令的介绍

目录 1.目标 2.快速认识指令 1.pwd 2.clear 3.ls 4.mkdir 5.cd 6.touch 3.细化每一条指令 1.ls指令 2.pwd指令 注&#xff1a; 3.cd指令 4.touch和mkdir指令 6.删除文件 4.总结 1.目标 上一篇博客中&#xff0c;我们了解了Linux的起源和发展&#xff0c;也知道…...

零基础开始的网工之路第十四天------Linux程序管理

目录 一、Linux程序与进程 1、程序,进程,线程的概念 2、程序和进程的区别 3、进程和线程的区别 二、Linux进程基础(生命周期) 1、进程生命周期 2、父子进程的关系 三、程序管理 1、常见的软件包类型 四、Linux操作系统启动流程详解 1、概述 2、启动流程核心阶段 1…...

SIGGRAPH 2025 | 快手可灵团队提出3D感知的电影级文本到视频生成框架CineMaster

Sora、可灵等视频生成模型令人惊艳的性能表现使得创作者仅依靠文本输入就能够创作出高质量的视频内容。然而&#xff0c;我们常见的电影片段通常是由导演在一个场景中精心布置多个目标的运动、摄像机拍摄角度后再剪辑而成的。例如&#xff0c;在拍摄赛车追逐的场景时&#xff0…...

历年西安电子科技大学计算机保研上机真题

2025西安电子科技大学计算机保研上机真题 2024西安电子科技大学计算机保研上机真题 2023西安电子科技大学计算机保研上机真题 在线测评链接&#xff1a;https://pgcode.cn/school 查找不同的连续数字串个数 题目描述 给定一个数字串&#xff0c;查找其中不同的连续数字串的个…...

利用openwrt路由器和随身WIFI搭建CPE

背景&#xff1a; 最近5GCPE挺火&#xff0c;各种硬件层出不穷&#xff0c;包括DY上很多商家在推的AX3000叠加展锐RM500 5G模块&#xff0c;自己组装CPE&#xff0c;成本也在300 看了下开源硬件&#xff0c;其实就是一个开源的openwrt系统&#xff0c;硬件上5G模块通过usb协议…...

科学智能赋能空间科学研究(2):AI4S 范式下空间科学实验的核心挑战

中国科学院空间应用工程与技术中心在空间科学实验领域的研究覆盖了多模态空间科学实验数据模式挖掘、领域知识抽取、跨学科知识融合与认知智能等研究内容&#xff0c;有效促进了空间科学实验领域的数据应用生态的体系化建设&#xff0c;相关研究成果已正式发表于权威学术期刊《…...

计算机网络学习(九)——CDN

一、CDN CDN&#xff08;Content Delivery Network&#xff0c;内容分发网络&#xff09;是一种通过分布式节点将内容更高效地传递给用户的技术架构&#xff0c;广泛应用于加速网站、视频、下载、直播等业务。 CDN 是把内容放到离用户最近的“高速公路入口”&#xff0c;提升访…...

Axure设计案例——科技感渐变线性图

想让数据变化趋势展示告别枯燥乏味&#xff0c;成为吸引观众目光的亮点吗&#xff1f;快来看看这个Axure设计的科技感渐变线性图案例&#xff01;科技感设计风格凭借炫酷的渐变色彩打破传统线性图的单调&#xff0c;营造出一种令人过目难忘的视觉体验。每一条线条都仿佛是流动的…...

【Opencv+Yolo】Day2_图像处理

目录 一、图像梯度计算 图像梯度-sobal算子&#xff1a; Scharr&#xff1a;权重变化更大&#xff08;线条更加丰富&#xff0c;比Sobel更加细致捕捉更多梯度信息&#xff09; Laplacian算子&#xff1a;对噪音点敏感&#xff08;可以和其他一起结合使用&#xff09; 二、边…...

嵌入式开发学习(第二阶段 C语言笔记)

内存操作 我们对于内存操作需要依赖于string.h头文件中相关的函数库。 内存操作函数 内存填充 头文件&#xff1a;#include <string.h> 函数原型&#xff1a; void* memset(void *s,int c,size_t n)函数功能&#xff1a;将内存块s的前n个字节填充为c&#xff0c;一般…...

STUSB4500 PPS(PD3.0)快充SINK模块——应用 解析

0 前言 朋友参加车展&#xff0c;收获一枚很漂亮的倍思65W氮化镓快充头&#xff0c;送给我了。 我看了手中只支持33W快充的三星陷入了沉思… 快充头支持PPS协议&#xff0c;我心思这玩意适合做可调电源啊&#xff01; 上网随便一查没查到&#xff0c;都是转换成5V、9V、12V等…...

Android全局网络监控最佳实践(Kotlin实现)

本文将介绍如何在Android应用中实现全局网络状态监控&#xff0c;适配高版本API&#xff0c;并提供完整的Kotlin实现方案。 一、核心实现方案 1. 网络监控核心类 SuppressLint("MissingPermission") class NetworkMonitor private constructor(private val contex…...

从认识AI开始-----解密门控循环单元(GRU):对LSTM的再优化

前言 在此之前&#xff0c;我已经详细介绍了RNN和LSTM&#xff0c;RNN虽然在处理序列数据中发挥了重要的作用&#xff0c;但它在实际使用中存在长期依赖问题&#xff0c;处理不了长序列&#xff0c;因为RNN对信息的保存只依赖一个隐藏状态&#xff0c;当序列过长&#xff0c;隐…...

Docker系列(五):ROS容器化三叉戟 --- 从X11、Wayland到DockerFile实战全解析

引言 随着机器人操作系统&#xff08;ROS&#xff09;在机器人领域的广泛应用&#xff0c;容器化技术成为提高开发效率和简化部署的关键。在多种容器化方案中&#xff0c;基于X11、Wayland和标准Dockerfile的ROS容器化方式各有特点&#xff0c;它们在容器内安装ROS1和ROS2的实…...

【位运算】常见位运算总结

位运算 常见位运算总结位1的个数比特位计数汉明距离只出现一次的数字只出现一次的数字 III 常见位运算总结 位1的个数 191. 位1的个数 给定一个正整数 n&#xff0c;编写一个函数&#xff0c;获取一个正整数的二进制形式并返回其二进制表达式中 设置位 的个数&#xff08;也被…...

Delphi 导入excel

Delphi导入Excel的常见方法可分为两种主流方案&#xff1a;基于OLE自动化操作Excel原生接口和利用第三方组件库。以下为具体实现流程及注意事项&#xff1a; ‌一、OLE自动化方案&#xff08;推荐基础场景&#xff09;‌ 该方法通过COM接口调用本地安装的Excel程序&#xff0c…...

5G RedCap是什么-与标准5G的区别及支持路由器推荐

技术背景与重要性 从智能穿戴到工业传感器&#xff0c;物联网设备种类繁多&#xff0c;但并非所有设备都需要标准5G的全部功能。为满足这些中端应用的需求&#xff0c;3GPP在Release 17中引入了5G RedCap&#xff08;Reduced Capability&#xff09;&#xff0c;也称为5G NR-L…...

纯html,js创建一个类似excel的表格

后台是php,表中数据可编辑,可删除,可提交到数据库 <!DOCTYPE html> <html> <head><meta charset="utf-8"><style>body {font-family: Arial, sans-serif;margin: 20px;background-color: #fff;}.toolbar {margin-bottom: 10px;disp…...

如何使用windows下的vscode连接到本地虚拟机的linux

1.打开windows下的vscode 下载下图所示插件 下载完以后打开首选项选择设置搜索ssh 搜索ssh往下滑对下图打上勾 点击下图或者按ctrl shift P 搜索ssh 选择第一个&#xff0c;双击后 进入这个界面 好的window基本配置差不多 2.打开虚拟机 在终端中输入 sudo apt-get install…...

Vue开发系列——零基础HTML引入 Vue.js 实现页面之间传参

目录 一、实现页面之间传参 二、使用 URL 查询参数实现传参(不需要额外引入vue-router) 一、实现页面之间传参 实现从a.html 向b.html传参param1value1, param2value2 二、使用 URL 查询参数实现传参(不需要额外引入vue-router) a.html页面 a.html代码&#xff1a; <!…...

Ubuntu22.04 重装后,串口无响应

欢迎关注公号&#xff1a;每日早参&#xff0c;获取每日最新资讯&#xff01; 1&#xff1a;确认串口设备文件是否存在 在Ubuntu中&#xff0c;串口通常会映射为以下两种 /dev/ttyS*&#xff08;对于传统的串口&#xff09; /fragistics/dev/ttyUSB*&#xff08;对于USB转串口…...

设计模式-发布订阅

文章目录 发布订阅概念发布订阅 vs 监听者例子代码 发布订阅概念 发布/订阅者模式最大的特点就是实现了松耦合&#xff0c;也就是说你可以让发布者发布消息、订阅者接受消息&#xff0c;而不是寻找一种方式把两个分离 的系统连接在一起。当然这种松耦合也是发布/订阅者模式最大…...

C#学习26天:内存优化的几种方法

1.减少对象创建 使用场景&#xff1a; 在循环或密集计算中频繁创建对象时。涉及大量短生命周期对象的场景&#xff0c;比如日志记录或字符串拼接。游戏开发中&#xff0c;需要频繁更新对象状态时。 说明&#xff1a; 重用对象可以降低内存分配和垃圾回收的开销。使用对象池…...

功能测试向量是个什么概念

在半导体测试领域&#xff0c;功能测试向量&#xff08;Functional Test Vector&#xff09; 是一个非常重要的概念。以下是对其的详细解释&#xff1a; 1. 什么是功能测试向量&#xff1f; 功能测试向量是一组输入信号和预期输出信号的集合&#xff0c;用于验证芯片的功能是否…...

C++之string的模拟实现

string 手写C字符串类类的基本结构与成员变量一、构造函数与析构函数二、赋值运算符重载三、迭代器支持四、内存管理与扩容机制五、字符串操作函数六、运算符重载总结 手写C字符串类 从零实现一个简易版std::string 类的基本结构与成员变量 namespace zzh { class string { …...

Python打卡第38天

浙大疏锦行 作业&#xff1a; 了解下cifar数据集&#xff0c;尝试获取其中一张图片 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader , Dataset # DataLoader 是 PyTorch 中用于加载数据的工具 from torchvision im…...

【网络安全】轻量敏感路径扫描工具

订阅专栏,获取文末项目源码。 文章目录 工具简介工具特点项目结构使用方法1.环境准备2.配置目标URL3.运行扫描4.结果查看5.自定义扩展项目源码工具简介 该工具是一款基于Python的异步敏感路径扫描工具,用于检测目标网站是否存在敏感文件或路径泄露(如配置文件、密钥、版本控…...

K8S查看pod资源占用和物理机器IP对应关系

方法1&#xff1a;使用管道组合多个grep kubectl describe node | grep -E "Resource|InternalIP" -A 3方法2&#xff1a;显示节点名称和IP地址的对应关系 kubectl describe node | grep -E "Name:|InternalIP:"方法3&#xff1a;更清晰的格式化输出 ku…...

Java Spring 之拦截器HandlerInterceptor详解与实战

目录 一、拦截器的作用1.1 请求处理前的拦截1.2 请求处理后的拦截1.3 请求完成后的拦截 二、创建拦截器2.1 实现 HandlerInterceptor 接口2.2 注册拦截器 三、拦截器的使用场景3.1 权限校验3.2 日志记录3.3 性能监控 四、总结 在 Spring 框架中&#xff0c;拦截器&#xff08; …...