首页 > 编程语言 >C#图片处理基本应用(裁剪,缩放,清晰度,水印)

C#图片处理基本应用(裁剪,缩放,清晰度,水印)

时间:2022-12-02 18:36:20浏览次数:45  
标签:原图 缩放 C# System 水印 initHeight initWidth new Drawing

C#图片处理基本应用(裁剪,缩放,清晰度,水印)

前言

需求源自项目中的一些应用,比如相册功能,通常用户上传相片后我们都会针对该相片再生成一张缩略图,用于其它页面上的列表显示。随便看一下,大部分网站基本都是将原图等比缩放来生成缩略图。但完美主义者会发现一些问题,比如显示排版时想让相片缩略图列表非常统一、整齐、和美观,比如要求每张缩略图大小固定为120 x 90且不拉伸变形怎么办?再比如用户头像如何让缩略图比原图更清晰?或是如何在上传的图片下加一个半透明的LOGO水印?

OK,本文根据自己的项目代码描述以上问题的解决方案,全部基于.Net Framework类库完成,代码中包含了C#图片处理的一些基础知识,与大家分享,个人能力有限,不足之处还请及时指正。

提高缩略图清晰度

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_网络应用

(原图200*200,12.3k)

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C++_02

(处理后80*80,17.7k)

之前一直认为缩略图不可能比原图清晰,直到某天一位产品的同事给我看某网站的效果。于是开始寻找.NET下实现代码,仔细观察缩略图确实比原图更清晰了一些,但代价是缩略图文件比原图更大,所以如果你想让一张占满显示器屏幕的超大图片更清晰,那么图片占用空间和网络流量就必需考虑了,如果是互联网应用,建议缩略图在200像素以内的使用该方法。当然如果哪位有更好的代码即能让图片文件大小变化不大又让图片更清晰还请分享。

图片裁剪

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C_03

(原图256*192)

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C#_04

(裁剪要求100*100)

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C_03

(原图256*192)

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C++_06

(裁剪要求90*120)

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C_03

(原图256*192)

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C_08

(裁剪要求120*90)

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C++_09

(原图146*256)

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_互联网_10

(裁剪要求100*100)


C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C++_09

(原图146*256)

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C#_12

(裁剪要求90*120)

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C++_09

(原图146*256)

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C_14

(裁剪要求120*90)

算法:以原图中心作为裁剪中心,最大范围的对原图进行裁剪,然后对裁剪结果等比缩放。

图片水印

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C++_15

C#图片处理基本应用(裁剪,缩放,清晰度,水印)_C++_16

仅演示了效果,如需要变更字体、水印透明度、位置等可自行在代码或方法中扩展。

代码

封装了几个通用的方法,如发现有BUG或漏洞还请及时指正。

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace WuJian.Common
{
/// <summary>
/// 图片处理类
/// 吴剑 2008-07-02 创建
/// 吴剑 2011-01-21 修改
/// </summary>
public class PTImage
{
#region 正方型裁剪并缩放
/// <summary>
/// 正方型裁剪
/// 以图片中心为轴心,截取正方型,然后等比缩放
/// 用于头像处理
/// </summary>
/// <remarks>吴剑 2010-11-23</remarks>
/// <param name="postedFile">原图HttpPostedFile对象</param>
/// <param name="fileSaveUrl">缩略图存放地址</param>
/// <param name="side">指定的边长(正方型)</param>
/// <param name="quality">质量(范围0-100)</param>
public static void CutForSquare(System.Web.HttpPostedFile postedFile, string fileSaveUrl, int side, int quality)
{
//创建目录
string dir = Path.GetDirectoryName(fileSaveUrl);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);

//原始图片(获取原始图片创建对象,并使用流中嵌入的颜色管理信息)
System.Drawing.Image initImage = System.Drawing.Image.FromStream(postedFile.InputStream, true);

//原图宽高均小于模版,不作处理,直接保存
if (initImage.Width <= side && initImage.Height <= side)
{
initImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
}
else
{
//原始图片的宽、高
int initWidth = initImage.Width;
int initHeight = initImage.Height;

//非正方型先裁剪为正方型
if (initWidth != initHeight)
{
//截图对象
System.Drawing.Image pickedImage = null;
System.Drawing.Graphics pickedG = null;

//宽大于高的横图
if (initWidth > initHeight)
{
//对象实例化
pickedImage = new System.Drawing.Bitmap(initHeight, initHeight);
pickedG = System.Drawing.Graphics.FromImage(pickedImage);
//设置质量
pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//定位
Rectangle fromR = new Rectangle((initWidth - initHeight) / 2, 0, initHeight, initHeight);
Rectangle toR = new Rectangle(0, 0, initHeight, initHeight);
//画图
pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
//重置宽
initWidth = initHeight;
}
//高大于宽的竖图
else
{
//对象实例化
pickedImage = new System.Drawing.Bitmap(initWidth, initWidth);
pickedG = System.Drawing.Graphics.FromImage(pickedImage);
//设置质量
pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//定位
Rectangle fromR = new Rectangle(0, (initHeight - initWidth) / 2, initWidth, initWidth);
Rectangle toR = new Rectangle(0, 0, initWidth, initWidth);
//画图
pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
//重置高
initHeight = initWidth;
}

//将截图对象赋给原图
initImage = (System.Drawing.Image)pickedImage.Clone();
//释放截图资源
pickedG.Dispose();
pickedImage.Dispose();
}

//缩略图对象
System.Drawing.Image resultImage = new System.Drawing.Bitmap(side, side);
System.Drawing.Graphics resultG = System.Drawing.Graphics.FromImage(resultImage);
//设置质量
resultG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
resultG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//用指定背景色清空画布
resultG.Clear(Color.White);
//绘制缩略图
resultG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, side, side), new System.Drawing.Rectangle(0, 0, initWidth, initHeight), System.Drawing.GraphicsUnit.Pixel);

//关键质量控制
//获取系统编码类型数组,包含了jpeg,bmp,png,gif,tiff
ImageCodecInfo[] icis = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo ici = null;
foreach (ImageCodecInfo i in icis)
{
if (i.MimeType == "image/jpeg" || i.MimeType == "image/bmp" || i.MimeType == "image/png" || i.MimeType == "image/gif")
{
ici = i;
}
}
EncoderParameters ep = new EncoderParameters(1);
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)quality);

//保存缩略图
resultImage.Save(fileSaveUrl, ici, ep);

//释放关键质量控制所用资源
ep.Dispose();

//释放缩略图资源
resultG.Dispose();
resultImage.Dispose();

//释放原始图片资源
initImage.Dispose();
}
}

/// <summary>
/// 正方型裁剪
/// 以图片中心为轴心,截取正方型,然后等比缩放
/// 用于头像处理
/// </summary>
/// <remarks>吴剑 2010-11-23</remarks>
/// <param name="postedFile">原图HttpPostedFile对象</param>
/// <param name="fileSaveUrl">缩略图存放地址</param>
/// <param name="side">指定的边长(正方型)</param>
/// <param name="quality">质量(范围0-100)</param>
public static void CutForSquare(System.IO.Stream fromFile, string fileSaveUrl, int side, int quality)
{
//创建目录
string dir = Path.GetDirectoryName(fileSaveUrl);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);

//原始图片(获取原始图片创建对象,并使用流中嵌入的颜色管理信息)
System.Drawing.Image initImage = System.Drawing.Image.FromStream(fromFile, true);

//原图宽高均小于模版,不作处理,直接保存
if (initImage.Width <= side && initImage.Height <= side)
{
initImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
}
else
{
//原始图片的宽、高
int initWidth = initImage.Width;
int initHeight = initImage.Height;

//非正方型先裁剪为正方型
if (initWidth != initHeight)
{
//截图对象
System.Drawing.Image pickedImage = null;
System.Drawing.Graphics pickedG = null;

//宽大于高的横图
if (initWidth > initHeight)
{
//对象实例化
pickedImage = new System.Drawing.Bitmap(initHeight, initHeight);
pickedG = System.Drawing.Graphics.FromImage(pickedImage);
//设置质量
pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//定位
Rectangle fromR = new Rectangle((initWidth - initHeight) / 2, 0, initHeight, initHeight);
Rectangle toR = new Rectangle(0, 0, initHeight, initHeight);
//画图
pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
//重置宽
initWidth = initHeight;
}
//高大于宽的竖图
else
{
//对象实例化
pickedImage = new System.Drawing.Bitmap(initWidth, initWidth);
pickedG = System.Drawing.Graphics.FromImage(pickedImage);
//设置质量
pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//定位
Rectangle fromR = new Rectangle(0, (initHeight - initWidth) / 2, initWidth, initWidth);
Rectangle toR = new Rectangle(0, 0, initWidth, initWidth);
//画图
pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
//重置高
initHeight = initWidth;
}

//将截图对象赋给原图
initImage = (System.Drawing.Image)pickedImage.Clone();
//释放截图资源
pickedG.Dispose();
pickedImage.Dispose();
}

//缩略图对象
System.Drawing.Image resultImage = new System.Drawing.Bitmap(side, side);
System.Drawing.Graphics resultG = System.Drawing.Graphics.FromImage(resultImage);
//设置质量
resultG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
resultG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//用指定背景色清空画布
resultG.Clear(Color.White);
//绘制缩略图
resultG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, side, side), new System.Drawing.Rectangle(0, 0, initWidth, initHeight), System.Drawing.GraphicsUnit.Pixel);

标签:原图,缩放,C#,System,水印,initHeight,initWidth,new,Drawing
From: https://blog.51cto.com/u_15834343/5907381

相关文章

  • docker常用
    docker镜像网址https://hub.docker.com/search?q=&type=imagehttps://hub.docker.com/后续......
  • 阿里云如何开放K8S内的SVC给集群外的机器访问
    方法:1.通过Ingress暴露2.通过新建负载均衡SVC通过ingress适用于http协议的暴露,基于7层来实现负载均衡SVC适用于4层协议的暴露,比如nacos、es、数据库等以下是我在工作当中的......
  • 小程序分包放置echarts组件
    app.json"subPackages":[{"root":"commonPackage","pages":[]}],pages同级目录加commonPackage分包中放入echarts组件信息使用xx.js......
  • IDEA与tomcat相关配置以及Servlet_体系结构
    IDEA与tomcat相关配置1.IDEA会为每一个tomcat部署的项目单独建立一份配置文件查看控制台log:UsingCATALINA_BASE:  "C:\Users\齐浩宽\AppData\Local\JetBrains\In......
  • USB Type-C Configuration Channel (CC)引脚功能介绍
    1.插入检测DFP(下行端口)为主机端口,UFP(上行端口)为设备端口。如图所示,在DFP中的CC通道上有上拉电阻,相应的在UFP中有对应的下拉电阻。在DFP与UFP连接之前,VBUS没有输出,当......
  • mac使用
    https://support.apple.com/zh-cn/guide/mac-help/mchlp1236/machttp://t.zoukankan.com/sandea-p-11320708.html......
  • mac安装nginx
    homebrew安装Nginx推荐Mac电脑上内置homebrew工具安装。安装Nginx:brewinstallnginx卸载Nginx:brewuninstallnginxHomebrewHomebrew是一款MacOS平台下的......
  • 【干货】超详细!TPC7062封装MQTT协议教程
    【干货】超详细!TPC7062封装MQTT协议教程一.功能简介通过将报文分解为16进制格式的字符串(比如:101C00044D51545404C2),再通过TPC-7062进行组包,利用串口服务器的TCP/IP协议栈连接......
  • 【JAVA】基于SpringSecurity登录的详细教程
    不知道抽起哪根筋,花了一周的时间终于写了个基于springsecurity的登录的样例,4、5年前在学springboot时曾经按书上的例子却怎么也写不出来,算是了却自己的一桩心愿吧。当然,我不......
  • cmd常用命令
    MicrosoftPowerToys是一组实用工具,可帮助高级用户调整和简化其Windows体验,从而提高工作效率。winver若要确保计算机满足这些要求,请按⊞Win+R,然后键入winver,并按“......