使用ASP.net(C#)批量上传图片并自动生成缩略图,文字水印图,图片水印图
本程序主要功能有:
(1)可以根据自己的需要更改上传到服务器上的目录,上传的源图、缩略图、文字水印图和图片水印图分别存入所定目录下的不同目录;
(2)自动检查目录,如无所选择的目录,则自动创建它们;
(3)自行设定生成缩略图的大小;
(4)可以选择是否需要生成文字水印、图片水印,默认为不生成水印图;
(5)可以添加、删除所需上传的图片。
在本程序中均加了相关注释,所以直接发代码,不再多作解释。
using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; using System.IO; using System.Net; using System.Text.RegularExpressions;
/// 〈summary> /// FileUpload1.HasFile 如果是true,则表示该控件有文件要上传 /// FileUpload1.FileName 返回要上传文件的名称,不包含路径信息 /// FileUpload1.FileContent 返回一个指向上传文件的流对象 /// FileUpload1.PostedFile 返回已经上传文件的引用 /// FileUpload1.PostedFile.ContentLength 返回上传文件的按字节表示的文件大小 /// FileUpload1.PostedFile.ContentType 返回上传文件的MIME内容类型,也就是文件类型,如返回"image/jpg" /// FileUpload1.PostedFile.FileName 返回文件在客户端的完全路径(包括文件名全称) /// FileUpload1.PostedFile.InputStream 返回一个指向上传文件的流对象 /// FileInfo对象表示磁盘或网络位置上的文件。提供文件的路径,就可以创建一个FileInfo对象: /// 〈/summary>public partial class BackManagement_ImagesUpload : System.Web.UI.Page { public string treePath = "" ; public int imageW = 100; public int imageH = 100; protected void Page_Load( object sender, EventArgs e) { this .Button5.Attributes.Add( "Onclick" , "window.close();" ); //在本地关闭当前页,而不需要发送到服务器去关闭当前页时 if (!Page.IsPostBack) { Label2.Text = Server.MapPath( "/" ); TextBox3.Text = "ImageUpload" ; treePath = Server.MapPath( "/" ) + TextBox3.Text.Trim() + "/" ; TextBox4.Text = imageW.ToString(); TextBox5.Text = imageH.ToString(); } } protected void btnload_Click( object sender, EventArgs e) { //如果保存图片的目录不存在,由创建它 treePath = Server.MapPath( "/" ) + TextBox3.Text.Trim() + "/" ; imageW = Convert.ToInt32(TextBox4.Text.ToString()); imageH = Convert.ToInt32(TextBox5.Text.ToString()); if (!File.Exists(treePath + "images" )) //如果/ImageUpload/images不存在,则创建/ImageUpload/images,用于存放源图片 { System.IO.Directory.CreateDirectory(treePath + "images" ); } if (!File.Exists(treePath + "thumbnails" )) //如果/ImageUpload/thumbnails不存在,则创建/ImageUpload/thumbnails,用于存放缩略图片 { System.IO.Directory.CreateDirectory(treePath + "thumbnails" ); } if (!File.Exists(treePath + "textImages" )) //如果/ImageUpload/textImages不存在,则创建/ImageUpload/textImages,用于存文字水印图片 { System.IO.Directory.CreateDirectory(treePath + "textImages" ); } if (!File.Exists(treePath + "waterImages" )) //如果/ImageUpload/waterImages不存在,则创建/ImageUpload/waterImages,用于存图形水印图片 { System.IO.Directory.CreateDirectory(treePath + "waterImages" ); }if (FileUpload1.HasFile) //如果是true,则表示该控件有文件要上传 { string fileContentType = FileUpload1.PostedFile.ContentType; if (fileContentType == "image/bmp" || fileContentType == "image/gif" || fileContentType == "image/pjpeg" ) { string name = FileUpload1.PostedFile.FileName; //返回文件在客户端的完全路径(包括文件名全称)FileInfo file = new FileInfo(name); //FileInfo对象表示磁盘或网络位置上的文件。提供文件的路径,就可以创建一个FileInfo对象: string fileName = file.Name; // 文件名称 string fileName_s = "x_" + file.Name; // 缩略图文件名称 string fileName_sy = "text_" + file.Name; // 水印图文件名称(文字) string fileName_syp = "water_" + file.Name; // 水印图文件名称(图片)string webFilePath = treePath + "images/" + fileName; // 服务器端文件路径 string webFilePath_s = treePath + "thumbnails/" + fileName_s; // 服务器端缩略图路径 string webFilePath_sy = treePath + "textImages/" + fileName_sy; // 服务器端带水印图路径(文字) string webFilePath_syp = treePath + "waterImages/" + fileName_syp; // 服务器端带水印图路径(图片) string webFilePath_sypf = Server.MapPath( "../images/tzwhx.png" ); // 服务器端水印图路径(图片) if (!File.Exists(webFilePath)) { try { FileUpload1.SaveAs(webFilePath); // 使用 SaveAs 方法保存文件 if (CheckBox1.Checked) //是否生成文字水印图 { AddWater(webFilePath, webFilePath_sy); } if (CheckBox2.Checked) //是否生成图形水印图 { AddWaterPic(webFilePath, webFilePath_syp, webFilePath_sypf); } MakeThumbnail(webFilePath, webFilePath_s, imageW, imageH, "Cut" ); // 生成缩略图方法 Label1.Text = "提示:文件“" + fileName + "”成功上传,并生成“" + fileName_s + "”缩略图,文件类型为:" + FileUpload1.PostedFile.ContentType + ",文件大小为:" + FileUpload1.PostedFile.ContentLength + "B" ; Image1.ImageUrl = "/" + TextBox3.Text.ToString() + "/images/" + fileName; TextBox1.Text = webFilePath; TextBox2.Text = "/" + TextBox3.Text.ToString() + "/images/" + fileName; } catch (Exception ex) { Label1.Text = "提示:文件上传失败,失败原因:" + ex.Message; } } else { Label1.Text = "提示:文件已经存在,请重命名后上传" ; } } else { Label1.Text = "提示:文件类型不符" ; } } } /**/ /// 〈summary> /// 生成缩略图 /// 〈/summary> /// 〈param name="originalImagePath">源图路径(物理路径)〈/param> /// 〈param name="thumbnailPath">缩略图路径(物理路径)〈/param> /// 〈param name="width">缩略图宽度〈/param> /// 〈param name="height">缩略图高度〈/param> /// 〈param name="mode">生成缩略图的方式〈/param> public static void MakeThumbnail( string originalImagePath, string thumbnailPath, int width, int height, string mode) { System.Drawing.Image originalImage = System.Drawing.Image.FromFile(originalImagePath);int towidth = width; int toheight = height;int x = 0; int y = 0; int ow = originalImage.Width; int oh = originalImage.Height;switch (mode) { case "HW" : //指定高宽缩放(可能变形) break ; case "W" : //指定宽,高按比例 toheight = originalImage.Height * width / originalImage.Width; break ; case "H" : //指定高,宽按比例 towidth = originalImage.Width * height / originalImage.Height; break ; case "Cut" : //指定高宽裁减(不变形) if (( double )originalImage.Width / ( double )originalImage.Height > ( double )towidth / ( double )toheight){oh = originalImage.Height;ow = originalImage.Height * towidth / toheight;y = 0;x = (originalImage.Width - ow) / 2;}else { ow = originalImage.Width; oh = originalImage.Width * height / towidth; x = 0; y = (originalImage.Height - oh) / 2; } break ; default : break ; }//新建一个bmp图片 System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);//新建一个画板 System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);//设置高质量插值法 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;//设置高质量,低速度呈现平滑程度 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;//清空画布并以透明背景色填充 g.Clear(System.Drawing.Color.Transparent);//在指定位置并且按指定大小绘制原图片的指定部分 g.DrawImage(originalImage, new System.Drawing.Rectangle(0, 0, towidth, toheight), new System.Drawing.Rectangle(x, y, ow, oh), System.Drawing.GraphicsUnit.Pixel);try { //以jpg格式保存缩略图 bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Jpeg); } catch (System.Exception e) { throw e; } finally { originalImage.Dispose(); bitmap.Dispose(); g.Dispose(); } }/**/ /// 〈summary> /// 在图片上增加文字水印 /// 〈/summary> /// 〈param name="Path">原服务器图片路径〈/param> /// 〈param name="Path_sy">生成的带文字水印的图片路径〈/param> protected void AddWater( string Path, string Path_sy) { string addText = "www.tzwhx.com" ; System.Drawing.Image image = System.Drawing.Image.FromFile(Path); System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(image); g.DrawImage(image, 0, 0, image.Width, image.Height); System.Drawing.Font f = new System.Drawing.Font( "Verdana" , 10); //字体位置为左空10 System.Drawing.Brush b = new System.Drawing.SolidBrush(System.Drawing.Color.Green);g.DrawString(addText, f, b, 14, 14); //字体大小为14X14 g.Dispose();image.Save(Path_sy); image.Dispose(); }/**/ /// 〈summary> /// 在图片上生成图片水印 /// 〈/summary> /// 〈param name="Path">原服务器图片路径〈/param> /// 〈param name="Path_syp">生成的带图片水印的图片路径〈/param> /// 〈param name="Path_sypf">水印图片路径〈/param> protected void AddWaterPic( string Path, string Path_syp, string Path_sypf) { System.Drawing.Image image = System.Drawing.Image.FromFile(Path); System.Drawing.Image copyImage = System.Drawing.Image.FromFile(Path_sypf); System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(image); g.DrawImage(copyImage, new System.Drawing.Rectangle(image.Width - copyImage.Width, image.Height - copyImage.Height, copyImage.Width, copyImage.Height), 0, 0, copyImage.Width, copyImage.Height, System.Drawing.GraphicsUnit.Pixel); g.Dispose();image.Save(Path_syp); image.Dispose(); }protected void Button2_Click( object sender, EventArgs e) { //自动保存远程图片 WebClient client = new WebClient(); //备用Reg:〈img.*?src=([\"\'])(http:\/\/.+\.(jpg|gif|bmp|bnp))\1.*?> Regex reg = new Regex( "IMG[^>]*?src\\s*=\\s*(?:\"(?〈1>[^\"]*)\"|'(?〈1>[^\']*)')" , RegexOptions.IgnoreCase); MatchCollection m = reg.Matches(TextBox1.Text);foreach (Match math in m) { string imgUrl = math.Groups[1].Value;//在原图片名称前加YYMMDD重名名并上传Regex regName = new Regex(@ "\w+.(?:jpg|gif|bmp|png)" , RegexOptions.IgnoreCase);string strNewImgName = DateTime.Now.ToShortDateString().Replace( "-" , "" ) + regName.Match(imgUrl).ToString();try { //保存图片 //client.DownloadFile(imgUrl, Server.MapPath("../ImageUpload/Auto/" + strNewImgName)); } catch { } finally {}client.Dispose(); }Response.Write( "〈script>alert('远程图片保存成功,保存路径为ImageUpload/auto')〈/script>" ); } } 另外,为解决大文件上传的限制,你必须在Web.config中加入以下代码。< system.web> < httpRuntime executionTimeout= "90" maxRequestLength= "20000" useFullyQualifiedRedirectUrl= "false" requestLengthDiskThreshold= "8192" /> < /system.web>
对上传图片 水印分析 图片上传函数,进行判断是否加水印,做出两种处理方式:加水印的函数如下: 填加图片函数,需要下面两个函数的支持,当然也可以写到一起,不过那看起来就很冗长了。1
/// <summary> 2
/// 上传图片代码 3
/// </summary> 4
/// <param name="image_file">HtmlInputFile控件</param> 5
/// <param name="ImgPath">存放的文件夹绝对位置</param> 6
/// <param name="ImgLink">生成的图片的名称带后缀</param> 7
/// <returns></returns> 8
public bool UpPic(System.Web.UI.HtmlControls.HtmlInputFile image_file,string ImgPath,string ImgLink ) 9
{10
if(image_file.PostedFile.FileName!=null && image_file.PostedFile.FileName.Trim()!="")11
{12
try 13
{14
if( !System.IO.Directory.Exists(ImgPath))15
{16
System.IO.Directory.CreateDirectory( ImgPath);17
} 18
//生成缩略图 this.GreateMiniImage((ImgPath+ "\\"+"old_"+ImgLink),(ImgPath+ "\\"+"mini_"+ImgLink),50,50);19
//如果显示水印20
if(ShowWatermark)21
{22
image_file.PostedFile.SaveAs(ImgPath+ "\\" +"old_"+ImgLink);23
//加水印 24
this.addWaterMark((ImgPath+ "\\"+"old_"+ImgLink),(ImgPath+ "\\"+ImgLink));25
26
27
28
} 29
else 30
{31
image_file.PostedFile.SaveAs(ImgPath+ "\\" +ImgLink);32
33
34
} 35
return true;36
} 37
38
catch 39
{40
return false;41
} 42
} 43
else 44
45
{46
return false;47
} 48
49
}
1
/// <summary> 2
/// 添加图片水印 3
/// </summary> 4
/// <param name="oldpath">原图片绝对地址</param> 5
/// <param name="newpath">新图片放置的绝对地址</param> 6
private void addWaterMark(string oldpath,string newpath) 7
8
{ 9
try 10
{11
12
System.Drawing.Image image = System.Drawing.Image.FromFile(oldpath);13
14
Bitmap b = new Bitmap(image.Width, image.Height,PixelFormat.Format24bppRgb);15
Graphics g = Graphics.FromImage(b);16
g.Clear(Color.White);17
g.SmoothingMode = SmoothingMode.HighQuality;18
g.InterpolationMode = InterpolationMode.High;19
20
g.DrawImage(image, 0, 0, image.Width, image.Height);21
22
if(如果需要填加水印)23
{24
switch(水印类型)25
{ 26
//是图片的话 case "WM_IMAGE":27
this.addWatermarkImage( g,Page.Server.MapPath(Watermarkimgpath),WatermarkPosition,image.Width,image.Height); 28
break; 29
//如果是文字 case "WM_TEXT": 30
this.addWatermarkText( g, WatermarkText,WatermarkPosition 31
,image.Width,image.Height); 32
break; 33
} 34
35
b.Save(newpath);36
b.Dispose();37
image.Dispose();38
} 39
40
} 41
catch 42
{43
44
if(File.Exists(oldpath))45
{46
File.Delete(oldpath);47
} 48
} 49
finally 50
{51
52
if(File.Exists(oldpath))53
{54
File.Delete(oldpath);55
} 56
57
58
} 59
60
61
62
63
64
65
}
//代码已经修改,可以按比率还填加图片水印,不过如果背景图片和水印图片太不成比率的话(指水印图片要大于背景图片的1/4),出来的效果不是很好。1
/// <summary> 2
/// 加水印文字 3
/// </summary> 4
/// <param name="picture">imge 对象</param> 5
/// <param name="_watermarkText">水印文字内容</param> 6
/// <param name="_watermarkPosition">水印位置</param> 7
/// <param name="_width">被加水印图片的宽</param> 8
/// <param name="_height">被加水印图片的高</param> 9
private void addWatermarkText( Graphics picture,string _watermarkText,string _watermarkPosition,int _width,int _height)10
{11
int[] sizes = new int[]{16,14,12,10,8,6,4};12
Font crFont = null;13
SizeF crSize = new SizeF();14
for (int i=0 ;i<7; i++)15
{16
crFont = new Font("arial", sizes[i], FontStyle.Bold);17
crSize = picture.MeasureString(_watermarkText, crFont);18
19
if((ushort)crSize.Width < (ushort)_width)20
break;21
} 22
23
float xpos = 0;24
float ypos = 0;25
26
switch(_watermarkPosition)27
{28
case "WM_TOP_LEFT":29
xpos = ((float)_width * (float).01) + (crSize.Width / 2);30
ypos = (float)_height * (float).01;31
break;32
case "WM_TOP_RIGHT":33
xpos = ((float)_width * (float).99) - (crSize.Width / 2);34
ypos = (float)_height * (float).01;35
break;36
case "WM_BOTTOM_RIGHT":37
xpos = ((float)_width * (float).99) - (crSize.Width / 2);38
ypos = ((float)_height * (float).99) - crSize.Height;39
break;40
case "WM_BOTTOM_LEFT":41
xpos = ((float)_width * (float).01) + (crSize.Width / 2);42
ypos = ((float)_height * (float).99) - crSize.Height;43
break;44
} 45
46
StringFormat StrFormat = new StringFormat();47
StrFormat.Alignment = StringAlignment.Center;48
49
SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(153, 0, 0,0));50
picture.DrawString(_watermarkText, crFont, semiTransBrush2, xpos+1, ypos+1, StrFormat);51
52
SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));53
picture.DrawString(_watermarkText, crFont, semiTransBrush, xpos, ypos, StrFormat);54
55
56
semiTransBrush2.Dispose();57
semiTransBrush.Dispose();58
59
60
61
}
1
/// <summary> 2
/// 加水印图片 3
/// </summary> 4
/// <param name="picture">imge 对象</param> 5
/// <param name="WaterMarkPicPath">水印图片的地址</param> 6
/// <param name="_watermarkPosition">水印位置</param> 7
/// <param name="_width">被加水印图片的宽</param> 8
/// <param name="_height">被加水印图片的高</param> 9
private void addWatermarkImage( Graphics picture,string WaterMarkPicPath,string _watermarkPosition,int _width,int _height) 10
{ 11
Image watermark = new Bitmap(WaterMarkPicPath); 12
13
ImageAttributes imageAttributes = new ImageAttributes(); 14
ColorMap colorMap = new ColorMap(); 15
16
colorMap.OldColor = Color.FromArgb(255, 0, 255, 0); 17
colorMap.NewColor = Color.FromArgb(0, 0, 0, 0); 18
ColorMap[] remapTable = {colorMap}; 19
20
imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap); 21
22
float[][] colorMatrixElements = { 23
new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 24
new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f}, 25
new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, 26
new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f}, 27
new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f} 28
}; 29
30
ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements); 31
32
imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); 33
34
int xpos = 0; 35
int ypos = 0; 36
int WatermarkWidth=0; 37
int WatermarkHeight=0; 38
double bl=1d; 39
//计算水印图片的比率 40
//取背景的1/4宽度来比较 41
if((_width>watermark.Width*4)&&(_height>watermark.Height*4)) 42
{ 43
bl=1; 44
} 45
else if((_width>watermark.Width*4)&&(_height<watermark.Height*4)) 46
{ 47
bl=Convert.ToDouble(_height/4)/Convert.ToDouble(watermark.Height); 48
49
}else 50
51
if((_width<watermark.Width*4)&&(_height>watermark.Height*4)) 52
{ 53
bl=Convert.ToDouble(_width/4)/Convert.ToDouble(watermark.Width); 54
} 55
else 56
{ 57
if((_width*watermark.Height)>(_height*watermark.Width)) 58
{ 59
bl=Convert.ToDouble(_height/4)/Convert.ToDouble(watermark.Height); 60
61
} 62
else 63
{ 64
bl=Convert.ToDouble(_width/4)/Convert.ToDouble(watermark.Width); 65
66
} 67
68
} 69
70
WatermarkWidth=Convert.ToInt32(watermark.Width*bl); 71
WatermarkHeight=Convert.ToInt32(watermark.Height*bl); 72
73
74
75
switch(_watermarkPosition) 76
{ 77
case "WM_TOP_LEFT": 78
xpos = 10; 79
ypos = 10; 80
break; 81
case "WM_TOP_RIGHT": 82
xpos = _width - WatermarkWidth - 10; 83
ypos = 10; 84
break; 85
case "WM_BOTTOM_RIGHT": 86
xpos = _width - WatermarkWidth - 10; 87
ypos = _height -WatermarkHeight - 10; 88
break; 89
case "WM_BOTTOM_LEFT": 90
xpos = 10; 91
ypos = _height - WatermarkHeight - 10; 92
break; 93
} 94
95
picture.DrawImage(watermark, new Rectangle(xpos, ypos, WatermarkWidth, WatermarkHeight), 0, 0, watermark.Width, watermark.Height, GraphicsUnit.Pixel, imageAttributes); 96
97
98
watermark.Dispose(); 99
imageAttributes.Dispose();100
}
C#上传图片加水印、缩放、裁剪【下】
接上文:http://csssky.blog.163.com/blog/static/188798121201110492644214/
生成缩略图函数1
2
/// <summary> 3
/// 生成缩略图 4
/// </summary> 5
/// <param name="oldpath">原图片地址</param> 6
/// <param name="newpath">新图片地址</param> 7
/// <param name="tWidth">缩略图的宽</param> 8
/// <param name="tHeight">缩略图的高</param> 9
private void GreateMiniImage(string oldpath,string newpath,int tWidth, int tHeight)10
{11
12
try 13
{14
15
System.Drawing.Image image = System.Drawing.Image.FromFile(oldpath);16
double bl=1d;17
if((image.Width<=image.Height)&&(tWidth>=tHeight))18
{19
bl=Convert.ToDouble(image.Height)/Convert.ToDouble(tHeight);20
} 21
else if((image.Width>image.Height)&&(tWidth<tHeight))22
{23
bl=Convert.ToDouble(image.Width)/Convert.ToDouble(tWidth);24
25
} 26
else 27
28
if((image.Width<=image.Height)&&(tWidth<=tHeight))29
{30
if(image.Height/tHeight>=image.Width/tWidth)31
{32
bl=Convert.ToDouble(image.Width)/Convert.ToDouble(tWidth);33
34
} 35
else 36
{37
bl=Convert.ToDouble(image.Height)/Convert.ToDouble(tHeight);38
} 39
} 40
else 41
{42
if(image.Height/tHeight>=image.Width/tWidth)43
{44
bl=Convert.ToDouble(image.Height)/Convert.ToDouble(tHeight);45
46
} 47
else 48
{49
bl=Convert.ToDouble(image.Width)/Convert.ToDouble(tWidth);50
51
} 52
53
} 54
55
56
Bitmap b = new Bitmap(image ,Convert.ToInt32(image.Width/bl), Convert.ToInt32(image.Height/bl));57
58
b.Save(newpath);59
b.Dispose();60
image.Dispose();61
62
63
} 64
catch 65
{66
67
68
} 69
70
}
以下是图片水印,缩放,剪裁处理
[C#]代码
001 using System;
002 using System.Linq;
003 using System.Collections.Generic;
004 using System.Drawing;
005 using System.Drawing.Drawing2D;
006 using System.Drawing.Imaging;
007
008
009 public static class Imager
010 {
011 public static void Save(Image img, string path)
012 {
013 Save(img, path, ImgCodes.JPEG, 90);
014 }
015
016 public static void Save(Image img, string path, ImgCodes code, int quality)
017 {
018 var qualityParam = new EncoderParameter(Encoder.Quality, quality);
019 var codecInfo = GetCodeInfo(code);
020 var encoderParams = new EncoderParameters(1);
021 encoderParams.Param[0] = qualityParam;
022 img.Save(path, codecInfo, encoderParams);
023 }
024
025 public static Image Resize(Image source, ResizeTypes resizeType, int width, int height)
026 {
027 ResizeModel model = new ResizeModel();
028 model.Source = source;
029 model.ResizeType = resizeType;
030 model.Width = width;
031 model.Height = height;
032 return Resize(model);
033 }
034
035 public static Image Resize(ResizeModel model)
036 {
037 int srcWidth, srcHeight, destWidth, destHeight, cutWidth, cutHeight, x, y;
038
039 #region 初始化变量
040 x = model.StartX;
041 y = model.StartY;
042 cutWidth = srcWidth = model.Source.Width;
043 cutHeight = srcHeight = model.Source.Height;
044 destWidth = model.Width;
045 destHeight = model.Height;
046 #endregion
047
048 #region 确定画布大小及裁剪尺寸
049 switch (model.ResizeType)
050 {
051 case ResizeTypes.Auto:
052 GetFinalSize(model.Width, model.Height, srcWidth, srcHeight, out destWidth, out destHeight);
053 break;
054 case ResizeTypes.Cut:
055 #region 裁剪算法
056 double srcProportion = (double)srcWidth / srcHeight;
057 double destProportion = (double)model.Width / model.Height;
058
059 bool autoCut = x == -1 && y == -1;
060
061 if (srcProportion >= destProportion)
062 {
063 //高瘦,固定高度,求宽度
064 cutWidth = (int)Math.Floor(srcHeight * destProportion);
065 if (autoCut) x += (srcWidth - cutWidth) / 2;
066 }
067 else
068 {
069 //矮胖,固定宽度,球高度
070 cutHeight = (int)Math.Floor(srcWidth / destProportion);
071 if (autoCut) y += (srcHeight - cutHeight) / 2;
072 }
073
074 if (x + cutWidth > srcWidth)
075 {
076 cutWidth = srcWidth - x;
077 }
078
079 if (y + cutHeight > srcHeight)
080 {
081 cutHeight = srcHeight - y;
082 }
083 #endregion
084 break;
085 case ResizeTypes.FixedHeight:
086 GetFinalSize(model.Width, model.Height, srcHeight - 1, srcHeight, out destWidth, out destHeight);
087 break;
088 case ResizeTypes.FixedWidth:
089 GetFinalSize(model.Width, model.Height, srcWidth, srcWidth - 1, out destWidth, out destHeight);
090 break;
091 default:
092 break;
093 }
094 #endregion
095
096 Image imgResult = new Bitmap(destWidth, destHeight);//结果对象
097
098 using (var g = Graphics.FromImage(imgResult))
099 {
100 g.Clear(Color.White);
101 g.InterpolationMode = InterpolationMode.HighQualityBicubic;
102 g.SmoothingMode = SmoothingMode.HighQuality;
103 //g.PixelOffsetMode = PixelOffsetMode.HighQuality;
104 g.CompositingQuality = CompositingQuality.HighQuality;
105
106 Rectangle destRect = new Rectangle(0, 0, destWidth, destHeight);
107 Rectangle srcRect = new Rectangle(x, y, cutWidth, cutHeight);
108
109 g.DrawImage(model.Source, destRect, srcRect, GraphicsUnit.Pixel);
110
111 if (model.IsWartermarked)//是否加水印
112 {
113 Image warterMark = model.ImageWartermark;
114 bool doImageWartermark = (null != warterMark
115 && warterMark.Width < destWidth / 3
116 && warterMark.Height < destHeight / 3);//能否图片水印
117
118 if (doImageWartermark)
119 {
120 #region 图片水印
121 GetWatermarkPlacement(WatermarkPositions.BottomLeft, g.DpiX, g.DpiY, destWidth, destHeight, warterMark, out x, out y);
122
123 /*
124 ImageAttributes ia = new ImageAttributes();
125 ColorMatrix cm = new ColorMatrix();
126 cm.Matrix33 = 0.75f;
127 ia.SetColorMatrix(cm);
128 */
129
130 ImageAttributes ia = new ImageAttributes();
131
132 //The first step in manipulating the watermark image is to replace
133 //the background color with one that is trasparent (Alpha=0, R=0, G=0, B=0)
134 //to do this we will use a Colormap and use this to define a RemapTable
135 ColorMap colorMap = new ColorMap();
136
137 //My watermark was defined with a background of 100% Green this will
138 //be the color we search for and replace with transparency
139 colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
140 colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
141
142 ColorMap[] remapTable = { colorMap };
143
144 ia.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
145
146 //The second color manipulation is used to change the opacity of the
147 //watermark. This is done by applying a 5x5 matrix that contains the
148 //coordinates for the RGBA space. By setting the 3rd row and 3rd column
149 //to 0.3f we achive a level of opacity
150 float[][] colorMatrixElements = {
151 new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
152 new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
153 new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
154 new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f},
155 new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}};
156 ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
157
158 ia.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default,
159 ColorAdjustType.Bitmap);
160
161
162 g.DrawImage(warterMark, new Rectangle(x, y, warterMark.Width, warterMark.Height), 0, 0, warterMark.Width, warterMark.Height, GraphicsUnit.Pixel, ia);
163
164 warterMark.Dispose();
165 #endregion
166 }
167 else
168 {
169 #region 文字水印
170
171 int[] sizes = new int[] { 18, 16, 14, 12, 10, 8, 6, 4 };
172
173 Font font = null;
174 SizeF size = new SizeF();
175
176 for (int i = 0; i < 8; i++)//自动适应大小
177 {
178 font = new Font("arial", sizes[i], FontStyle.Bold);
179 size = g.MeasureString(model.TextWatermark, font);
180
181 if ((ushort)size.Width < (ushort)destWidth * .90)
182 break;
183 }
184
185 float fx = destWidth * .95f - size.Width;
186 float fy = destHeight * .99f - size.Height;
187
188 StringFormat StrFormat = new StringFormat();
189 StrFormat.Alignment = StringAlignment.Near;
190
191 //黑色阴影 (Alpha 153)
192 SolidBrush brush1 = new SolidBrush(Color.FromArgb(153, 0, 0, 0));
193 g.DrawString(model.TextWatermark,
194 font,
195 brush1,
196 new PointF(fx + 1, fy + 1),
197 StrFormat);
198
199 //白色前景 (Alpha 153)
200 SolidBrush brush2 = new SolidBrush(Color.FromArgb(153, 255, 255, 255));
201 g.DrawString(model.TextWatermark,
202 font,
203 brush2,
204 new PointF(fx, fy),
205 StrFormat);
206 #endregion
207 }
208 }
209
210 g.Flush();
211 }
212
213 model.Source.Dispose();
214
215 return imgResult;
216 }
217
218 private static void GetWatermarkPlacement(WatermarkPositions watermarkPosition, float xDpi, float yDpi, int destWidth, int destHeight, Image watermarkImg, out int x, out int y)
219 {
220 float xProportion = xDpi / watermarkImg.HorizontalResolution;
221 float yProportion = yDpi / watermarkImg.VerticalResolution;
222
223 int watermarkImgWidth = Convert.ToInt32((float)watermarkImg.Width * xProportion);
224 int watermarkImgHeight = Convert.ToInt32((float)watermarkImg.Height * yProportion);
225
226 x = 5;
227 y = 5;
228
229 switch (watermarkPosition)
230 {
231 case WatermarkPositions.TopRight:
232 x = destWidth - watermarkImgWidth - 5;
233 y = 5;
234 break;
235 case WatermarkPositions.BottomRight:
236 x = destWidth - watermarkImgWidth - 5;
237 y = destHeight - watermarkImgHeight - 5;
238 break;
239 case WatermarkPositions.BottomLeft:
240 x = 5;
241 y = destHeight - watermarkImgHeight - 5;
242 break;
243 }
244 }
245
246 private static void GetFinalSize(int width, int height, int srcWidth, int srcHeight, out int destWidth, out int destHeight)
247 {
248 destWidth = 800;
249 destHeight = 800;
250
251 if (srcWidth > srcHeight)
252 {
253 double proportion = srcWidth / (double)width;
254
255 destWidth = width;
256 destHeight = Convert.ToInt32(srcHeight / proportion);
257 }
258 else
259 {
260 double proportion = srcHeight / (double)height;
261
262 destHeight = height;
263 destWidth = Convert.ToInt32(srcWidth / proportion);
264 }
265 }
266
267 public static ImageCodecInfo GetCodeInfo(ImgCodes code)
268 {
269 return ImageCodecInfo.GetImageEncoders().FirstOrDefault(m => m.MimeType == codes[code]);
270 }
271
272 static Imager()
273 {
274 codes.Add(ImgCodes.BMP, "image/bmp");
275 codes.Add(ImgCodes.GIF, "image/gif");
276 codes.Add(ImgCodes.JPEG, "image/jpeg");
277 codes.Add(ImgCodes.PNG, "image/png");
278 codes.Add(ImgCodes.TIFF, "image/tiff");
279 }
280
281 private static Dictionary<ImgCodes, string> codes = new Dictionary<ImgCodes, string>();
282 }
283
284 public enum WatermarkPositions { TopLeft, TopRight, BottomLeft, BottomRight }
285
286 public enum ImgCodes { BMP, GIF, JPEG, PNG, TIFF }
287
288 public enum ResizeTypes { Auto, Absolute, FixedWidth, FixedHeight, Cut }
289
290 public class ResizeModel
291 {
292 public ResizeModel()
293 {
294 ResizeType = ResizeTypes.Auto;
295 IsWartermarked = true;
296 TextWatermark = string.Concat("版权所有 ? 2009-", DateTime.Now.Year);
297 Position = WatermarkPositions.BottomLeft;
298 StartX = StartY = -1;
299 }
300
301 /// <summary>
302 /// 待处理图片
303 /// </summary>
304 public Image Source { get; set; }
305 /// <summary>
306 /// 缩放类型
307 /// </summary>
308 public ResizeTypes ResizeType { get; set; }
309 /// <summary>
310 /// 是否水印,若开启水印无图片则添加文字水印
311 /// </summary>
312 public bool IsWartermarked { get; set; }
313 /// <summary>
314 /// 水印图片
315 /// </summary>
316 public Image ImageWartermark { get; set; }
317 /// <summary>
318 /// 水印文字
319 /// </summary>
320 public string TextWatermark { get; set; }
321 /// <summary>
322 /// 水印图片位置
323 /// </summary>
324 public WatermarkPositions Position { get; set; }
325 /// <summary>
326 /// 后缀
327 /// </summary>
328 public string Suffix { get; set; }
329 /// <summary>
330 /// 输出宽度
331 /// </summary>
332 public int Width { get; set; }
333 /// <summary>
334 /// 输出高度
335 /// </summary>
336 public int Height { get; set; }
337 /// <summary>
338 /// 水印图片开始X坐标
339 /// </summary>
340 public int StartX { get; set; }
341 /// <summary>
342 /// 水印图片开始Y坐标
343 /// </summary>
344 public int StartY { get; set; }
345 }
没有评论:
发表评论