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# 图像处理方面有所帮助,如果你有任何疑问或改进建议,欢迎在评论区交流!

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/85540.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年- H57-Lc165--994.腐烂的橘子(图论,广搜)--Java版

1.题目描述 2.思路 3.代码实现 import java.util.LinkedList; import java.util.Queue;public class H994 {public int orangesRotting(int[][] grid) {//1.获取行数int rowsgrid.length;int colsgrid[0].length;//2.创建队列用于bfsQueue<int[]> quenew LinkedList<…

005 flutter基础,初始文件讲解(4)

书接上回&#xff0c;今天继续完成最后的讲解&#xff1a; class _MyHomePageState extends State<MyHomePage> {int _counter 0;void _incrementCounter() {setState(() {_counter;});}可以看到&#xff0c;这里的_MyHomePageState是一个类&#xff0c;继承于 State&l…

DeepSeek R1开源模型的技术突破与AI产业格局的重构

引言​ 2025年&#xff0c;中国AI企业深度求索&#xff08;DeepSeek&#xff09;推出的开源模型DeepSeek-R1&#xff0c;以低成本、高性能和开放生态为核心特征&#xff0c;成为全球人工智能领域的技术焦点。这一模型不仅通过算法创新显著降低算力依赖&#xff0c;更通过开源策…

轻量级swiper插件推荐

推荐插件列表&#xff08;按体积从小到大排序&#xff09; 1. Embla Carousel 体积&#xff1a;约 5KB (gzipped) 官网&#xff1a;A lightweight carousel library with fluid motion and great swipe precision | Embla Carousel 特点&#xff1a; 极小体积&#xff0c;高…

设计模式——访问者设计模式(行为型)

摘要 访问者设计模式是一种行为型设计模式&#xff0c;它将数据结构与作用于结构上的操作解耦&#xff0c;允许在不修改数据结构的前提下增加新的操作行为。该模式包含关键角色如元素接口、具体元素类、访问者接口和具体访问者类。通过访问者模式&#xff0c;可以在不改变对象…

Vue基础(12)_Vue.js循环语句用法:列表渲染

js补充 术语解释 循环(loop)&#xff1a;最基础的概念, 所有重复的行为。 递归(recursion)&#xff1a; 在函数内调用自身, 将复杂情况逐步转化成基本情况。 (数学)迭代(iterate) &#xff1a;在多次循环中逐步接近结果。 (编程)迭代(iterate) &#xff1a;按顺序访问线性结构中…

Linux入门(十三)动态监控系统监控网络状态

top与ps 命令很相似&#xff0c;它们都是用来显示正在执行的进程&#xff0c;top与ps大的区别是top在执行一段时间可以更新正在运行的进程。 #-d 更新秒数 如果不写-d 那默认是3秒更新 # -i 隐藏不活跃进程 top -d 5交互操作 P 按cpu使用大小排序&#xff0c;默认此项 M 按内存…

Java 中 MySQL 索引深度解析:面试核心知识点与实战

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Java 中 MySQL 索引深度解析&#xff1a;面试…

Kafka集成Flume/Spark/Flink(大数据)/SpringBoot

Kafka集成Flume Flume生产者 ③、安装Flume&#xff0c;上传apache-flume的压缩包.tar.gz到Linux系统的software&#xff0c;并解压到/opt/module目录下&#xff0c;并修改其名称为flume Flume消费者 Kafka集成Spark 生产者 object SparkKafkaProducer{def main(args:Array[S…

debian12.9或ubuntu,vagrant离线安装插件vagrant-libvirt,20250601

系统盘: https://mirror.lzu.edu.cn/debian-cd/12.9.0/amd64/iso-dvd/debian-12.9.0-amd64-DVD-1.iso 需要的依赖包,无需安装ruby( sudo apt install -y ruby-full ruby-dev rubygems,后来发现不安装会有编译警告,还是安装吧 ) ,无需安装 zlib1g-dev liblzma-dev libxml2-de…

2025年软件测试面试八股文(含答案+文档)

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 Part1 1、你的测试职业发展是什么&#xff1f; 测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师…

[CSS3]响应式布局

导读 响应式就是一套代码, 兼容大中小不同的屏幕, 即网页内容不变, 网页布局随屏幕切换而改变 媒体查询 响应式布局的核心技术是媒体查询 媒体查询可以检测屏幕尺寸, 设置差异化的css 开发中的常用写法 使用范围属性, 划定屏幕范围 max-width 最大宽度min-width 最小宽度 …

在 Windows安装 make 的几种方式

在 Windows 上使用 make&#xff08;通常用于自动化构建 C/C 项目等&#xff09;有几种方法。以下是最常见的几种安装和使用方法&#xff1a; 文章目录 ✅ 方法一&#xff1a;使用 Chocolatey 安装 GNU Make&#xff08;推荐&#xff09;✅ 方法二&#xff1a;使用 WSL&#xf…

深度学习笔记25-RNN心脏病预测(Pytorch)

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、前期准备 1.数据处理 import torch.nn.functional as F import numpy as np import pandas as pd import torch from torch import nn dfpd.read_csv(r&…

Pytorch知识点2

Pytorch知识点 1、官方教程2、张量&#x1f9f1; 0、数组概念&#x1f9f1; 1. 创建张量&#x1f4d0; 2. 张量形状与维度&#x1f522; 3. 张量数据类型➗ 4. 张量的数学与逻辑操作&#x1f504; 5. 张量的就地操作&#x1f4e6; 6. 复制张量&#x1f680; 7. 将张量移动到加速…

池中锦鲤的自我修养,聊聊蓄水池算法

面试如泡池&#xff0c;蓄水似人生 起初你满怀期待跳进大厂池子&#xff0c;以为自己是天选之子&#xff0c;结果发现池子里早挤满了和你一样的“锦鲤候选人”。HR的渔网一撒&#xff0c;捞谁全看概率——这不就是蓄水池算法的精髓吗&#xff1f; 初入池&#xff08;i≤k&…

Linux应用开发之网络套接字编程

套接字&#xff08;Socket&#xff09;是计算机网络数据通信的基本概念和编程接口&#xff0c;允许不同主机上的进程&#xff08;运行中的程序&#xff09;通过网络进行数据交换。它为应用层软件提供了发送和接收数据的能力&#xff0c;使得开发者可以在不用深入了解底层网络细…

小白的进阶之路系列之六----人工智能从初步到精通pytorch数据集与数据加载器

本文将介绍以下内容: 数据集与数据加载器 数据迁移 如何建立神经网络 数据集与数据加载器 处理数据样本的代码可能会变得混乱且难以维护;理想情况下,我们希望我们的数据集代码与模型训练代码解耦,以获得更好的可读性和模块化。PyTorch提供了两个数据原语:torch.utils…

深入理解设计模式之中介者模式

深入理解设计模式之&#xff1a;中介者模式&#xff08;Mediator Pattern&#xff09; 一、什么是中介者模式&#xff1f; 中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为型设计模式。它通过引入一个中介对象&#xff0c;来封装一组对象之间的交互&#xff0…

基于通义千问的儿童陪伴学习和成长的智能应用架构。

1.整体架构概览 我们的儿童聊天助手将采用典型的语音交互系统架构,结合大模型能力和外部知识库: 2. 技术方案分解 2.1. 前端应用/设备 选择: 移动App(iOS/Android)、Web应用,或者集成到智能音箱/平板等硬件设备中。技术栈: 移动App: React Native / Flutter (跨平台…