在web程序开发中,相信很多同行们都碰到过图片压缩,生成缩略图的操作,比如产品的图片,会员的照片等等功能。
为了满足此类操作今天给大家介绍ImageUtility类,该类几乎实现了常规网站开发图片处理的功能,比如按大小生成缩略图,指定位置和大小裁剪,以前给图片添加 文字或图片水印等。此外此类生成的文件格式均为.jpg格式,如果想要.GIF或PNG的透明效果的朋友,就不要再向下看了。
老样子,先上图:

所有详细的介绍在代里的注释里已经标识的很清楚了,在此不在多说。
代码:

ImageUtility
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Drawing;
5
using System.Drawing.Drawing2D;
6
using System.Drawing.Imaging;
7
using System.IO;
8
9
namespace Loskiv.Utility
10

{
11
/**//// <summary>
12
/// 名称:图片处理常用操作类
13
/// 作者:loskiv
14
/// 创建时间:2009-07-07
15
/// </summary>
16
public class ImageUtility
17
{
18
19
/**//// <summary>
20
/// 获取指定mimeType的ImageCodecInfo
21
/// </summary>
22
private static ImageCodecInfo GetImageCodecInfo(string mimeType)
23
{
24
ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
25
foreach (ImageCodecInfo ici in CodecInfo)
26
{
27
if (ici.MimeType == mimeType) return ici;
28
}
29
return null;
30
}
31
32
/**//// <summary>
33
/// 获取inputStream中的Bitmap对象
34
/// </summary>
35
public static Bitmap GetBitmapFromStream(Stream inputStream)
36
{
37
Bitmap bitmap = new Bitmap(inputStream);
38
return bitmap;
39
}
40
41
/**//// <summary>
42
/// 将Bitmap对象压缩为JPG图片类型
43
/// </summary>
44
/// </summary>
45
/// <param name="bmp">源bitmap对象</param>
46
/// <param name="saveFilePath">目标图片的存储地址</param>
47
/// <param name="quality">压缩质量,越大照片越清晰,推荐80</param>
48
public static void CompressAsJPG(Bitmap bmp, string saveFilePath, int quality)
49
{
50
EncoderParameter p = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality); ;
51
EncoderParameters ps = new EncoderParameters(1);
52
ps.Param[0] = p;
53
bmp.Save(saveFilePath, GetImageCodecInfo("image/jpeg"), ps);
54
bmp.Dispose();
55
}
56
57
/**//// <summary>
58
/// 将inputStream中的对象压缩为JPG图片类型
59
/// </summary>
60
/// <param name="inputStream">源Stream对象</param>
61
/// <param name="saveFilePath">目标图片的存储地址</param>
62
/// <param name="quality">压缩质量,越大照片越清晰,推荐80</param>
63
public static void CompressAsJPG(Stream inputStream, string saveFilePath, int quality)
64
{
65
Bitmap bmp = GetBitmapFromStream(inputStream);
66
CompressAsJPG(bmp, saveFilePath, quality);
67
}
68
69
70
/**//// <summary>
71
/// 生成缩略图(JPG 格式)
72
/// </summary>
73
/// <param name="inputStream">包含图片的Stream</param>
74
/// <param name="saveFilePath">目标图片的存储地址</param>
75
/// <param name="width">缩略图的宽</param>
76
/// <param name="height">缩略图的高</param>
77
public static void ThumbAsJPG(Stream inputStream, string saveFilePath, int width, int height)
78
{
79
Image image = Image.FromStream(inputStream);
80
if (image.Width == width && image.Height == height)
81
{
82
CompressAsJPG(inputStream, saveFilePath, 80);
83
}
84
int tWidth, tHeight, tLeft, tTop;
85
double fScale = (double)height / (double)width;
86
if (((double)image.Width * fScale) > (double)image.Height)
87
{
88
tWidth = width;
89
tHeight = (int)((double)image.Height * (double)tWidth / (double)image.Width);
90
tLeft = 0;
91
tTop = (height - tHeight) / 2;
92
}
93
else
94
{
95
tHeight = height;
96
tWidth = (int)((double)image.Width * (double)tHeight / (double)image.Height);
97
tLeft = (width - tWidth) / 2;
98
tTop = 0;
99
}
100
if (tLeft < 0) tLeft = 0;
101
if (tTop < 0) tTop = 0;
102
103
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
104
Graphics graphics = Graphics.FromImage(bitmap);
105
106
//可以在这里设置填充背景颜色
107
graphics.Clear(Color.White);
108
graphics.DrawImage(image, new Rectangle(tLeft, tTop, tWidth, tHeight));
109
image.Dispose();
110
try
111
{
112
CompressAsJPG(bitmap, saveFilePath, 80);
113
}
114
catch
115
{
116
;
117
}
118
finally
119
{
120
bitmap.Dispose();
121
graphics.Dispose();
122
}
123
}
124
125
/**//// <summary>
126
/// 将Bitmap对象裁剪为指定JPG文件
127
/// </summary>
128
/// <param name="bmp">源bmp对象</param>
129
/// <param name="saveFilePath">目标图片的存储地址</param>
130
/// <param name="x">开始坐标x,单位:像素</param>
131
/// <param name="y">开始坐标y,单位:像素</param>
132
/// <param name="width">宽度:像素</param>
133
/// <param name="height">高度:像素</param>
134
public static void CutAsJPG(Bitmap bmp, string saveFilePath, int x, int y, int width, int height)
135
{
136
int bmpW = bmp.Width;
137
int bmpH = bmp.Height;
138
139
if (x >= bmpW || y >= bmpH)
140
{
141
CompressAsJPG(bmp, saveFilePath, 80);
142
return;
143
}
144
145
if (x + width > bmpW)
146
{
147
width = bmpW - x;
148
}
149
150
if (y + height > bmpH)
151
{
152
height = bmpH - y;
153
}
154
155
Bitmap bmpOut = new Bitmap(width, height, PixelFormat.Format24bppRgb);
156
Graphics g = Graphics.FromImage(bmpOut);
157
g.DrawImage(bmp, new Rectangle(0, 0, width, height), new Rectangle(x, y, width, height), GraphicsUnit.Pixel);
158
g.Dispose();
159
bmp.Dispose();
160
CompressAsJPG(bmpOut, saveFilePath, 80);
161
}
162
163
/**//// <summary>
164
/// 将Stream中的对象裁剪为指定JPG文件
165
/// </summary>
166
/// <param name="inputStream">源bmp对象</param>
167
/// <param name="saveFilePath">目标图片的存储地址</param>
168
/// <param name="x">开始坐标x,单位:像素</param>
169
/// <param name="y">开始坐标y,单位:像素</param>
170
/// <param name="width">宽度:像素</param>
171
/// <param name="height">高度:像素</param>
172
public static void CutAsJPG(Stream inputStream, string saveFilePath, int x, int y, int width, int height)
173
{
174
Bitmap bmp = GetBitmapFromStream(inputStream);
175
CutAsJPG(bmp, saveFilePath, x, y, width, height);
176
}
177
178
179
图片水印操作#region 图片水印操作
180
181
/**//// <summary>
182
/// 给图片添加图片水印
183
/// </summary>
184
/// <param name="inputStream">包含要源图片的流</param>
185
/// <param name="watermarkPath">水印图片的物理地址</param>
186
/// <param name="saveFilePath">目标图片的存储地址</param>
187
/// <param name="mp">水印位置</param>
188
public static void AddPicWatermarkAsJPG(Stream inputStream, string watermarkPath, string saveFilePath, MarkPosition mp)
189
{
190
191
Image image = Image.FromStream(inputStream);
192
Bitmap b = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb);
193
Graphics g = Graphics.FromImage(b);
194
g.Clear(Color.White);
195
g.SmoothingMode = SmoothingMode.HighQuality;
196
g.InterpolationMode = InterpolationMode.High;
197
g.DrawImage(image, 0, 0, image.Width, image.Height);
198
199
AddWatermarkImage(g, watermarkPath, mp, image.Width, image.Height);
200
201
try
202
{
203
CompressAsJPG(b, saveFilePath, 80);
204
}
205
catch
{ ;}
206
finally
207
{
208
b.Dispose();
209
image.Dispose();
210
}
211
}
212
213
214
/**//// <summary>
215
/// 给图片添加图片水印
216
/// </summary>
217
/// <param name="sourcePath">源图片的存储地址</param>
218
/// <param name="watermarkPath">水印图片的物理地址</param>
219
/// <param name="saveFilePath">目标图片的存储地址</param>
220
/// <param name="mp">水印位置</param>
221
public static void AddPicWatermarkAsJPG(string sourcePath, string watermarkPath, string saveFilePath, MarkPosition mp)
222
{
223
if (File.Exists(sourcePath))
224
{
225
using (StreamReader sr = new StreamReader(sourcePath))
226
{
227
AddPicWatermarkAsJPG(sr.BaseStream, watermarkPath, saveFilePath, mp);
228
}
229
}
230
}
231
/**//// <summary>
232
/// 给图片添加文字水印
233
/// </summary>
234
/// <param name="inputStream">包含要源图片的流</param>
235
/// <param name="text">水印文字</param>
236
/// <param name="saveFilePath">目标图片的存储地址</param>
237
/// <param name="mp">水印位置</param>
238
public static void AddTextWatermarkAsJPG(Stream inputStream, string text, string saveFilePath, MarkPosition mp)
239
{
240
241
Image image = Image.FromStream(inputStream);
242
Bitmap b = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb);
243
Graphics g = Graphics.FromImage(b);
244
g.Clear(Color.White);
245
g.SmoothingMode = SmoothingMode.HighQuality;
246
g.InterpolationMode = InterpolationMode.High;
247
g.DrawImage(image, 0, 0, image.Width, image.Height);
248
249
AddWatermarkText(g, text, mp, image.Width, image.Height);
250
251
try
252
{
253
CompressAsJPG(b, saveFilePath, 80);
254
}
255
catch
{ ;}
256
finally
257
{
258
b.Dispose();
259
image.Dispose();
260
}
261
}
262
263
/**//// <summary>
264
/// 给图片添加文字水印
265
/// </summary>
266
/// <param name="sourcePath">源图片的存储地址</param>
267
/// <param name="text">水印文字</param>
268
/// <param name="saveFilePath">目标图片的存储地址</param>
269
/// <param name="mp">水印位置</param>
270
public static void AddTextWatermarkAsJPG(string sourcePath, string text, string saveFilePath, MarkPosition mp)
271
{
272
if (File.Exists(sourcePath))
273
{
274
using (StreamReader sr = new StreamReader(sourcePath))
275
{
276
AddTextWatermarkAsJPG(sr.BaseStream, text, saveFilePath, mp);
277
}
278
}
279
}
280
281
/**//// <summary>
282
/// 添加文字水印
283
/// </summary>
284
/// <param name="picture">要加水印的原图像</param>
285
/// <param name="text">水印文字</param>
286
/// <param name="mp">添加的位置</param>
287
/// <param name="width">原图像的宽度</param>
288
/// <param name="height">原图像的高度</param>
289
private static void AddWatermarkText(Graphics picture, string text, MarkPosition mp, int width, int height)
290
{
291
int[] sizes = new int[]
{ 16, 14, 12, 10, 8, 6, 4 };
292
Font crFont = null;
293
SizeF crSize = new SizeF();
294
for (int i = 0; i < 7; i++)
295
{
296
crFont = new Font("Arial", sizes[i], FontStyle.Bold);
297
crSize = picture.MeasureString(text, crFont);
298
299
if ((ushort)crSize.Width < (ushort)width)
300
break;
301
}
302
303
float xpos = 0;
304
float ypos = 0;
305
306
switch (mp)
307
{
308
case MarkPosition.MP_Left_Top:
309
xpos = ((float)width * (float).01) + (crSize.Width / 2);
310
ypos = (float)height * (float).01;
311
break;
312
case MarkPosition.MP_Right_Top:
313
xpos = ((float)width * (float).99) - (crSize.Width / 2);
314
ypos = (float)height * (float).01;
315
break;
316
case MarkPosition.MP_Right_Bottom:
317
xpos = ((float)width * (float).99) - (crSize.Width / 2);
318
ypos = ((float)height * (float).99) - crSize.Height;
319
break;
320
case MarkPosition.MP_Left_Bottom:
321
xpos = ((float)width * (float).01) + (crSize.Width / 2);
322
ypos = ((float)height * (float).99) - crSize.Height;
323
break;
324
}
325
326
StringFormat StrFormat = new StringFormat();
327
StrFormat.Alignment = StringAlignment.Center;
328
329
SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(153, 0, 0, 0));
330
picture.DrawString(text, crFont, semiTransBrush2, xpos + 1, ypos + 1, StrFormat);
331
332
SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));
333
picture.DrawString(text, crFont, semiTransBrush, xpos, ypos, StrFormat);
334
335
semiTransBrush2.Dispose();
336
semiTransBrush.Dispose();
337
338
}
339
340
/**//// <summary>
341
/// 添加图片水印
342
/// </summary>
343
/// <param name="picture">要加水印的原图像</param>
344
/// <param name="waterMarkPath">水印文件的物理地址</param>
345
/// <param name="mp">添加的位置</param>
346
/// <param name="width">原图像的宽度</param>
347
/// <param name="height">原图像的高度</param>
348
private static void AddWatermarkImage(Graphics picture, string waterMarkPath, MarkPosition mp, int width, int height)
349
{
350
Image watermark = new Bitmap(waterMarkPath);
351
352
ImageAttributes imageAttributes = new ImageAttributes();
353
ColorMap colorMap = new ColorMap();
354
355
colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
356
colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
357
ColorMap[] remapTable =
{ colorMap };
358
359
imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
360
361
float[][] colorMatrixElements =
{
362
new float[]
{1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
363
new float[]
{0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
364
new float[]
{0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
365
new float[]
{0.0f, 0.0f, 0.0f, 0.3f, 0.0f},
366
new float[]
{0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
367
};
368
369
ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);
370
371
imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
372
373
int xpos = 0;
374
int ypos = 0;
375
int WatermarkWidth = 0;
376
int WatermarkHeight = 0;
377
double bl = 1d;
378
if ((width > watermark.Width * 4) && (height > watermark.Height * 4))
379
{
380
bl = 1;
381
}
382
else if ((width > watermark.Width * 4) && (height < watermark.Height * 4))
383
{
384
bl = Convert.ToDouble(height / 4) / Convert.ToDouble(watermark.Height);
385
386
}
387
else
388
389
if ((width < watermark.Width * 4) && (height > watermark.Height * 4))
390
{
391
bl = Convert.ToDouble(width / 4) / Convert.ToDouble(watermark.Width);
392
}
393
else
394
{
395
if ((width * watermark.Height) > (height * watermark.Width))
396
{
397
bl = Convert.ToDouble(height / 4) / Convert.ToDouble(watermark.Height);
398
399
}
400
else
401
{
402
bl = Convert.ToDouble(width / 4) / Convert.ToDouble(watermark.Width);
403
404
}
405
406
}
407
408
WatermarkWidth = Convert.ToInt32(watermark.Width * bl);
409
WatermarkHeight = Convert.ToInt32(watermark.Height * bl);
410
411
412
switch (mp)
413
{
414
case MarkPosition.MP_Left_Top:
415
xpos = 10;
416
ypos = 10;
417
break;
418
case MarkPosition.MP_Right_Top:
419
xpos = width - WatermarkWidth - 10;
420
ypos = 10;
421
break;
422
case MarkPosition.MP_Right_Bottom:
423
xpos = width - WatermarkWidth - 10;
424
ypos = height - WatermarkHeight - 10;
425
break;
426
case MarkPosition.MP_Left_Bottom:
427
xpos = 10;
428
ypos = height - WatermarkHeight - 10;
429
break;
430
}
431
432
picture.DrawImage(watermark, new Rectangle(xpos, ypos, WatermarkWidth, WatermarkHeight), 0, 0, watermark.Width, watermark.Height, GraphicsUnit.Pixel, imageAttributes);
433
434
435
watermark.Dispose();
436
imageAttributes.Dispose();
437
}
438
439
/**//// <summary>
440
/// 水印的位置
441
/// </summary>
442
public enum MarkPosition
443
{
444
/**//// <summary>
445
/// 左上角
446
/// </summary>
447
MP_Left_Top,
448
449
/**//// <summary>
450
/// 左下角
451
/// </summary>
452
MP_Left_Bottom,
453
454
/**//// <summary>
455
/// 右上角
456
/// </summary>
457
MP_Right_Top,
458
459
/**//// <summary>
460
/// 右下角
461
/// </summary>
462
MP_Right_Bottom
463
}
464
465
466
#endregion
467
468
}
469
}
470