水印制作就是简要来说利用GDI+的函数,进行原图和水印图片的合成,或者在原图上配置文字。
水印制作的关键函数:
这两个函数有比较多重载,具体请参考MSDN。
说到GDI+,他一般用于Winform对于GUI的绘制,例如桌面上的窗体。其实GDI不仅可以绘制窗体,它可以绘制一切的表面图像。
其中Graphics是绘制图像最核心的类,该对象就像一张画图画的画布,我们可以绘制图像的方法在其上绘图。一个应用程序如果需要绘制和着色,它就必须使用该对象。
此外不得不说还有两个对象:Image类和BitMap类。这两个对象也比较重要。
首先是Image类,该类提供了位图和元文件操作的函数,它是一个抽象类,不能实例化,只能用作基类,我们主要用它来加载一些文件,生成Image对象,以便对位图进一步操作。
其次是BitMap对象,用于由像素数据定义的图像,它也是进行图像处理的主要类。我们可以取得或者设置它的一些属性,还可用它读入和保存一些图像。
下面就进入我们的主题:
一、绘制文字水印
private static void drawText(Graphics g, String wmText, Font font, PointF p, StringFormat format)
{
SolidBrush brush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));
g.DrawString(wmText, font, brush, p, format);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;//设置g的呈现质量
//用指定的笔刷,和字体绘制文字
SolidBrush brush2 = new SolidBrush(Color.FromArgb(153, 0, 0, 0));
g.DrawString(wmText, font, brush2, new PointF(p.X + 1, p.Y + 1), format);
}
二、绘制图片水印
图片水印主要是两个图像的合成,重点是要设置图片的水印的透明度,透明度一般降为原来的30%,这里将使用colorMatrix来做。矩阵在很多地方的被合使用,主要有矩阵进行像素的高速变换(其它方法处理速度相对较慢),特别是变换的地方。仔细观察矩阵对角线数字,1,1,1,0.3,1;这些是倍数运算因子,对应RGBAW的变换倍数。RGB不变,透明度为原来的0.3倍。通过这种方法就将图片的透明度降低了。
设置图像特性,主要是透明度的代码:
private static ImageAttributes getImageAttributes() { ImageAttributes imgAttr = new ImageAttributes(); ColorMap colorMap = new ColorMap(); colorMap.OldColor = Color.FromArgb(255, 0, 255, 0); colorMap.NewColor = Color.FromArgb(0, 0, 0, 0); ColorMap[] remapTable = { colorMap }; imgAttr.SetRemapTable(remapTable, ColorAdjustType.Bitmap); 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)(ImageTransparencyNum/100.0), 0.0f}, new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f} }; ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements); imgAttr.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); return imgAttr; }
绘制图片水印核心的代码:
public static Bitmap AddWaterMark_IMG(String srcPath, String watermarkPath, WaterMarkPosition wp = WaterMarkPosition.BottomRight) { using (Image src = Image.FromFile(srcPath)) { using (Bitmap bm = new Bitmap(srcPath)) { using (Graphics g = Graphics.FromImage(bm)) { using (Image wm = Image.FromFile(watermarkPath)) { ImageAttributes imgAttr = getImageAttributes(); Rectangle rect = getPicRectangle(src, wm, wp); g.DrawImage(wm, rect, 0, 0, wm.Width, wm.Height, GraphicsUnit.Pixel, imgAttr); return new Bitmap((Image)(bm.Clone())); } } } } }
有时灰度化图像也比较常用,这个如果也用像素法处理也是较慢的,我们也采用矩阵处理
public static Bitmap GrayPicuure(String srcPicturePath) { using (Bitmap currentBitmap = new Bitmap(srcPicturePath)) { using (Graphics g = Graphics.FromImage(currentBitmap)) { using (ImageAttributes ia = new ImageAttributes()) { float[][] colorMatrix = { new float[] {0.299f, 0.299f, 0.299f, 0, 0}, new float[] {0.587f, 0.587f, 0.587f, 0, 0}, new float[] {0.114f, 0.114f, 0.114f, 0, 0}, new float[] {0, 0, 0, 1, 0}, new float[] {0, 0, 0, 0, 1} }; //颜色调整矩阵 ColorMatrix cm = new ColorMatrix(colorMatrix); ia.SetColorMatrix(cm, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); g.DrawImage(currentBitmap, new Rectangle(0, 0, currentBitmap.Width, currentBitmap.Height), 0, 0, currentBitmap.Width, currentBitmap.Height, GraphicsUnit.Pixel, ia); return new Bitmap((Image)(currentBitmap.Clone())); } } } }
此外我们在图像处理时也会翻转旋转图像,这里主要用Image类的RotateFlip方法处理
public static Bitmap RotateFlipPicture(String srcPicturePath, RotateFlipType RotateFlipType) { using (Image tmp = Image.FromFile(srcPicturePath)) { tmp.RotateFlip(RotateFlipType); return new Bitmap(tmp); } }
图像处理内容比较多,在此不一列举,这里只给出常用的,下面给出全部源代码
1 /* 2 * Copyright 2012 www.vision.net.cn 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 using System; 18 using System.IO; 19 using System.Drawing; 20 using System.Drawing.Imaging; 21 using System.Windows.Forms; 22 23 namespace myDrawing 24 { 25 /// <summary> 26 /// 水印的位置 27 /// </summary> 28 public enum WaterMarkPosition 29 { 30 /// <summary> 31 /// 左上角 32 /// </summary> 33 TopLeft, 34 /// <summary> 35 /// 左下角 36 /// </summary> 37 BottomLeft, 38 /// <summary> 39 /// 右上角 40 /// </summary> 41 TopRight, 42 /// <summary> 43 /// 右下角 44 /// </summary> 45 BottomRight, 46 /// <summary> 47 /// 顶部中间 48 /// </summary> 49 TopCenter, 50 /// <summary> 51 /// 底部中间 52 /// </summary> 53 BottomCenter 54 }; 55 /// <summary> 56 /// 字体 57 /// </summary> 58 public enum myFont 59 { 60 /// <summary> 61 /// 字体:中文宋体 62 /// </summary> 63 宋体, 64 /// <summary> 65 /// 字体:中文楷体 66 /// </summary> 67 楷体, 68 /// <summary> 69 /// 字体:中文仿宋 70 /// </summary> 71 仿宋, 72 /// <summary> 73 /// 字体:中文黑体 74 /// </summary> 75 黑体, 76 /// <summary> 77 /// 字体:Arial 78 /// </summary> 79 Arial, 80 /// <summary> 81 /// 字体:Georgia 82 /// </summary> 83 Georgia 84 } 85 /// <summary> 86 /// 水印工具 87 /// </summary> 88 public class Watermark 89 { 90 private static int imageTransparency=0; 91 /// <summary> 92 /// 水印图像的透明度,默认30%透明 93 /// </summary> 94 public static int ImageTransparencyNum 95 { 96 get { if (imageTransparency == 0)imageTransparency = 30; return imageTransparency; } 97 set 98 { 99 if (imageTransparency >=0 && imageTransparency <= 100) imageTransparency = value; 100 } 101 } 102 /// <summary> 103 /// 取得设置的图像特性,主要是透明度 104 /// </summary> 105 /// <returns></returns> 106 private static ImageAttributes getImageAttributes() 107 { 108 ImageAttributes imgAttr = new ImageAttributes(); 109 110 ColorMap colorMap = new ColorMap(); 111 colorMap.OldColor = Color.FromArgb(255, 0, 255, 0); 112 colorMap.NewColor = Color.FromArgb(0, 0, 0, 0); 113 ColorMap[] remapTable = { colorMap }; 114 115 imgAttr.SetRemapTable(remapTable, ColorAdjustType.Bitmap); 116 117 float[][] colorMatrixElements = { 118 new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 119 new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f}, 120 new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, 121 new float[] {0.0f, 0.0f, 0.0f, (float)(ImageTransparencyNum/100.0), 0.0f}, 122 new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f} 123 }; 124 125 ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements); 126 imgAttr.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); 127 128 return imgAttr; 129 } 130 /// <summary> 131 /// 添加图片水印:将原始图片添加图片水印之后存储 132 /// </summary> 133 /// <param name="srcPath">原图片绝对地址</param> 134 /// <param name="watermarkPath">水印图片路径</param> 135 /// <param name="wp">水印位置的枚举值</param> 136 public static Bitmap AddWaterMark_IMG(String srcPath, String watermarkPath, WaterMarkPosition wp = WaterMarkPosition.BottomRight) 137 { 138 using (Image src = Image.FromFile(srcPath)) 139 { 140 using (Bitmap bm = new Bitmap(srcPath)) 141 { 142 using (Graphics g = Graphics.FromImage(bm)) 143 { 144 using (Image wm = Image.FromFile(watermarkPath)) 145 { 146 147 ImageAttributes imgAttr = getImageAttributes(); 148 Rectangle rect = getPicRectangle(src, wm, wp); 149 150 g.DrawImage(wm, rect, 0, 0, wm.Width, wm.Height, GraphicsUnit.Pixel, imgAttr); 151 152 return new Bitmap((Image)(bm.Clone())); 153 154 } 155 } 156 } 157 } 158 159 } 160 161 /// <summary> 162 /// 取得绘制水印的矩形 163 /// </summary> 164 /// <param name="src">原图像映像</param> 165 /// <param name="wm">水印图像映像</param> 166 /// <param name="wp">指定的水印位置枚举值WaterMarkPosition</param> 167 /// <returns></returns> 168 private static Rectangle getPicRectangle(Image src, Image wm, WaterMarkPosition wp) 169 { 170 171 int xpos = 10;//水印图像X坐标 172 int ypos = 10;//水印图像y坐标 173 174 switch (wp) 175 { 176 case WaterMarkPosition.TopLeft: 177 xpos = 10; 178 ypos = 10; 179 break; 180 case WaterMarkPosition.TopCenter: 181 xpos = src.Width / 2 - wm.Width / 2; 182 ypos = 10; 183 break; 184 case WaterMarkPosition.TopRight: 185 xpos = ((src.Width - wm.Width) - 10); 186 ypos = 10; 187 break; 188 case WaterMarkPosition.BottomLeft: 189 xpos = 10; 190 ypos = src.Height - wm.Height - 10; 191 break; 192 case WaterMarkPosition.BottomRight: 193 xpos = ((src.Width - wm.Width) - 10); 194 ypos = src.Height - wm.Height - 10; 195 break; 196 case WaterMarkPosition.BottomCenter: 197 xpos = src.Width / 2 - wm.Width / 2; 198 ypos = src.Height - wm.Height - 10; 199 break; 200 } 201 return new Rectangle(xpos, ypos, wm.Width, wm.Height); 202 } 203 204 /// <summary> 205 /// 添加文字水印:将原始图片添加文字水印之后存储 206 /// </summary> 207 /// <param name="srcPath">原图片绝对地址</param> 208 /// <param name="words">要添加的水印文本</param> 209 /// <param name="wp">水印位置WaterMarkPosition,参数可数</param> 210 /// <param name="fontSize">字体大小,可选</param> 211 /// <param name="myfont">字体myFont,可选</param> 212 public static Bitmap AddWaterMark_WORD(String srcPath, String words, WaterMarkPosition wp = WaterMarkPosition.BottomRight, int fontSize = 40, myFont myfont = myFont.楷体) 213 { 214 215 using (Image src = Image.FromFile(srcPath)) 216 { 217 using (Bitmap bm = new Bitmap(srcPath)) 218 { 219 using (Graphics g = Graphics.FromImage(bm)) 220 { 221 //font定义特定的文字格式,包括文本字体,字号大小,和字形属性。 222 Font crFont = new Font(myfont.ToString(), fontSize, FontStyle.Regular); 223 //Sizef存储有序的浮点数对。通常为矩形的宽度和高度。(Drawing.SizeF) 224 SizeF crSize = g.MeasureString(words, crFont); 225 //FontAndSize fs = FontAndSize.GetValue(g, words, "arial", fontSize, src.Width); 226 PointF p = getTextPoint(src, crSize, wp); 227 StringFormat sf = getStringFormat(); 228 229 drawText(g, words, crFont, p, sf); 230 231 return new Bitmap((Image)(bm.Clone())); 232 } 233 } 234 } 235 236 } 237 /// <summary> 238 /// 绘制文本对象 239 /// </summary> 240 /// <param name="g">Graphics画面 对象</param> 241 /// <param name="wmText">水印文字的内容</param> 242 /// <param name="font">水印文字的字体</param> 243 /// <param name="p">水印文字的位置坐标有序对</param> 244 /// <param name="format">水印广本的格式化格式</param> 245 private static void drawText(Graphics g, String wmText, Font font, PointF p, StringFormat format) 246 { 247 248 SolidBrush brush = new SolidBrush(Color.FromArgb(153, 255, 255, 255)); 249 g.DrawString(wmText, font, brush, p, format); 250 251 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;//设置g的呈现质量 252 //用指定的笔刷,和字体绘制文字 253 SolidBrush brush2 = new SolidBrush(Color.FromArgb(153, 0, 0, 0)); 254 g.DrawString(wmText, font, brush2, new PointF(p.X + 1, p.Y + 1), format); 255 256 } 257 /// <summary> 258 /// 取得水印的格式格式 259 /// </summary> 260 /// <returns>StringFormat格式</returns> 261 private static StringFormat getStringFormat() 262 { 263 StringFormat StrFormat = new StringFormat(); 264 StrFormat.Alignment = StringAlignment.Center; 265 return StrFormat; 266 } 267 /// <summary> 268 /// 取水印文字的位置坐标有序对 269 /// </summary> 270 /// <param name="src">原Graphics图面 对象</param> 271 /// <param name="textSize">文字所占区域的宽度和高度有序对SizeF。</param> 272 /// <param name="wp">水印文字的位置WaterMarkPosition</param> 273 /// <returns></returns> 274 private static PointF getTextPoint(Image src, SizeF textSize, WaterMarkPosition wp) 275 { 276 277 float x = 5; 278 float y = 5; 279 280 int margin = 10;//水平方向,textSize文字居中对齐 281 282 switch (wp) 283 { 284 case WaterMarkPosition.TopLeft: 285 x = textSize.Width/2+margin; 286 y = textSize.Height / 2 +5; 287 break; 288 case WaterMarkPosition.TopCenter: 289 x = src.Width / 2; 290 y = textSize.Height / 2 + 5; 291 break; 292 case WaterMarkPosition.TopRight: 293 x = src.Width - textSize.Width/2- margin; 294 y = textSize.Height / 2+ 5; 295 break; 296 case WaterMarkPosition.BottomLeft: 297 x =textSize.Width/2+ margin; 298 y = src.Height- textSize.Height -5; 299 break; 300 case WaterMarkPosition.BottomCenter: 301 x = src.Width / 2; 302 y = src.Height - textSize.Height - 5; 303 break; 304 case WaterMarkPosition.BottomRight: 305 x = src.Width - textSize.Width/2 - margin; 306 y = src.Height - textSize.Height - 5; 307 break; 308 } 309 return new PointF(x, y); 310 } 311 /// <summary> 312 /// 将文本保存力图像格式的文件,备用作透明文字 313 /// </summary> 314 /// <param name="srcPath">原图片绝对地址,主要用来取得图像的大小,以便放文字</param> 315 /// <param name="wmText">文本(要转换为图像的文本)</param> 316 /// <param name="font">字体,new font("名称",大小),依赖操作系统</param> 317 public static void SaveWaterMarkWord_To_Picture(String srcPath,String wmText, Font font) 318 { 319 using (Image src = Image.FromFile(srcPath)) 320 { 321 using (Bitmap bm = new Bitmap(srcPath)) 322 { 323 using (Graphics g = Graphics.FromImage(bm)) 324 { 325 // 生成水印图片(将文字写到图片中) 326 SizeF crSize = g.MeasureString(wmText, font); 327 Bitmap floatBmp = new Bitmap((int)crSize.Width + 3, 328 (int)crSize.Height + 3, PixelFormat.Format32bppArgb); 329 //GDI+绘图图面,封装一个绘图图面。 330 Graphics fg = Graphics.FromImage(floatBmp); 331 //浮点x和y坐标的有序对。PointF。 332 PointF pt = new PointF(0, 0); 333 334 // 画阴影文字 335 Brush TransparentBrush0 = new SolidBrush(Color.FromArgb(255, Color.Black)); 336 Brush TransparentBrush1 = new SolidBrush(Color.FromArgb(255, Color.Black)); 337 fg.DrawString(wmText, font, TransparentBrush0, pt.X, pt.Y + 1); 338 fg.DrawString(wmText, font, TransparentBrush0, pt.X + 1, pt.Y); 339 340 fg.DrawString(wmText, font, TransparentBrush1, pt.X + 1, pt.Y + 1); 341 fg.DrawString(wmText, font, TransparentBrush1, pt.X, pt.Y + 2); 342 fg.DrawString(wmText, font, TransparentBrush1, pt.X + 2, pt.Y); 343 344 TransparentBrush0.Dispose(); 345 TransparentBrush1.Dispose(); 346 347 //**画文字**// 348 fg.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;//设置fg的呈现质量 349 //用指定的笔刷,和字体绘制文字 350 StringFormat sf = getStringFormat(); 351 fg.DrawString(wmText, font, new SolidBrush(Color.White), pt.X, pt.Y, sf); 352 353 // 保存刚才的操作 354 fg.Save(); 355 fg.Dispose(); 356 //保存图片对话取得路径和文件名 357 SaveFileDialog savefileDlg1 = new SaveFileDialog(); 358 savefileDlg1.Filter = "(*.JPG)|*.JPG|(*.BMP)|*.BMP"; 359 savefileDlg1.FilterIndex = 0; 360 savefileDlg1.Title = "保存文件"; 361 savefileDlg1.InitialDirectory = Application.StartupPath; 362 savefileDlg1.RestoreDirectory = true; 363 savefileDlg1.ShowDialog(); 364 string filename = savefileDlg1.FileName; 365 if (filename == "") return; 366 floatBmp.Save(filename); 367 } 368 } 369 } 370 371 } 372 } 373 374 #region ImageProceesClass 375 /// <summary> 376 /// 图像处理类:包含灰度化图像,自定义裁切,缩放,反转旋转等操作 377 /// </summary> 378 public class ImageProcees 379 { 380 #region 旋转翻转图像 381 382 /// <summary> 383 /// 旋转翻转图像 384 /// </summary> 385 /// <param name="srcPicturePath">原图片绝对地址</param> 386 /// <param name="RotateFlipType">旋转或者翻转的枚举RotateFlipType</param> 387 /// <returns>返回bitmap对象</returns> 388 public static Bitmap RotateFlipPicture(String srcPicturePath, RotateFlipType RotateFlipType) 389 { 390 using (Image tmp = Image.FromFile(srcPicturePath)) 391 { 392 tmp.RotateFlip(RotateFlipType); 393 return new Bitmap(tmp); 394 } 395 } 396 397 #endregion 旋转翻转图像 398 399 #region 灰度化图像 400 401 402 /// <summary> 403 /// (经典矩阵法) 404 /// </summary> 405 /// <param name="srcPicturePath">原图片绝对地址</param> 406 /// <returns>返回bitmap对象</returns> 407 public static Bitmap GrayPicuure(String srcPicturePath) 408 { 409 using (Bitmap currentBitmap = new Bitmap(srcPicturePath)) 410 { 411 using (Graphics g = Graphics.FromImage(currentBitmap)) 412 { 413 using (ImageAttributes ia = new ImageAttributes()) 414 { 415 float[][] colorMatrix = { 416 new float[] {0.299f, 0.299f, 0.299f, 0, 0}, 417 new float[] {0.587f, 0.587f, 0.587f, 0, 0}, 418 new float[] {0.114f, 0.114f, 0.114f, 0, 0}, 419 new float[] {0, 0, 0, 1, 0}, 420 new float[] {0, 0, 0, 0, 1} 421 }; 422 //颜色调整矩阵 423 ColorMatrix cm = new ColorMatrix(colorMatrix); 424 425 ia.SetColorMatrix(cm, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); 426 427 g.DrawImage(currentBitmap, new Rectangle(0, 0, currentBitmap.Width, currentBitmap.Height), 0, 0, currentBitmap.Width, currentBitmap.Height, GraphicsUnit.Pixel, ia); 428 429 return new Bitmap((Image)(currentBitmap.Clone())); 430 } 431 } 432 } 433 } 434 #endregion 灰度化图像 435 436 #region 正方型裁剪并缩放 437 438 /// <summary> 439 /// 正方型裁剪 440 /// 以图片中心为轴心,截取正方型,然后等比缩放 441 /// 用于头像处理 442 /// </summary> 443 /// <remarks>2012-12-18</remarks> 444 /// <param name="srcPicturePath">原图片绝对地址</param> 445 /// <param name="fileSaveUrl">缩略图存放绝对地址</param> 446 /// <param name="side">指定的边长(正方型)</param> 447 /// <param name="quality">质量(范围0-100)</param> 448 public static void CutBySquare(string srcPicturePath, string fileSaveUrl, int side, int quality) 449 { 450 //创建目录 451 //string dir = Path.GetDirectoryName(fileSaveUrl); 452 //if (!Directory.Exists(dir)) 453 // Directory.CreateDirectory(dir); 454 455 //原始图片(获取原始图片创建对象,并使用流中嵌入的颜色管理信息) 456 System.Drawing.Image initImage = System.Drawing.Image.FromFile(srcPicturePath); 457 458 //原图宽高均小于模版,不作处理,直接保存 459 if (initImage.Width <= side && initImage.Height <= side) 460 { 461 initImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg); 462 } 463 else 464 { 465 //原始图片的宽、高 466 int initWidth = initImage.Width; 467 int initHeight = initImage.Height; 468 469 //非正方型先裁剪为正方型 470 if (initWidth != initHeight) 471 { 472 //截图对象 473 System.Drawing.Image pickedImage = null; 474 System.Drawing.Graphics pickedG = null; 475 476 //宽大于高的横图 477 if (initWidth > initHeight) 478 { 479 //对象实例化 480 pickedImage = new System.Drawing.Bitmap(initHeight, initHeight); 481 pickedG = System.Drawing.Graphics.FromImage(pickedImage); 482 //设置质量 483 pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 484 pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 485 //定位 486 Rectangle fromR = new Rectangle((initWidth - initHeight) / 2, 0, initHeight, initHeight); 487 Rectangle toR = new Rectangle(0, 0, initHeight, initHeight); 488 //画图 489 pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel); 490 //重置宽 491 initWidth = initHeight; 492 } 493 //高大于宽的竖图 494 else 495 { 496 //对象实例化 497 pickedImage = new System.Drawing.Bitmap(initWidth, initWidth); 498 pickedG = System.Drawing.Graphics.FromImage(pickedImage); 499 //设置质量 500 pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 501 pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 502 //定位 503 Rectangle fromR = new Rectangle(0, (initHeight - initWidth) / 2, initWidth, initWidth); 504 Rectangle toR = new Rectangle(0, 0, initWidth, initWidth); 505 //画图 506 pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel); 507 //重置高 508 initHeight = initWidth; 509 } 510 511 //将截图对象赋给原图 512 initImage = (System.Drawing.Image)pickedImage.Clone(); 513 //释放截图资源 514 pickedG.Dispose(); 515 pickedImage.Dispose(); 516 } 517 518 //缩略图对象 519 System.Drawing.Image resultImage = new System.Drawing.Bitmap(side, side); 520 System.Drawing.Graphics resultG = System.Drawing.Graphics.FromImage(resultImage); 521 //设置质量 522 resultG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 523 resultG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 524 //用指定背景色清空画布 525 resultG.Clear(Color.White); 526 //绘制缩略图 527 resultG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, side, side), new System.Drawing.Rectangle(0, 0, initWidth, initHeight), System.Drawing.GraphicsUnit.Pixel); 528 529 //关键质量控制 530 //获取系统编码类型数组,包含了jpeg,bmp,png,gif,tiff 531 ImageCodecInfo[] icis = ImageCodecInfo.GetImageEncoders(); 532 ImageCodecInfo ici = null; 533 foreach (ImageCodecInfo i in icis) 534 { 535 if (i.MimeType == "image/jpeg" || i.MimeType == "image/bmp" || i.MimeType == "image/png" || i.MimeType == "image/gif") 536 { 537 ici = i; 538 } 539 } 540 EncoderParameters ep = new EncoderParameters(1); 541 ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)quality); 542 543 //保存缩略图 544 resultImage.Save(fileSaveUrl, ici, ep); 545 546 //释放关键质量控制所用资源 547 ep.Dispose(); 548 549 //释放缩略图资源 550 resultG.Dispose(); 551 resultImage.Dispose(); 552 553 //释放原始图片资源 554 initImage.Dispose(); 555 } 556 } 557 558 #endregion 正方型裁剪并缩放 559 560 #region 自定义裁剪并缩放 561 562 /// <summary> 563 /// 指定长宽裁剪 564 /// 按模版比例最大范围的裁剪图片并缩放至模版尺寸 565 /// </summary> 566 /// <remarks>2012-12-18</remarks> 567 /// <param name="srcPicturePath">原图片绝对地址</param> 568 /// <param name="fileSaveUrl">保存路径</param> 569 /// <param name="maxWidth">最大宽(单位:px)</param> 570 /// <param name="maxHeight">最大高(单位:px)</param> 571 /// <param name="quality">质量(范围0-100)</param> 572 public static void CutByCustom(string srcPicturePath, string fileSaveUrl, int maxWidth, int maxHeight, int quality) 573 { 574 //从文件获取原始图片,并使用流中嵌入的颜色管理信息 575 System.Drawing.Image initImage = System.Drawing.Image.FromFile(srcPicturePath); 576 577 //原图宽高均小于模版,不作处理,直接保存 578 if (initImage.Width <= maxWidth && initImage.Height <= maxHeight) 579 { 580 initImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg); 581 } 582 else 583 { 584 //模版的宽高比例 585 double templateRate = (double)maxWidth / maxHeight; 586 //原图片的宽高比例 587 double initRate = (double)initImage.Width / initImage.Height; 588 589 //原图与模版比例相等,直接缩放 590 if (templateRate == initRate) 591 { 592 //按模版大小生成最终图片 593 System.Drawing.Image templateImage = new System.Drawing.Bitmap(maxWidth, maxHeight); 594 System.Drawing.Graphics templateG = System.Drawing.Graphics.FromImage(templateImage); 595 templateG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; 596 templateG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 597 templateG.Clear(Color.White); 598 templateG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, maxWidth, maxHeight), new System.Drawing.Rectangle(0, 0, initImage.Width, initImage.Height), System.Drawing.GraphicsUnit.Pixel); 599 templateImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg); 600 } 601 //原图与模版比例不等,裁剪后缩放 602 else 603 { 604 //裁剪对象 605 System.Drawing.Image pickedImage = null; 606 System.Drawing.Graphics pickedG = null; 607 608 //定位 609 Rectangle fromR = new Rectangle(0, 0, 0, 0);//原图裁剪定位 610 Rectangle toR = new Rectangle(0, 0, 0, 0);//目标定位 611 612 //宽为标准进行裁剪 613 if (templateRate > initRate) 614 { 615 //裁剪对象实例化 616 pickedImage = new System.Drawing.Bitmap(initImage.Width, (int)System.Math.Floor(initImage.Width / templateRate)); 617 pickedG = System.Drawing.Graphics.FromImage(pickedImage); 618 619 //裁剪源定位 620 fromR.X = 0; 621 fromR.Y = (int)System.Math.Floor((initImage.Height - initImage.Width / templateRate) / 2); 622 fromR.Width = initImage.Width; 623 fromR.Height = (int)System.Math.Floor(initImage.Width / templateRate); 624 625 //裁剪目标定位 626 toR.X = 0; 627 toR.Y = 0; 628 toR.Width = initImage.Width; 629 toR.Height = (int)System.Math.Floor(initImage.Width / templateRate); 630 } 631 //高为标准进行裁剪 632 else 633 { 634 pickedImage = new System.Drawing.Bitmap((int)System.Math.Floor(initImage.Height * templateRate), initImage.Height); 635 pickedG = System.Drawing.Graphics.FromImage(pickedImage); 636 637 fromR.X = (int)System.Math.Floor((initImage.Width - initImage.Height * templateRate) / 2); 638 fromR.Y = 0; 639 fromR.Width = (int)System.Math.Floor(initImage.Height * templateRate); 640 fromR.Height = initImage.Height; 641 642 toR.X = 0; 643 toR.Y = 0; 644 toR.Width = (int)System.Math.Floor(initImage.Height * templateRate); 645 toR.Height = initImage.Height; 646 } 647 648 //设置质量 649 pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 650 pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 651 652 //裁剪 653 pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel); 654 655 //按模版大小生成最终图片 656 System.Drawing.Image templateImage = new System.Drawing.Bitmap(maxWidth, maxHeight); 657 System.Drawing.Graphics templateG = System.Drawing.Graphics.FromImage(templateImage); 658 templateG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; 659 templateG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 660 templateG.Clear(Color.White); 661 templateG.DrawImage(pickedImage, new System.Drawing.Rectangle(0, 0, maxWidth, maxHeight), new System.Drawing.Rectangle(0, 0, pickedImage.Width, pickedImage.Height), System.Drawing.GraphicsUnit.Pixel); 662 663 //关键质量控制 664 //获取系统编码类型数组,包含了jpeg,bmp,png,gif,tiff 665 ImageCodecInfo[] icis = ImageCodecInfo.GetImageEncoders(); 666 ImageCodecInfo ici = null; 667 foreach (ImageCodecInfo i in icis) 668 { 669 if (i.MimeType == "image/jpeg" || i.MimeType == "image/bmp" || i.MimeType == "image/png" || i.MimeType == "image/gif") 670 { 671 ici = i; 672 } 673 } 674 EncoderParameters ep = new EncoderParameters(1); 675 ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)quality); 676 677 //保存缩略图 678 templateImage.Save(fileSaveUrl, ici, ep); 679 //templateImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg); 680 681 //释放资源 682 templateG.Dispose(); 683 templateImage.Dispose(); 684 685 pickedG.Dispose(); 686 pickedImage.Dispose(); 687 } 688 } 689 690 //释放资源 691 initImage.Dispose(); 692 } 693 #endregion 自定义裁剪并缩放 694 695 #region 等比缩放 696 697 /// <summary> 698 /// 图片等比缩放 699 /// </summary> 700 /// <remarks> 2012-12-18</remarks> 701 /// <param name="srcPicturePath">原图片绝对地址</param> 702 /// <param name="savePath">另存为图片绝对地址</param> 703 /// <param name="targetWidth">指定的最大宽度</param> 704 /// <param name="targetHeight">指定的最大高度</param> 705 /// <param name="watermarkText">水印文字(为""表示不使用水印)</param> 706 /// <param name="watermarkImage">水印图片路径(为""表示不使用水印)</param> 707 public static void ZoomAuto(string srcPicturePath, string savePath, System.Double targetWidth, System.Double targetHeight, string watermarkText="", string watermarkImage="") 708 { 709 //创建目录 710 //string dir = Path.GetDirectoryName(savePath); 711 //if (!Directory.Exists(dir)) 712 // Directory.CreateDirectory(dir); 713 714 //原始图片(获取原始图片创建对象,并使用流中嵌入的颜色管理信息) 715 System.Drawing.Image initImage = System.Drawing.Image.FromFile(srcPicturePath); 716 717 //原图宽高均小于模版,不作处理,直接保存 718 if (initImage.Width <= targetWidth && initImage.Height <= targetHeight) 719 { 720 //文字水印 721 if (watermarkText != "") 722 { 723 using (System.Drawing.Graphics gWater = System.Drawing.Graphics.FromImage(initImage)) 724 { 725 System.Drawing.Font fontWater = new Font("黑体", 30); 726 System.Drawing.Brush brushWater = new SolidBrush(Color.White); 727 gWater.DrawString(watermarkText, fontWater, brushWater, 10, 10); 728 gWater.Dispose(); 729 } 730 } 731 732 //透明图片水印 733 if (watermarkImage != "") 734 { 735 if (File.Exists(watermarkImage)) 736 { 737 //获取水印图片 738 using (System.Drawing.Image wrImage = System.Drawing.Image.FromFile(watermarkImage)) 739 { 740 //水印绘制条件:原始图片宽高均大于或等于水印图片 741 if (initImage.Width >= wrImage.Width && initImage.Height >= wrImage.Height) 742 { 743 Graphics gWater = Graphics.FromImage(initImage); 744 745 //透明属性 746 ImageAttributes imgAttributes = new ImageAttributes(); 747 ColorMap colorMap = new ColorMap(); 748 colorMap.OldColor = Color.FromArgb(255, 0, 255, 0); 749 colorMap.NewColor = Color.FromArgb(0, 0, 0, 0); 750 ColorMap[] remapTable = { colorMap }; 751 imgAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap); 752 753 float[][] colorMatrixElements = { 754 new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 755 new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f}, 756 new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, 757 new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f},//透明度:0.3 758 new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f} 759 }; 760 761 ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements); 762 imgAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); 763 gWater.DrawImage(wrImage, new Rectangle(initImage.Width - wrImage.Width, initImage.Height - wrImage.Height, wrImage.Width, wrImage.Height), 0, 0, wrImage.Width, wrImage.Height, GraphicsUnit.Pixel, imgAttributes); 764 765 gWater.Dispose(); 766 } 767 wrImage.Dispose(); 768 } 769 } 770 } 771 772 //保存 773 initImage.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg); 774 } 775 else 776 { 777 //缩略图宽、高计算 778 double newWidth = initImage.Width; 779 double newHeight = initImage.Height; 780 781 //宽大于高或宽等于高(横图或正方) 782 if (initImage.Width > initImage.Height || initImage.Width == initImage.Height) 783 { 784 //如果宽大于模版 785 if (initImage.Width > targetWidth) 786 { 787 //宽按模版,高按比例缩放 788 newWidth = targetWidth; 789 newHeight = initImage.Height * (targetWidth / initImage.Width); 790 } 791 } 792 //高大于宽(竖图) 793 else 794 { 795 //如果高大于模版 796 if (initImage.Height > targetHeight) 797 { 798 //高按模版,宽按比例缩放 799 newHeight = targetHeight; 800 newWidth = initImage.Width * (targetHeight / initImage.Height); 801 } 802 } 803 804 //生成新图 805 //新建一个bmp图片 806 System.Drawing.Image newImage = new System.Drawing.Bitmap((int)newWidth, (int)newHeight); 807 //新建一个画板 808 System.Drawing.Graphics newG = System.Drawing.Graphics.FromImage(newImage); 809 810 //设置质量 811 newG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 812 newG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 813 814 //置背景色 815 newG.Clear(Color.White); 816 //画图 817 newG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, newImage.Width, newImage.Height), new System.Drawing.Rectangle(0, 0, initImage.Width, initImage.Height), System.Drawing.GraphicsUnit.Pixel); 818 819 //文字水印 820 if (watermarkText != "") 821 { 822 using (System.Drawing.Graphics gWater = System.Drawing.Graphics.FromImage(newImage)) 823 { 824 System.Drawing.Font fontWater = new Font("宋体", 30); 825 System.Drawing.Brush brushWater = new SolidBrush(Color.White); 826 gWater.DrawString(watermarkText, fontWater, brushWater, 10, 10); 827 gWater.Dispose(); 828 } 829 } 830 831 //透明图片水印 832 if (watermarkImage != "") 833 { 834 if (File.Exists(watermarkImage)) 835 { 836 //获取水印图片 837 using (System.Drawing.Image wrImage = System.Drawing.Image.FromFile(watermarkImage)) 838 { 839 //水印绘制条件:原始图片宽高均大于或等于水印图片 840 if (newImage.Width >= wrImage.Width && newImage.Height >= wrImage.Height) 841 { 842 Graphics gWater = Graphics.FromImage(newImage); 843 844 //透明属性 845 ImageAttributes imgAttributes = new ImageAttributes(); 846 ColorMap colorMap = new ColorMap(); 847 colorMap.OldColor = Color.FromArgb(255, 0, 255, 0); 848 colorMap.NewColor = Color.FromArgb(0, 0, 0, 0); 849 ColorMap[] remapTable = { colorMap }; 850 imgAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap); 851 852 float[][] colorMatrixElements = { 853 new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 854 new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f}, 855 new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, 856 new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f},//透明度:0.3 857 new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f} 858 }; 859 860 ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements); 861 imgAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); 862 gWater.DrawImage(wrImage, new Rectangle(newImage.Width - wrImage.Width, newImage.Height - wrImage.Height, wrImage.Width, wrImage.Height), 0, 0, wrImage.Width, wrImage.Height, GraphicsUnit.Pixel, imgAttributes); 863 gWater.Dispose(); 864 } 865 wrImage.Dispose(); 866 } 867 } 868 } 869 870 //保存缩略图 871 newImage.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg); 872 873 //释放资源 874 newG.Dispose(); 875 newImage.Dispose(); 876 initImage.Dispose(); 877 } 878 } 879 880 #endregion 881 882 #region 其它 883 884 /// <summary> 885 /// 判断文件类型是否为WEB格式图片 886 /// (注:JPG,GIF,BMP,PNG) 887 /// </summary> 888 /// <param name="contentType">HttpPostedFile.ContentType</param> 889 /// <returns></returns> 890 public static bool IsWebImage(string contentType) 891 { 892 if (contentType == "image/pjpeg" || contentType == "image/jpeg" || contentType == "image/gif" || contentType == "image/bmp" || contentType == "image/png") 893 { 894 return true; 895 } 896 else 897 { 898 return false; 899 } 900 } 901 902 #endregion 其它 903 904 905 } 906 #endregion 907 908 }