之前写了一个公共的ImgHelper类,主要提供高清晰缩略图生成,由于在之前的实际操作过程中存在一些问题,最近有了点时间,于是重新拾起来再改进一下,顺便研究一下GDI+。

问题一:产品搜索列表展示,每个产品显示的图片大小为100x100,缩略图生成是按比例缩小的,可能为100x100、100x90、90x100、90x90,为了显示美观,我们需要让该图片在100x100的区域垂直、左右居中显示,那么就需要使用样式来控制,这时WEB前端开发人员建议,是否可以给图片加一个透明的背景,即将按比例生成的缩略图放置在一个大小为100x100、背景透明的图片上。

问题二:需要在缩略图上打上水印,包括文字水印、图片水印。

问题三:需要实现文字、图片水印透明。

针对上述三个问题,解决方案如下,看代码:

MakeThumbnailBase

/// <summary>
/// 生成高清晰缩略图基方法,图片按比例大小缩放,可以生成固定大小的图片,不足处以透明背景填充
/// </summary>
/// <param name="image"></param>
/// <param name="newFile"></param>
/// <param name="maxWidth"></param>
/// <param name="maxHeight"></param>
/// <param name="Quality"></param>
/// <param name="FixedSize">当此值为true时,生成固定大小图片时,不足处以透明背景填充</param>
/// <param name="waterMark"></param>
private static void MakeThumbnailBase(System.Drawing.Image image, string newFile, int maxWidth, int maxHeight, int Quality, bool FixedSize, WaterMark waterMark)
{
int OldWidth = image.Width;//图片实际宽度
int OldHeight = image.Height;//图片实际高度
int NewWidth = maxWidth;
int NewHeight = maxHeight;
int x = 0;
int y = 0;

string mode = string.Empty;
if (OldWidth <= NewWidth && OldHeight <= NewHeight)
{
if (FixedSize)
{
x = (maxWidth - OldWidth) / 2;
y = (maxHeight - OldHeight) / 2;
}
NewWidth = OldWidth;
NewHeight = OldHeight;
}
else if (OldWidth > NewWidth && OldHeight < NewHeight)
mode = "W";
else if (OldWidth < NewWidth && OldHeight > NewHeight)
mode = "H";
else if (OldWidth >= NewWidth && OldHeight >= NewHeight)
if (OldWidth * NewHeight > NewWidth * OldHeight)
mode = "W";
else
mode = "H";

switch (mode)
{
case "W"://指定宽,高按比例
NewHeight = OldHeight * NewWidth / OldWidth;
if (FixedSize)
y = (maxHeight - NewHeight) / 2;
break;
case "H"://指定高,宽按比例
NewWidth = OldWidth * NewHeight / OldHeight;
if (FixedSize)
x = (maxWidth - NewWidth) / 2;
break;
}

Bitmap outBmp;
if (FixedSize)
outBmp = new Bitmap(maxWidth, maxHeight);
else
outBmp = new Bitmap(NewWidth, NewHeight);
Graphics g = Graphics.FromImage(outBmp);

// 设置画布描绘质量及背景
g.InterpolationMode = InterpolationMode.High;
g.CompositingQuality = CompositingQuality.HighQuality;
g.SmoothingMode = SmoothingMode.HighQuality;
g.Clear(System.Drawing.Color.Transparent);

//在指定位置并且按指定大小绘制指定的Image的指定部分。
g.DrawImage(image, new System.Drawing.Rectangle(x, y, NewWidth, NewHeight), new System.Drawing.Rectangle(0, 0, OldWidth, OldHeight), GraphicsUnit.Pixel);

#region 添加水印
//添加文字水印(可设文字透明度)
if (waterMark == WaterMark.Both || waterMark == WaterMark.Text)
{
System.Drawing.Font _Font = new System.Drawing.Font(ConfigHelper.GetConfigValue("WaterMarkFontFimily"), (float)Convert.ToDouble(ConfigHelper.GetConfigValue("WaterMarkFontSize")));
//Color.FromArgb(a,r,g,b) 参数说明:a-透明度0-100,100表示不透明; r-红色; g-绿色; b-蓝色
string[] ArrARGB = ConfigHelper.GetConfigValue("WaterMarkARGB").Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
System.Drawing.Brush _Brush = new System.Drawing.SolidBrush(System.Drawing.Color.FromArgb(int.Parse(ArrARGB[0]), int.Parse(ArrARGB[1]), int.Parse(ArrARGB[2]), int.Parse(ArrARGB[3])));

string strWaterMarkText = ConfigHelper.GetConfigValue("WaterMarkText");

//根据字体及字体大小获取字符串所占宽度及高度
SizeF _SizeF = g.MeasureString(strWaterMarkText, _Font);

//设置水印位置
if (FixedSize)
{
x = (maxWidth - NewWidth) / 2;
y = (maxHeight + NewHeight) / 2 - Convert.ToInt32(_SizeF.Height);
}
else
{
y = NewHeight - Convert.ToInt32(_SizeF.Height);
}

g.DrawString(strWaterMarkText, _Font, _Brush, x, y);
}

//添加图片水印(可设图片透明度)
if (waterMark == WaterMark.Both || waterMark == WaterMark.Image)
{
System.Drawing.Image WaterMarkImage = System.Drawing.Image.FromFile(System.Web.HttpContext.Current.Server.MapPath(ConfigHelper.GetConfigValue("WaterMarkImg")));
System.Drawing.Imaging.ImageAttributes _ImageAttributes = new System.Drawing.Imaging.ImageAttributes();

//第四行第四个值用来设置透明度,值越大越不透明: 1为不透明、0为全透明
//正对角线的值分别代表红、绿、蓝、透明度、第五个值也没做太深入研究,想了解ColorMatrix即5x5矩阵可以在网上搜一下,这个矩阵的各个值的设置听说还申请了专利。
float[][] colorMatrixElements = {
new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
new float[] {0.0f, 0.0f, 0.0f, (float)Convert.ToDouble(ConfigHelper.GetConfigValue("WaterMarkImgAlpha")), 0.0f},
new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
};
System.Drawing.Imaging.ColorMatrix colorMatrix = new System.Drawing.Imaging.ColorMatrix(colorMatrixElements);
_ImageAttributes.SetColorMatrix(colorMatrix, System.Drawing.Imaging.ColorMatrixFlag.Default, System.Drawing.Imaging.ColorAdjustType.Bitmap);

//设置水印位置
if (FixedSize)
{
x = (maxWidth + NewWidth - 2 * WaterMarkImage.Width) / 2;
y = (maxHeight + NewHeight - 2 * WaterMarkImage.Height) / 2;
}
else
{
x = NewWidth - WaterMarkImage.Width;
y = NewHeight - WaterMarkImage.Height;
}

g.DrawImage(WaterMarkImage, new System.Drawing.Rectangle(x, y, WaterMarkImage.Width, WaterMarkImage.Height), 0, 0, WaterMarkImage.Width, WaterMarkImage.Height, System.Drawing.GraphicsUnit.Pixel, _ImageAttributes);

WaterMarkImage.Dispose();
_ImageAttributes.Dispose();
}
#endregion

#region 知识补充
//g.DrawArc 绘制一段弧线,它表示由一对坐标、宽度和高度指定的椭圆部分。
//g.DrawBezier 绘制由4个Point结构定义的贝塞尔样条。
//g.DrawBeziers 用Point结构数组绘制一系列贝塞尔样条。
//g.DrawClosedCurve 绘制由Point结构的数组定义的闭合基数样条。
//g.DrawCurve 绘制经过一组指定的Point结构的基数样条。
//g.DrawEllipse 绘制一个由边框(该边框由一对坐标、高度和宽度指定)定义的椭圆。
//g.DrawIcon 在指定坐标处绘制由指定的 Icon 表示的图像。
//g.DrawIconUnstretched 绘制指定的 Icon 表示的图像,而不缩放该图像。
//g.DrawImage 在指定位置并且按原始大小绘制指定的 Image。
//g.DrawImageUnscaled 在由坐标对指定的位置,使用图像的原始物理大小绘制指定的图像。
//g.DrawImageUnscaledAndClipped 在不进行缩放的情况下绘制指定的图像,并在需要时剪辑该图像以适合指定的矩形。
//g.DrawLine 绘制一条连接由坐标对指定的两个点的线条。
//g.DrawLines 绘制一系列连接一组 Point 结构的线段。
//g.DrawPath
//g.DrawPie 绘制一个扇形,该形状由一个坐标对、宽度、高度以及两条射线所指定的椭圆定义。
//g.DrawPolygon 绘制由一组 Point 结构定义的多边形。
//g.DrawRectangle 绘制由坐标对、宽度和高度指定的矩形。
//g.DrawRectangles 绘制一系列由 Rectangle 结构指定的矩形。
//g.DrawString 在指定位置并且用指定的 Brush 和 Font 对象绘制指定的文本字符串.
#endregion

//设置图片压缩质量
EncoderParameters _EncoderParameters = new EncoderParameters(1);
EncoderParameter _EncoderParameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, Quality < 30 ? 100 : Quality);
_EncoderParameters.Param[0] = _EncoderParameter;

//设定图片保存格式(固定大小时必须保存为png图片,否则无法保证背景透明)
ImageCodecInfo _ImageCodecInfo = null;
if (FixedSize)
_ImageCodecInfo = GetImageCodecInfo("PNG");
else
_ImageCodecInfo = GetImageCodecInfo(image.RawFormat.Guid);

//保存图片
if (_ImageCodecInfo == null)
outBmp.Save(newFile, ImageFormat.Png);
else
outBmp.Save(newFile, _ImageCodecInfo, _EncoderParameters);

g.Dispose();
image.Dispose();
outBmp.Dispose();
}

/// <summary>
/// 根据FormatDescription获取ImageCodeInfo
/// </summary>
/// <param name="strFormatDescription"></param>
/// <returns></returns>
private static ImageCodecInfo GetImageCodecInfo(string strFormatDescription)
{
ImageCodecInfo _ImageCodecInfo = null;
ImageCodecInfo[] ArrImageCodecInfo = ImageCodecInfo.GetImageEncoders();
foreach (var obj in ArrImageCodecInfo)
{
if (obj.FormatDescription == strFormatDescription.ToUpper())
{
_ImageCodecInfo = obj;
break;
}
}
return _ImageCodecInfo;
}

/// <summary>
/// 根据Guid获取ImageCodeInfo
/// </summary>
/// <param name="_Guid"></param>
/// <returns></returns>
private static ImageCodecInfo GetImageCodecInfo(Guid _Guid)
{
ImageCodecInfo _ImageCodecInfo = null;
ImageCodecInfo[] ArrImageCodecInfo = ImageCodecInfo.GetImageEncoders();
foreach (var obj in ArrImageCodecInfo)
{
if (obj.FormatID == _Guid)
{
_ImageCodecInfo = obj;
break;
}
}
return _ImageCodecInfo;
}

public enum WaterMark
{
None,
Text,
Image,
Both
}

接下来还会针对在线图片切割做一个实例给大家。

转载于:https://www.cnblogs.com/zengen/archive/2011/01/06/1915066.html

生成高清缩略图; 添加图片、文字水印; 图片、文字水印透明相关推荐

  1. php生成高清缩略图,PHP生成缩略图函数

    /** * 生成缩略图 * @author [email protected] * @param string 源图绝对完整地址{带文件名及后缀名} * @param string 目标图绝对完整地址 ...

  2. Stable Diffusion 生成高清图片

    Stable Diffusion 生成 8K 高清图片 0. 简介 1. 安装 ultimate-upscale-for-automatic1111 插件 2. 安装 4x-UltraSharp 模型 ...

  3. 使用FFmpeg生成高清gif图

    前言 使用FFmpeg能够很方便的给视频片段或GIF加水印,同时还能对选取的片段生成GIF图,但是在使用默认FFmpeg设置情况下,生成的GIF画质很差,有很明显的栅格化现象.如何生成高质量的GIF是 ...

  4. Swift开发小技巧--扫描二维码,二维码的描边与锁定,设置扫描范围,二维码的生成(高清,无码,你懂得!)...

    二维码的扫描,二维码的锁定与描边,二维码的扫描范围,二维码的生成(高清,无码,你懂得!),识别相册中的二维码 扫描二维码用到的三个重要对象的关系,如图: 1.懒加载各种类 // MARK: - 懒加载 ...

  5. 视频转GIF太模糊了吗?我来教你使用FFmpeg生成高清GIF!!!

    有钱能使鬼推磨,昨天40多个阅读,没有一个人给我实在是太惨了,所以,再来个第二弹吧! 那么这次的主题,就是教你如何通过视频生成高清的GIF图片!! 恩,素材就用上次的那个动态收款码吧! 使用FFmpe ...

  6. [计算机视觉] 手把手教你如何生成高清的AprilTag

    官方提供的AprilTag 3系列的所有标签的图像:https://github.com/AprilRobotics/apriltag-imgs 但是当我克隆下来以后,发现里面的AprilTag标签图 ...

  7. 生死看淡,不服就GAN(九)----英伟达力作PGGAN实战,生成高清图片

    一.前言 2017年,NVIDIA Research 网站发布了一篇颇为震撼的GAN论文:Progressive Growing of GANs for Improved Quality, Stabi ...

  8. Jupyter notebook 绘图时,如何生成高清图片?

    来源:凹凸数据 最近有小伙伴问了个问题:如何在jupyter notebook,用Matplotlib画图时能够更"高清"? 今天正好跟大家聊聊,解决办法. 先举个小例子,用 Ma ...

  9. Asp.Net 上传图片并生成高清晰缩略图

    在asp.net中,上传图片功能或者是常用的,生成缩略图也是常用的.baidu或者google,c#的方法也是很多的,但是一用却发现缩略图不清晰啊,缩略图片太大之类的事情,下面是我在处理图片上的代码, ...

最新文章

  1. 开发Eclipse自定义控件
  2. 斯坦福助理教授马腾宇:ML非凸优化很难,如何破?
  3. 75的写的自己情感经历(转贴自天涯社区)
  4. Laravel 清空配置缓存
  5. Nginx location执行顺序和匹配规则
  6. 优麒麟 20.04 LTS 版本发布,UKUI3.0 灵动转身
  7. JavaScript隐式类型转换
  8. JAVA 基础8-面向对象3
  9. iOS开发之模拟器(simulator)的复制粘贴
  10. pdf拆分成一页一页,pdf拆分方法
  11. 项目文件3 项目范围说明书、项目团队派工单、质量控制测量结果、质量测量指标、质量报告、需求文件、需求跟踪矩阵、 资源分解结构
  12. 中国公有云厂商2017年收入利润综合排名
  13. egret 使用frame转载
  14. 解决Latex编译报错 Font shape `TU/ptm/b/n‘ undefined (Font) using ‘TU/ptm/bx/n‘ instead
  15. mac安装php+mysql数据库_Mac环境下Nginx+PHP+MySQL的安装与配置
  16. Len和lenB的区别
  17. Eclipse中怎样将java项目转化为web项目?
  18. 基于mini2440嵌入式linux上整合一套Domoticz智能家居系统(九)使用domoticz+mosquitto+Android客户端实现控制mini2440上的LED(二)
  19. TP-LINK路由器与pfSense建立IPsec连接
  20. Nett源码剖析ServerBootstrap的设置2021SC@SDUSC

热门文章

  1. linux服务器重启ctrl,Linux禁止Ctrl+Alt+Del重启
  2. mysql 批量替换域名_msyql 中批量替换url网址中的域名方案。
  3. burst什么意思_为什么Windows/iOS操作很流畅而Linux/Android却很卡顿呢?
  4. javamail 解码 base64 html格式邮件_[源码和文档分享]基于JavaMail的邮件收发系统
  5. java程序员_哪些书是不可错过的?Java程序员书单分享
  6. RocketMQ(二)——系统架构及基本知识
  7. 无迹卡尔曼滤波(UKF)详解
  8. centos5.9 安装mysql_centos 5.9 安装mysql 5.5.31
  9. java二次指数平滑法预测未来的值
  10. python创建线程在后台运行