對(duì)于縮率圖的處理是在圖片上傳到服務(wù)器之后,同步生成兩張不同尺寸的縮率供前端調(diào)用,剛開始還能滿足需求,慢慢的隨著前端展示的多樣化,縮率圖已不能前端展示的需求,所以考慮做一個(gè)實(shí)時(shí)生成圖片縮率圖服務(wù)。
每次調(diào)用實(shí)時(shí)生成縮率圖,不緩存著實(shí)有點(diǎn)浪費(fèi),所以在生成縮率的同時(shí)緩存到硬盤一份,效率提高很多。
之前從網(wǎng)上看了一下有人用nginx + lua實(shí)現(xiàn)的,效率那是沒什么可說的,但是時(shí)間緊迫,自己也沒時(shí)間去研究,所以暫時(shí)先用aps.net mvc4來實(shí)現(xiàn) 一個(gè),以后有時(shí)間了,再慢慢修改。
用自己熟悉的.net性能可能差那么一點(diǎn)點(diǎn),但是實(shí)現(xiàn)速度快,保證可以在極端的時(shí)間內(nèi)上線,并且在功能上更強(qiáng)。
思路很簡單,就是根據(jù)請(qǐng)求,判斷需要的縮率圖是否已存在于硬盤上,如果有直接返回,沒有則下載原圖,并生成縮率圖到本地,返回給客戶端。
下面直接粘貼代碼片段:
/// summary>
/// 生成圖片縮率圖Action
/// /summary>
/// param name="p">原圖url/param>
/// param name="id">圖片尺寸以及生成縮率圖的類型/param>
/// returns>/returns>
[ValidateInput(false)]
public ActionResult Index(string p, string id)
{
if (string.IsNullOrEmpty(p))
{
return new HttpStatusCodeResult(404);
}
string oPath = Regex.Replace(p, @"http[s]?://(.*?)/", "/", RegexOptions.IgnoreCase);
int? oWidth = 200, oHeight = 200;
int cutMode = 3;
string pPath;
string oDir;
if (!string.IsNullOrEmpty(id))
{
string[] ss = id.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
if (ss.Length 2)
{
return new HttpStatusCodeResult(404);
}
if (ss.Length > 2)
{
cutMode = int.Parse(ss[2]);
}
oPath = oPath.Insert(oPath.LastIndexOf('/') + 1, string.Format("{0}_{1}_{2}_", ss[0], ss[1], cutMode));
oWidth = int.Parse(ss[0]);
oHeight = int.Parse(ss[1]);
}
pPath = Server.MapPath(oPath);
oDir = Path.GetDirectoryName(pPath);
if (!System.IO.File.Exists(pPath))
{
byte[] imagebytes = FileHelper.DownLoadFile(p);
if (!Directory.Exists(oDir))
{
Directory.CreateDirectory(oDir);
}
FileHelper.MakeThumbnail(FileHelper.BytToImg(imagebytes), oWidth.Value, oHeight.Value, (ThumbnailMode)cutMode, pPath, true);
}
return File(pPath, FileHelper.GetContentTypeByExtension(Path.GetExtension(pPath).ToLower()));
}
輔助方法:
public class FileHelper
{
/// summary>
/// 圖片后綴和ContentType對(duì)應(yīng)字典
/// /summary>
static Dictionarystring, string> extensionContentTypeDic;
static FileHelper()
{
if (extensionContentTypeDic == null)
{
//.jpg", ".png", ".gif", ".jpeg
extensionContentTypeDic = new Dictionarystring, string>();
extensionContentTypeDic.Add(".jpg", "image/jpeg");
extensionContentTypeDic.Add(".png", "image/png");
extensionContentTypeDic.Add(".gif", "image/gif");
extensionContentTypeDic.Add(".jpeg", "image/jpeg");
}
}
/// summary>
/// 根據(jù)后綴名獲取extension
/// /summary>
/// param name="extension">/param>
/// returns>/returns>
public static string GetContentTypeByExtension(string extension)
{
if (extensionContentTypeDic.ContainsKey(extension))
{
return extensionContentTypeDic[extension];
}
return null;
}
/// summary >
/// 將Image對(duì)象轉(zhuǎn)化成二進(jìn)制流
/// /summary >
/// param name="image" > /param >
/// returns > /returns >
public static byte[] ImageToByteArray(Image image)
{
MemoryStream imageStream = new MemoryStream();
Bitmap bmp = new Bitmap(image.Width, image.Height);
Graphics g = Graphics.FromImage(bmp);
g.DrawImage(image, new System.Drawing.Rectangle(0, 0, image.Width, image.Height));
try
{
bmp.Save(imageStream, image.RawFormat);
}
catch (Exception e)
{
bmp.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
byte[] byteImg = imageStream.GetBuffer();
bmp.Dispose();
g.Dispose();
imageStream.Close();
return byteImg;
}
/// summary>
/// 字節(jié)流轉(zhuǎn)換成圖片
/// /summary>
/// param name="byt">要轉(zhuǎn)換的字節(jié)流/param>
/// returns>轉(zhuǎn)換得到的Image對(duì)象/returns>
public static Image BytToImg(byte[] byt)
{
MemoryStream ms = new MemoryStream(byt);
Image img = Image.FromStream(ms);
ms.Close();
return img;
}
/// summary>
/// 生成縮率圖
/// /summary>
/// param name="originalImage">原始圖片Image/param>
/// param name="width">縮率圖寬/param>
/// param name="height">縮率圖高/param>
/// param name="mode">生成縮率圖的方式/param>
/// param name="thumbnailPath">縮率圖存放的地址/param>
public static Image MakeThumbnail(Image originalImage, int width, int height, ThumbnailMode mode, string thumbnailPath, bool isSave = true)
{
int towidth = width;
int toheight = height;
int x = 0;
int y = 0;
int ow = originalImage.Width;
int oh = originalImage.Height;
switch (mode)
{
case ThumbnailMode.HW://指定高寬縮放(可能變形)
break;
case ThumbnailMode.W://指定寬,高按比例
toheight = originalImage.Height * width / originalImage.Width;
break;
case ThumbnailMode.H://指定高,寬按比例
towidth = originalImage.Width * height / originalImage.Height;
break;
case ThumbnailMode.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;
}
//新建一個(gè)bmp圖片
System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);
//新建一個(gè)畫板
Graphics g = System.Drawing.Graphics.FromImage(bitmap);
//設(shè)置高質(zhì)量插值法
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
//設(shè)置高質(zhì)量,低速度呈現(xiàn)平滑程度
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//清空畫布并以透明背景色填充
g.Clear(Color.Transparent);
//在指定位置并且按指定大小繪制原圖片的指定部分
g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight),
new Rectangle(x, y, ow, oh),
GraphicsUnit.Pixel);
if (!isSave)
{
return bitmap;
}
try
{
//以jpg格式保存縮略圖
//bitmap.Save(thumbnailPath, bitmap.RawFormat);
bitmap.Save(thumbnailPath, ImageFormat.Jpeg);
return bitmap;
}
catch (System.Exception e)
{
throw e;
}
finally
{
originalImage.Dispose();
bitmap.Dispose();
g.Dispose();
}
return null;
}
/// summary>
/// 下載指定文件
/// /summary>
/// param name="remoteUrl">/param>
/// param name="ss">/param>
public static byte[] DownLoadFile(string remoteUrl)
{
WebClient wc = new WebClient();
try
{
return wc.DownloadData(remoteUrl);
}
catch (Exception e)
{
throw new Exception("下載文件失敗");
}
}
}
public enum ThumbnailMode
{
/// summary>
/// 指定高寬縮放(可能變形)
/// /summary>
HW,
/// summary>
/// 指定高,寬按比例
/// /summary>
H,
/// summary>
/// 指定寬,高按比例
/// /summary>
W,
/// summary>
/// 指定高寬裁減(不變形)
/// /summary>
Cut,
}
訪問方式:
http://www.souji8.com/Home/Index/{width}_{height}_{ThumMode}?p={imageUrl}
{imageUrl}:目標(biāo)圖片地址
{ThumMode}: 1:指定高寬按比例、2:指定寬,高按比例、3:指定高寬裁減(不變形)
{Width}:期望圖片寬
{Height}:期望圖片高
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。
您可能感興趣的文章:- ASP.NET設(shè)計(jì)網(wǎng)絡(luò)硬盤之文件夾實(shí)現(xiàn)
- asp.net 網(wǎng)絡(luò)硬盤實(shí)現(xiàn)分析
- ASP.NET+XML打造網(wǎng)絡(luò)硬盤原理分析
- ASP.NET設(shè)計(jì)網(wǎng)絡(luò)硬盤之兩重要類代碼
- ASP.NET設(shè)計(jì)網(wǎng)絡(luò)硬盤之查看文件夾實(shí)現(xiàn)代碼
- ASP.NET設(shè)計(jì)網(wǎng)絡(luò)硬盤之上傳文件實(shí)現(xiàn)代碼
- ASP.NET設(shè)計(jì)網(wǎng)絡(luò)硬盤之下載或在線查看實(shí)現(xiàn)代碼
- ASP.NET設(shè)計(jì)網(wǎng)絡(luò)硬盤之刪除文件夾實(shí)現(xiàn)代碼