主要利用Imazen.WebP.dll来生成Webp格式图片
namespace Melon.AspNet.Base.Handler
{
/// <summary>
/// 图片路径格式:{域名}/原始文件或{域名}/原始文件_{指定大小}或{域名}/原始文件_{指定大小}_{_webp}
/// http://demo.vdn.com/2018/01/1201454885412.png_250x250.png._webp或
/// http://demo.vdn.com/2018/01/1201454885412.png_250x250.png或
/// http://demo.vdn.com/2018/01/1201454885412.png
/// </summary>
public class WebPHandler : IHttpHandler
{
public bool IsReusable
{
get
{
return false;
}
}
public void ProcessRequest(HttpContext context)
{
try
{
HttpRequest request = context.Request;
HttpResponse response = context.Response;
string type = "";
string contenttype = "image/jpeg";
string cachekey = string.Empty;
string img_path = request.Url.LocalPath;//请求的图片路径
type = Path.GetExtension(img_path);
switch (type)
{
case ".webp": contenttype = "image/webp"; break;
case ".jpeg": contenttype = "image/jpeg"; break;
case ".jpg": contenttype = "image/jpeg"; break;
case ".png": contenttype = "image/png"; break;
case ".gif": contenttype = "image/gif"; break;
default: contenttype= "image/jpeg"; break;
}
//如果文件存在直接返回
if (File.Exists(context.Server.MapPath(img_path)))
{
response.ContentType = contenttype;
response.WriteFile(context.Server.MapPath(img_path));
return;
}
string[] arr_path = img_path.Split('_');
if (arr_path == null || arr_path.Length > 3) return;
string ori_filepath = arr_path[0]; //原始文件
ImageSize img_size = new Handler.ImageSize();//缩略图的图片大小
if (File.Exists(context.Server.MapPath(ori_filepath)) && !File.Exists(context.Server.MapPath(img_path)))
{
if (arr_path.Length == 2)
{
if (type == ".webp")//返回指定原图的webp格式图片
{
Melon.WebP.WebPHelper.ConvertNormalToWebp(context.Server.MapPath(ori_filepath), context.Server.MapPath(img_path), 80);
}
else
{
//创建返回指定大小的缩略图
img_size = GetImageSize(arr_path[1]);
ImageTools.CreateSmallImageNoChange(context.Server.MapPath(ori_filepath), context.Server.MapPath(img_path), img_size.width, img_size.height);
}
}
if (arr_path.Length == 3)//返回指定大小的webp格式图片
{
img_size = GetImageSize(arr_path[1]);
Melon.WebP.WebPHelper.ConvertNormalToWebp(context.Server.MapPath(ori_filepath), context.Server.MapPath(img_path), 80, img_size.width, img_size.height);
}
}
if (File.Exists(context.Server.MapPath(img_path)))
{
response.ContentType = contenttype;
response.WriteFile(context.Server.MapPath(img_path));
}
else
{
context.Response.ContentType = contenttype;
context.Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
}
}
catch (Exception ex)
{
throw ex;
}
}
private ImageSize GetImageSize(string size_str)
{
ImageSize img_size = new ImageSize();
string[] arr_size = size_str.Substring(0, size_str.IndexOf(".")).Split('x');
if (arr_size.Length == 1)
{
img_size.width = arr_size[0].ToInt32();//缩略图的宽
img_size.height = img_size.width;
}
if (arr_size.Length == 2)
{
img_size.width = arr_size[0].ToInt32();//缩略图的宽
img_size.height = arr_size[1].ToInt32();
}
return img_size;
}
}
class ImageSize
{
public int width { get; set; }
public int height { get; set; }
}
}
public class WebPHelper
{
/// <summary>
///
/// </summary>
/// <param name="filepath">WebP图片的完整路径</param>
/// <returns></returns>
static Bitmap LoadFromFile(string filepath)
{
if (!File.Exists(filepath)) throw new Exception("文件不存在"+ filepath);
byte[] bs = File.ReadAllBytes(filepath);
return new SimpleDecoder().DecodeFromBytes(bs, bs.Length);
}
/// <summary>
/// 将Webp格式图片转换成普通图片文件格式
/// </summary>
/// <param name="iSourceFilename">待转换的源Webp格式图片地址</param>
/// <param name="iDestinationFilename">转换后的目标图片保存完整地址</param>
/// <param name="iFormat">普通图片格式</param>
/// <returns></returns>
public static bool ConvertWebpToNormal(string iSourceFilename, string iDestinationFilename, ImageFormat iFormat=null)
{
try
{
if (Path.GetExtension(iSourceFilename).ToLower() != ".webp") throw new Exception("不是webp图片格式文件");
using (Bitmap image = LoadFromFile(iSourceFilename))
{
if (iFormat != null)
image.Save(iDestinationFilename, iFormat);
else
image.Save(iDestinationFilename);
}
}
catch (Exception ex)
{
throw ex;
}
return true;
}
/// <summary>
/// 将普通图片文件格式转换成Webp格式图片
/// </summary>
/// <param name="iSourceFilename">待转换的源普通图片文件地址</param>
/// <param name="iDestinationFilename">转换后的目标图片保存完整地址</param>
/// <param name="quality">图片质量(0-100)</param>
/// <returns></returns>
public static bool ConvertNormalToWebp(string iSourceFilename, string iDestinationFilename,float quality)
{
try
{
using (Image image = Image.FromFile(iSourceFilename))
{
//WebP只支持 Format32bppArgb 和 Format32bppRgb 两种像素格式
// 所以有时候需要改码,重绘一个图像
using (Bitmap bitmap = new Bitmap(image.Width, image.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
{
// 将图片重绘到新画布
using (Graphics g = Graphics.FromImage(bitmap))
{
g.DrawImage(image, 0, 0, image.Width, image.Height);
}
// 转码并保存文件
using (FileStream fs = File.Create(iDestinationFilename))
{
new Imazen.WebP.SimpleEncoder().Encode(bitmap, fs, quality);
}
}
}
}
catch (Exception ex)
{
throw ex;
}
return true;
}
/// <summary>
/// 将普通图片文件格式转换成Webp格式图片
/// </summary>
/// <param name="iSourceFilename">待转换的源普通图片文件地址</param>
/// <param name="iDestinationFilename">转换后的目标图片保存完整地址</param>
/// <param name="quality">图片质量(0-100)</param>
/// <returns></returns>
public static bool ConvertNormalToWebp(string iSourceFilename, string iDestinationFilename, float quality,int width,int height)
{
try
{
using (Image image = Image.FromFile(iSourceFilename))
{
//WebP只支持 Format32bppArgb 和 Format32bppRgb 两种像素格式
// 所以有时候需要改码,重绘一个图像
int x = 0; //缩略图在画布上的X放向起始点
int y = 0; //缩略图在画布上的Y放向起始点
int dw = 0;
int dh = 0;
if ((double)image.Width / (double)image.Height > (double)width / (double)height)
{
//宽比高大,以宽为准
dw = width;
dh = image.Height * dw / image.Width;
x = 0;
y = (height - dh) / 2;
}
else
{
//高比宽大,以高为准
dh = height;
dw = image.Width * dh / image.Height;
x = (width - dw) / 2;
y = 0;
}
using (Bitmap bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
{
// 将图片重绘到新画布
using (Graphics g = Graphics.FromImage(bitmap))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default; //设置高质量插值法
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;//设置高质量,低速度呈现平滑程度
g.Clear(Color.Transparent); //清空画布并以透明背景色填充
g.DrawImage(image, new Rectangle(x, y, dw, dh), new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);
}
// 转码并保存文件
using (FileStream fs = File.Create(iDestinationFilename))
{
new Imazen.WebP.SimpleEncoder().Encode(bitmap, fs, quality);
}
}
}
}
catch (Exception ex)
{
throw ex;
}
return true;
}
}