1、为什么要加水印及缩略图?
给图片加水印可以避免图片被别的网站盗用,并且起到宣传网站的作用。好的水印开发包应该具备的功能:允许设置文字水印;允许设置图片水印;允许轻松设置图片的显示位置;
为大图生成缩略图可以先展示给用户缩略图,提高网页的加载速度并且降低服务器的流量压力。好的缩略图开发包应该具备:处理极端图片(特别大的图片、特别小的图片、特别窄的图片、特别扁的图片),缩略的时候考虑图片裁剪及空白区域填充。
水印、缩略图的功能都可以使用GDI实现,但是自己做太麻烦。我从nuget上扒了很多开发包,其中有Piczard、ImageResizer、ImageProcessor等。下面挨个给大家介绍一下。
测试的时候都用这样一张广告图来做:
2、CodeCarvings.Piczard
项目名称:CodeCarvings.Piczard
NuGet安装指令:Install-Package CodeCarvings.Piczard
官方网站:https://piczard.com/
开源协议:非开源,社区版个人使用及商业使用都免费
可靠程度:2013年最后一次更新,项目较老,但是该有的功能也都有,功能最强大。
Piczard可以对图片进行缩放、缩略图、文字水印、图片水印等处理,而且这些操作可以同时执行。
NuGet安装Piczard后会自动在App.config/Web.config中增加Piczard的节点,那些节点是Piczard提供的简化web开发的一些handler。但是我很讨厌这种做法,还是希望把它当成普通开发包用,自己决定怎么调用,因此像我一样讨厌这种做法的可以把那些节点删掉。
1)文字水印
Piczard最核心的类是ImageProcessingJob,ImageProcessingJob最重要的一个属性就是Filters,可以添加不同的Filter进去,从而实现缩放、缩略图、文字水印、图片水印等不同效果的过滤器进去,很显然可以同时添加多个过滤器。然后调用
SaveProcessedImageToFileSystem、
SaveProcessedImageToStream等方法对图片进行处理、保存。
举一个“文字水印”的例子
ImageProcessingJob jobThumb = new ImageProcessingJob();
TextWatermark txtWM = new TextWatermark();
txtWM.Text = "如鹏网 www.rupeng.com";//水印文字
txtWM.ContentAlignment =
System.Drawing.ContentAlignment.TopLeft;//水印的位置
txtWM.Font.Bold = true;//粗体
txtWM.Font.Italic = true;//斜体
txtWM.Font.Name = "微软雅黑";//字体
txtWM.Font.Size = 30;//文字字体大小
txtWM.ForeColor = System.Drawing.Color.Red;//文字颜色
jobThumb.Filters.Add(txtWM);
jobThumb.SaveProcessedImageToFileSystem(@"D:\temp\1.png", @"d:\temp\2.bmp");
效果如下:
void
SaveProcessedImageToFileSystem(object source, string destFilePath)方法是用来把source代表的原图处理后保存到磁盘上destFilePath这个路径。参数source是object类型的,可以传入String(代表文件路径)、Image、Stream、byte[](代表图片二进制数据)等类型,感觉这样设计很搞笑,作者难道不懂“重载”吗?参数destFilePath为保存文件的路径,方法会根据文件名的后缀自动决定保存的格式,因此如果改成
jobThumb.SaveProcessedImageToFileSystem(@"D:\temp\1.png", @"d:\temp\2.png");就会自动保存成png格式的。
2)其他方法
除了
SaveProcessedImageToFileSystem方法之外,还有其他方法:byte[]
SaveProcessedImageToByteArray(object source)(处理原图source后以byte[]数组返回)、void
SaveProcessedImageToStream(object source, System.IO.Stream destStream) (处理原图source后保存到destStream流中)。
SaveProcessedImageToByteArray、
SaveProcessedImageToStream默认保存是jpeg格式的,由于没有文件名,所以无法猜测保存的格式,可以给第三个参数赋值修改为其他格式,比如
jobThumb.SaveProcessedImageToStream(@"D:\temp\1.png", fsStream,new BmpFormatEncoderParams()); BmpFormatEncoderParams表示是BMP格式的,除此之外还有GifFormatEncoderParams、JpegFormatEncoderParams、PngFormatEncoderParams。
3)图片水印
ImageProcessingJob jobThumb = new ImageProcessingJob();
ImageWatermark imgWM = new ImageWatermark(@"d:\temp\logo.png");//水印logo图,支持背景透明图
imgWM.ContentAlignment =
System.Drawing.ContentAlignment.TopRight;//位置
imgWM.Alpha = 80;//透明度,默认100
jobThumb.Filters.Add(imgWM);
jobThumb.SaveProcessedImageToFileSystem(@"D:\temp\1.png", @"d:\temp\2.png");
运行效果:
4)按指定宽高比生成缩略图
FixedAspectRatioCropConstraint会生成指定宽高比的缩略图,不会导致宽高比失真,但是可能会导致图片显示不全。为了避免用户提交的图片过大或者过小,还可以限制图片的宽高的最大、最小值,对于大图会缩小,对于小图会放大。
ImageProcessingJob jobThumb = new ImageProcessingJob();
FixedAspectRatioCropConstraint constraint1 = new
FixedAspectRatioCropConstraint(1.5f);//宽高比
constraint1.LimitedDimension = SizeDimension.Height;//是限制宽度还是限制高度(Height为限制高度,Width为限制宽度)
constraint1.Min = 50;//最小50像素(根据LimitedDimension确定是限定宽度还是高度)
constraint1.Max = 200;//最大200像素(根据LimitedDimension确定是限定宽度还是高度)
jobThumb.Filters.Add(constraint1);
jobThumb.SaveProcessedImageToFileSystem(@"D:\temp\small.png", @"d:\temp\2.png");
下面是运行结果:
我们会发现图片处理成了指定横纵比的图片,但是图片有被裁减掉的部分。可以设定
constraint1.DefaultImageSelectionStrategy =
CropConstraintImageSelectionStrategy.WholeImage; 来保证显示原图全部内容,不裁剪。
效果如下:
注意如果设定WholeImage,则有可能有白边,因为毕竟又想固定横纵比、又想显示全图,人家只能用白边来填充不足的部分。如果嫌弃白边不好看,可以通过constraint1.CanvasColor =
System.Drawing.Color.Transparent;设置白边为透明背景(当然需要保存为png格式才管用)
5)混合多个Filter
可以把多个Filter加入,实现复合的效果。下面的代码就是缩略图的同时加上水印
ImageProcessingJob jobThumb = new ImageProcessingJob();
FixedAspectRatioCropConstraint constraint1 = new
FixedAspectRatioCropConstraint(1.5f);//宽高比
constraint1.LimitedDimension = SizeDimension.Height;//是限制宽度还是限制高度
constraint1.Min = 50;//最小50像素
constraint1.Max = 200;//最大200像素
//constraint1.CanvasColor = new BackgroundColor(System.Drawing.Color.Transparent);
constraint1.CanvasColor = System.Drawing.Color.Transparent;
constraint1.DefaultImageSelectionStrategy = CropConstraintImageSelectionStrategy.WholeImage;
jobThumb.Filters.Add(constraint1);
TextWatermark txtWM = new TextWatermark();
txtWM.Text = "如鹏网 www.rupeng.com";//水印文字
txtWM.ContentAlignment =
System.Drawing.ContentAlignment.TopLeft;//水印的位置
jobThumb.Filters.Add(txtWM);
jobThumb.SaveProcessedImageToFileSystem(@"D:\temp\1.png", @"d:\temp\2.png");
效果如下:
3、ImageProcessor
项目名称:ImageProcessor
NuGet安装指令:Install-Package ImageProcessor
官方网站:
http://imageprocessor.org/
开源协议:Apache
可靠程度:更新活跃,目前是2.x版。
ImageProcessor支持图片缩放、裁剪、旋转、水印等。而且是Fluent风格的API,这是目前非常流行、方便的编程风格。
下面的代码就是加载1.png,然后从中截取出左上角坐标为(10,20)宽高为100、50的一个区域,然后以Jpeg格式保存到2.jpg中。
ImageFactory fac = new ImageFactory();
fac.Load(@"D:\temp\1.png").Crop(new System.Drawing.Rectangle(10,20,100,50)).Format(new JpegFormat()).Save(@"d:\temp\2.jpg");
这种Fluent风格的API是不是用起来爽多了? 注意Load方法有byte[]、Stream、Image等多个类型的重载,Save方法也支持Stream(流)、string(文件路径)等重载。保存前通过Format方法设定要保存的格式,可选类型有JpegFormat、GifFormat、PngFormat等。
除了Crop这个剪切的方法外,还有Alpha(设置透明度);BackgroundColor(设置背景颜色);Constrain(限定范围);Flip(翻转);Resize(缩放);Rotate(旋转);Watermark(水印)等方法。
水印也支持文字水印(TextLayer)和图片水印(ImageLayer),不过需要通过Position指定水印显示的坐标,如果要把水印显示到右上角或者右下角,需要自己进行坐标计算,没有Piczard的imgWM.ContentAlignment =
System.Drawing.ContentAlignment.TopRight;这种傻瓜化的API。
下面是制作缩略图的方法:
ImageFactory fac = new ImageFactory();
fac.Load(@"D:\temp\1.png").Resize(new ResizeLayer(new System.Drawing.Size(400, 220),ResizeMode.Pad))
.Format(new JpegFormat()).Save(@"d:\temp\2.jpg");
ResizeMode.Pad表示“不改变图片的宽高比”;改成ResizeMode.Stretch则表示对图片进行缩放,因此有可能会失真。
FluentAPI的风格就是“一直点儿下去”,因此可以很轻松实现“缩放、然后加水印、然后宣传、然后***”这样连续的动作,比如下面的代码就是“缩略图,然后加水印,然后旋转30度”,是不是很炫酷
ImageFactory fac = new ImageFactory();
fac.Load(@"D:\temp\1.png").Resize(new ResizeLayer(new System.Drawing.Size(400, 220),ResizeMode.Pad)).Watermark(new TextLayer() { Text="我是水印",
FontSize=20,FontColor=System.Drawing.Color.Purple,Position=new System.Drawing.Point(80,20)})
.Rotate(30)
.Format(new JpegFormat()).Save(@"d:\temp\2.jpg");
要不是ImageProcessor水印的位置需要自己算,如鹏网就首推ImageProcessor而不是Piczard了。毕竟ImageProcessor是开源的,API很漂亮,而Piczard只是免费,不是开源,而且Piczard的dll都是混淆的,API也丑的要死。希望ImageProcessor加油更新,等功能完善以后,如鹏网就推ImageProcessor了。
定期发布技术文章,请点【关注】。