1 /// <summary> 图像处理模式
2 /// </summary>
3 public enum ImageSizeMode
4 {
5 /// <summary> 原图,不做其他处理
6 /// </summary>
7 [CustomAttribute.Custom("原图", "N")]
8 None,
9
10 /// <summary> 居中 固定中心 剪裁或者留黑
11 /// </summary>
12 [CustomAttribute.Custom("居中", "C")]
13 Center,
14
15 /// <summary> 拉伸 变形 铺满
16 /// </summary>
17 [CustomAttribute.Custom("拉伸", "S")]
18 Stretch,
19
20 /// <summary> 适应 保持比率 留黑边
21 /// </summary>
22 [CustomAttribute.Custom("适应", "A")]
23 Adaptive,
24
25 /// <summary> 填充 保持比率 剪裁多余部分
26 /// </summary>
27 [CustomAttribute.Custom("填充", "F")]
28 Fill
29 }
30
31 /// <summary> 图像缓存
32 /// </summary>
33 public class ImageCache
34 {
35 /// <summary> 文件路径
36 /// </summary>
37 public string FullName { get; set; }
38
39 /// <summary> 数据
40 /// </summary>
41 public byte[] Data { get; set; }
42
43 /// <summary> 最后访问时间
44 /// </summary>
45 public DateTime LastTime { get; set; }
46 }
47
48 /// <summary> 图片资源库
49 /// </summary>
50 public class ImageResources
51 {
52 public static ImageResources Current
53 {
54 get { return _current; }
55 }
56
57 public ImageResources()
58 {
59 _path = Application.StartupPath + "\\";
60 CacheList = new Dictionary<string, ImageCache>();
61 }
62
63 ImageDraw draw = new ImageDraw();
64
65 private string _path;
66 private static readonly ImageResources _current = new ImageResources();
67
68 /// <summary> 图片存放路径 \ 结尾
69 /// </summary>
70 public string Path
71 {
72 get { return _path; }
73 set
74 {
75 _path = value.TrimEnd('/').TrimEnd('\\') + "\\";
76 if (!Directory.Exists(_path))
77 {
78 Directory.CreateDirectory(_path);
79 }
80 }
81 }
82
83 /// <summary> 缓存尺寸 MB 默认 1024
84 /// </summary>
85 public int CacheSize { get; set; }
86
87 /// <summary> 缓存 Key = Path Value.Key = 最后访问时间. Value.Value = 数据
88 /// </summary>
89 public Dictionary<string, ImageCache> CacheList { get; set; }
90
91 /// <summary> 通过网络路径添加图像
92 /// </summary>
93 /// <param name="name"></param>
94 /// <param name="src"></param>
95 public void AddImageBySrc(string name, string src)
96 {
97 var wr = WebRequest.Create(src) as WebRequest;
98
99 var rs = wr.GetResponse().GetResponseStream();
100 var im = Image.FromStream(rs);
101
102 im.Save(Path + name);
103 }
104
105 /// <summary> 添加图像
106 /// </summary>
107 /// <param name="name"></param>
108 /// <param name="data"> </param>
109 public void AddImage(string name, byte[] data)
110 {
111 lock (Path)
112 {
113 File.WriteAllBytes(Path + name, data);
114 }
115 }
116
117 /// <summary> 添加图像
118 /// </summary>
119 /// <param name="name"></param>
120 /// <param name="data"></param>
121 public void AddImage(string name, HttpPostedFileBase data)
122 {
123 lock (Path)
124 {
125 data.SaveAs(Path + name);
126 }
127 }
128
129 /// <summary> 获取图像
130 /// </summary>
131 /// <param name="param"></param>
132 /// <returns></returns>
133 public byte[] GetImageByParam(string param)
134 {
135 var ii = param.FromJsone<ImageInfo>();
136
137 var bs = Current.GetImage(ii.N, new Size(ii.W, ii.H), ii.M.As(ImageSizeMode.None), ii.Q);
138
139 return bs;
140 }
141
142 /// <summary> 获取图像
143 /// </summary>
144 /// <param name="name"></param>
145 /// <param name="size"></param>
146 /// <param name="quality"> </param>
147 /// <param name="sizeModule"> </param>
148 public byte[] GetImage(string name, Size? size = null, ImageSizeMode sizeModule = ImageSizeMode.None, int quality = 90)
149 {
150 if (name.IsNullOrEmpty())
151 {
152 name = "Null.jpg";
153 }
154
155 string fn;
156 var isReturnSource = (size == null || sizeModule == ImageSizeMode.None);
157
158 if (isReturnSource)
159 {
160 fn = Path + name;
161 }
162 else
163 {
164 fn = Path + sizeModule.Value() + "_" + quality + "_" + size.Value.Width + "," + size.Value.Height + "/"
165 + name + ".jpg";
166 }
167
168 var value = CacheList.TryGet(fn, () =>
169 {
170 try
171 {
172 lock (this)
173 {
174 byte[] data;
175 if (File.Exists(fn))
176 {
177 //缓存文件存在,直接返回
178 data = File.ReadAllBytes(fn);
179 }
180 else
181 {
182 // ReSharper disable PossibleInvalidOperationException
183 if (!File.Exists(Path + name))
184 {
185 //图片丢失
186 name = "NoFind.jpg";
187 if (!File.Exists(Path + name))
188 {
189 //NoFind.jpg 也不存在.
190 return null;
191 }
192 }
193
194 if (isReturnSource)
195 {
196 //返回源图
197 return new ImageCache { Data = File.ReadAllBytes(Path + name) };
198 }
199
200 var img = Image.FromFile(Path + name);
201 var di = img;
202 switch (sizeModule)
203 //生成图片
204 {
205 case ImageSizeMode.Adaptive:
206 img = draw.GetAdaptiveImage(img, size.Value);
207 break;
208 case ImageSizeMode.Fill:
209 img = draw.GetFillImage(img, size.Value);
210 break;
211 case ImageSizeMode.Stretch:
212 img = draw.GetStretchImage(img, size.Value);
213 break;
214 default:
215 //没时间写.
216 throw new Exception("未知的图像处理方式!");
217 }
218
219 di.Dispose();
220
221 draw.SaveImageToJpeg(img, fn, quality);
222
223 data = GetImage(name, size, sizeModule, quality);
224 }
225 return new ImageCache { Data = data };
226 }
227 }
228 catch (Exception ex)
229 {
230 if (Query.Ip.IsIn("::1", "127.0.0.1"))
231 {
232 throw (ex.Message).ToException();
233 }
234 return null;
235 }
236 });
237
238 value.IsNotNull(j => j.LastTime = DateTime.Now);
239 return value.NotNull(j => j.Data);
240 }
241
242 /// <summary> 图像信息 用于 ToJsone
243 /// </summary>
244 private class ImageInfo
245 {
246 /// <summary> mode
247 /// </summary>
248 public string M { get; set; }
249
250 /// <summary> width
251 /// </summary>
252 public int W { get; set; }
253
254 /// <summary> height
255 /// </summary>
256 public int H { get; set; }
257
258 /// <summary> name
259 /// </summary>
260 public string N { get; set; }
261
262 /// <summary> Quality
263 /// </summary>
264 public int Q { get; set; }
265 }
266
267 /// <summary> 获取文件参数
268 /// </summary>
269 /// <returns></returns>
270 public string GetImageParam(string name, ImageSizeMode mode = ImageSizeMode.None, int width = 0, int height = 0, int quality = 90)
271 {
272 var ii = new ImageInfo { N = name, M = mode.As(""), H = height, W = width, Q = quality };
273
274 return ii.ToJsone();
275 }
276
277 /// <summary> 获取ImageUrl
278 /// </summary>
279 /// <param name="name"></param>
280 /// <param name="mode"></param>
281 /// <param name="width"></param>
282 /// <param name="height"></param>
283 /// <returns></returns>
284 public string GetImageUrl(string name, ImageSizeMode mode = ImageSizeMode.None, int width = 0, int height = 0, int quality = 90)
285 {
286 return "/Image/" + GetImageParam(name, mode, width, height, quality);
287 }
288
289 /// <summary> 清理缩略图文件缓存
290 /// </summary>
291 public void ClearFileCache()
292 {
293 var ps = Directory.GetDirectories(Path);
294
295 foreach (var s in ps)
296 {
297 try
298 {
299 Directory.Delete(s, true);
300 }
301 catch
302 { }
303 }
304 }
305 }
306 }