您的位置:首页 > 其它

关于缩略图的生成与访问策略的一些经验分享

2012-09-02 15:07 459 查看
之前在一家做图片分享的互联网公司上班,由于一系列的因素公司业务关停,我们不得不另谋出路。不过还是很感谢公司为我们提供了一个相对宽松的工作环境,同时也让我们体会到了一个创业公司的激情与困惑。

今天就跟大家说说缩略图的那些事儿,以此来做为一个总结和纪念。

对于项目来说,不管大小一般都或多或少的存在一些图片,有时候我们需要用代码对图片进行一些处理,比如加个水印、生成个缩略图等,这些都是比较普通的需求了。为了让大家对接下来的需求有一个直观的了解,我们还是先来看一些截图

View Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using ImgService.Helpers;
using System.Text.RegularExpressions;
using ImgService.EF;
using ImgService.EF.Domain;
using System.Drawing;
using System.IO;

namespace ImgService.Controllers
{
public class ServiceController : Controller
{
private ImgServiceContext DB = new ImgServiceContext();

public FileResult Thumbnail(string key = "")
{
//1.从缓存提取图片
//2.缓存没有,读取缩略图文件
//3.缩略图不存在,读取图片源文件。生成缩略图,加入缓存
key = key.ToLower();
if (string.IsNullOrEmpty(key)) { return null; }
byte[] bytes = null;

//正则分析Key的内容,可匹配的格式如 43sdfwerw345343ff_s_150.jpg 或 43sdfwerw345343ff_w_800.jpg 等
string rule = @"(?<p1>([a-z0-9]+)_(s|w)_([\d]+)\.(jpg|png|bmp|tif|tiff))";

Match match = Regex.Match(key, rule, RegexOptions.IgnoreCase);
if (match.Success)
{
string type = ""; //s或w
int imgSize = 200;
Bitmap originalBitmap = null;
Bitmap thumbnaiBitmap = null;
MemoryStream ms = null;

type = match.Groups[2].Value.Trim().ToLower();
int.TryParse(match.Groups[3].Value, out imgSize);

//确认请求的缩略图是否在系统生成范围之内,验证合法性
ThumbnailImage thumbnailData = GetThumbnail(key);
if (thumbnailData != null)
{
//查询缓存
bytes = ImageCacheHelper.GetImageCache(key);
if (bytes != null && bytes.Length > 0)
{
return File(bytes, "image/jpeg");
}

//缓存不存在,从文件读取缩略图
bytes = ImageHelper.GetImageBytes(Server.MapPath(thumbnailData.Path));
if (bytes != null && bytes.Length > 0) //缩略图文件存在
{
ImageCacheHelper.SetImageCahce(key, bytes);
return File(bytes, "image/jpeg");
}
else  //缩略图不存在,读原图生成缩略图
{
bytes = ImageHelper.GetImageBytes(Server.MapPath( thumbnailData.OriginalImage.Path ));
if (bytes != null && bytes.Length > 0) //原图存在
{
ms = new MemoryStream(bytes);
originalBitmap = new Bitmap(ms);

if (type == "s")
{
thumbnaiBitmap = ImageHelper.Resize(originalBitmap, imgSize);//生成缩略图
}

if (type == "w")
{
thumbnaiBitmap = ImageHelper.ResizeW(originalBitmap, imgSize);//生成缩略图
}

thumbnaiBitmap.Save(Server.MapPath(thumbnailData.Path)); //保存缩略图
bytes = ImageHelper.GetImageBytes(Server.MapPath(thumbnailData.Path));
ImageCacheHelper.SetImageCahce(key, bytes);//把缩略图放入缓存

ms.Dispose();
originalBitmap.Dispose();
thumbnaiBitmap.Dispose();
return File(bytes, "image/jpeg");

}
else  //原图不存在
{
return File(Server.MapPath("~/404.jpg"), "image/jpeg");
}
}
}
else
{
return File(Server.MapPath("~/404.jpg"), "image/jpeg");
}
}
else
{
return File(Server.MapPath("~/404.jpg"), "image/jpeg");
}
}

private ThumbnailImage GetThumbnail(string key)
{
var q = from t in DB.ThumbnailImages
where
t.ID == key
select t;
var imgList = q.ToList();
if (imgList == null || imgList.Count == 0)
{
return null;
}
return imgList.First();
}
}
}


5.自定义路由规则,让缩略图地址更友好

如果没有自定义路由规则的话,那么缩略图的访问地址应该类似这样。http://www.caidian.com/Thumbnail?key=d92fe65928bc48a8b9ac47d771dad56e_s_200.jpg

这样的地址给人的第一印象会让人觉着不是一个纯粹的图片地址,所以我对它进行了路由规则的重写,来看看代码

Global.asax.cs

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

//为缩略图的访问配置一个比较友好的地址,访问的地址一般如下
//http://localhost:1087/Thumbnail/d92fe65928bc48a8b9ac47d771dad56e_s_200.jpg
//http://localhost:1087/Thumbnail/d92fe65928bc48a8b9ac47d771dad56e_w_800.jpg
routes.MapRoute(
"ImgService", // Route name
"thumbnail/{key}", // URL with parameters
new { controller = "Service", action = "Thumbnail", key = "" } // Parameter defaults
);

//照片列表,访问的地址一般如下
//http://localhost:1087/photos
routes.MapRoute(
"Client-photos", // Route name
"photos", // URL with parameters
new { controller = "Client", action = "Index"} // Parameter defaults
);

//单张照片,访问的地址一般如下
//http://localhost:1087/photo/61e69dc5a92940ad86d9d419c496324d
routes.MapRoute(
"Client-photo", // Route name
"photo/{key}", // URL with parameters
new { controller = "Client", action = "Photo", key = "" } // Parameter defaults
);

//这里请注意,默认的路由配置放在自定义配置后面,否则不认自定义路由规则
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Manage", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}


6.关于如何运行程序的注意事项

下载源码,然后修改web.config中的数据库连接字符串,依你个人的环境而定。

<connectionStrings>
<add name="ImgServiceDB" connectionString="server=.;uid=sa;pwd=123456;database=ImgServiceDB" providerName="System.Data.SqlClient"/>
</connectionStrings>


接下来就是运行程序了,会自动的跳转到照片上传页面,由于里面没有任何照片数据所以你必须先进行上传,接下来就是看照片了... ...很简单

当然本项目只是一个很简单的范例程序,真正要开发一套大数据量,高并发的图片分享网站光有这点知识是远远不够的,我在这里也只是算抛砖引玉吧。

最后,感谢你了浏览到这里,如果你觉得有点收获的话不妨点击推荐。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: