web实现QQ头像上传截取功能
由于最近一段时间比较忙,发现好久没写博客了,给大家分享下最近搞的logo上传截取功能。在实现这个功能之前找了一些jq的插件,最后选定了cropper在github中可以找到。
具体的思路是1:选择上传的图片,在change事件中用form.jquery.js中的formajax异步提交表单,保存上传的图片
2:绑定cooper事件,对图片进行选取。
3:得到选中区域的坐标,对图片进行截取保存。
其中的难点是ie的兼容性问题,由于本人也不是很好,就不献丑了下面给大家附上代码
页面中的html
<div class="input">
<div><span class="xuanze">选择</span><input type="file" class="file" name="file" id="file" onchange="change()" /><span class="jpeg">支持jpg、jpeg、gif、png、bmp格式的图片</span></div> <div class="xiechneg"> <span class="daxc"> @{ var url = Model.LogoMiddleUrl == null ? "" : Model.LogoMiddleUrl; var path200 = ReadConfig.GetHostUrl("Host") + url; } <img src="@path200" width="118" height="49" alt="" /> </span><i class="dxgou"></i><i class="dxcha"></i><span class="shuzi01">200*80 </span> <span class="xiaoxc"> @{ var url1 = Model.LogoSmallUrl == null ? "" : Model.LogoSmallUrl; var path100 = ReadConfig.GetHostUrl("Host") + url1; } <img src="@path100" width="95" height="38" alt="" /> </span><i class="xiaoxgou"></i><i class="xiaoxcha"></i><span class="shuzi02">100*40 </span> </div> <div class="yzhz"> <div class="xiaoyz"> <div class="img-container"> <img src="/Content/img/xtsz/xiaoyizi.jpg" width="400" height="280" alt="" id="HeadPic" /> </div> <span class="logo">选择本地照片,上传编辑自己的LOGO</span> <span class="qd" onclick="SubmitHead()">确定</span> </div> <div class="ybXC"> <span class="lgyl">LOGO预览</span> <div class="img-preview preview-lg"> </div> <div class="img-preview preview-md"> </div> </div> </div> </div>
cropper下载地址http://jquery-plugins.net/image-cropper-jquery-image-cropping-plugin
form.jquery.js的下载地址 http://malsup.com/jquery/form/#download
页面的js
<script> function change() { var pic = document.getElementById("HeadPic"), file = document.getElementById("file"); var ext = file.value.substring(file.value.lastIndexOf(".") + 1).toLowerCase(); // gif在IE浏览器暂时无法显示 if (ext != 'png' && ext != 'jpg' && ext != 'jpeg') { alert("图片的格式必须为png或者jpg或者jpeg格式!"); return; } var isIE = navigator.userAgent.match(/MSIE/) != null, isIE6 = navigator.userAgent.match(/MSIE 6.0/) != null; if (isIE) { file.select(); file.blur(); var reallocalpath = document.selection.createRange().text; // IE6浏览器设置img的src为本地路径可以直接显示图片 if (isIE6) { pic.src = reallocalpath; } else { //// 非IE6版本的IE由于安全问题直接设置img的src无法显示本地图片,但是可以通过滤镜来实现 //pic.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='crop',src=\"" + reallocalpath + "\")"; //// 设置img的src为base64编码的透明图片 取消显示浏览器默认图片 //pic.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='; //CutPic(); $("#HeadForm").ajaxSubmit({ type: "POST", url: "/AjaxCommon/UpPic/", dataType: "text", success: function (data) { $("#HeadSrc").val(data); $("#HeadPic").attr("src", "@ReadConfig.GetHostUrl("Host")" + data); CutPic(); } }); } } else { html5Reader(file); } } function html5Reader(file) { var file = file.files[0]; var reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function (e) { var pic = document.getElementById("HeadPic"); pic.src = this.result; $("#HeadForm").ajaxSubmit({ type: "POST", url: "/AjaxCommon/UpPic/", dataType: "text", success: function (data) { $("#HeadSrc").val(data); CutPic(); } }); CutPic(); }; } function CutPic() { var $image = $('.img-container>img'); var options = { aspectRatio: 5 / 2, preview: '.img-preview', }; $image.cropper(options); } function SubmitHead() { $.NabianPost({ url: "/Handler/CutImage.ashx", data: { filesrc: $("#HeadPic").attr("src"), top: parseInt($(".cropper-move").offset().top - $(".cropper-canvas").offset().top), left: parseInt($(".cropper-move").offset().left - $(".cropper-canvas").offset().left), height: parseInt($(".cropper-move").css("height")), width: parseInt($(".cropper-move").css("width")), HeadSrc: $("#HeadSrc").val() }, callback: function (data) { if (data.status == "no") { alert("对不起上传失败"); } else { alert("上传成功"); window.location.reload(); } } }); } </script>
上传图片的方法
public ActionResult UpPic() { var file = Request.Files["file"]; if (file.ContentLength == 0) { return Content("请选择文件"); } if (file.ContentLength > 307200) { return Content("文件过大"); } int width = 0; int height = 0; string path = ReadEnum.GetFilePath((int)FilePath.GYS_Logo); string HostUrl = ReadConfig.GetHostUrl("HostUrl"); string finalPaht; Request.Files.Processing(HostUrl, path, 400, 280, 100, out finalPaht, "GYS_Logo", 11); string a = path; return Content(a); }
截取并保存截取后的图片的handler
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Web; using BCommon.common; using BLL.BLL; using Model.Model; namespace www.nabian.com.Handler { /// <summary> /// CutImage 的摘要说明 /// </summary> public class CutImage : IHttpHandler, System.Web.SessionState.IRequiresSessionState { /// <summary> /// 对图像的裁减操作主入口 /// </summary> /// <param name="context">所有HTTP请求的特定信息</param> public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/json"; string fileSource = context.Request["filesrc"]; //原文件路径和文件名 //文件保存路径 string HostUrl = ReadConfig.GetHostUrl("HostUrl"); //minilogo的保存路径 string path100 = ReadEnum.GetFilePath((int)FilePath.GYS_inLOGO100_40); string path200 = ReadEnum.GetFilePath((int)FilePath.GYS_inLOGO200_80); int cutY = int.Parse(context.Request["top"]); //Y轴坐标 int cutX = int.Parse(context.Request["left"]); //X轴坐标 int cutWidth = int.Parse(context.Request["width"]); //裁减宽度 int cutHeight = int.Parse(context.Request["height"]); //裁减高度 string HeadSrc = HostUrl + context.Request["HeadSrc"]; //裁减后上传 CutImg(HeadSrc, cutX, cutY, cutWidth, cutHeight, path100, "GYS_inLOGO100_40", context); CutImg(HeadSrc, cutX, cutY, cutWidth, cutHeight, path200, "GYS_inLOGO200_80", context); //如果文件存在,说明文件上传成功 if (File.Exists(HostUrl + path100) && File.Exists(HostUrl + path200)) { var user = (B_Com_User)context.Session["LoginUser"]; var com = new B_Com_CompanyBLL().SelectByID(user.CompanyID.ToString()); com.LogoUrl = HeadSrc; com.LogoMiddleUrl = path200; com.LogoSmallUrl = path100; if (new B_Com_CompanyBLL().UpdateLogoById(com)) { context.Response.Write("{\"status\":\"ok\"}"); } else { context.Response.Write("{\"status\":\"no\"}"); } } else { context.Response.Write("{\"status\":\"error\"}"); } } /// <summary> /// 从指定路径中获取图片,按照指定位置及大小截取相应的图片内容,并保存到指定路径下 /// </summary> /// <param name="filepath">图片来源路径及文件名(已使用Server.MapPath)</param> /// <param name="cutX">裁减的起始X轴坐标</param> /// <param name="cutY">裁减的起始Y坐标</param> /// <param name="cutwidth">裁减的宽度</param> /// <param name="cutheight">裁减的高度</param> /// <param name="savepath">裁减后的图片名称,路径为上一级的images文件夹中</param> /// <param name="context">所有http特定的信息对象</param> void CutImg(string filepath, int cutX, int cutY, int cutwidth, int cutheight, string savepath, string fileName, HttpContext context) { //TODO 判断文件类型暂时未做 //创建图像对象,由于web中有个image控件,会导致这个图像的类重复,需要带上使用命名空间 System.Drawing.Image oldImage = System.Drawing.Image.FromFile(filepath); //创建一个指定宽高的图像对象 System.Drawing.Image newImage = new Bitmap(cutwidth, cutheight); //创建存放截取图像的画布 Graphics newGraphics = Graphics.FromImage(newImage); //创建矩形对象,裁减是就是照着这个矩形来裁减的 Rectangle CutReatangle = new Rectangle(cutX, cutY, cutwidth, cutheight); //创建矩形对象,用于下面的指定裁减出来的图像在新画布上的显示情况 Rectangle showRectangle = new Rectangle(0, 0, cutwidth, cutheight); //执行裁减操作 newGraphics.DrawImage(oldImage, showRectangle, CutReatangle, GraphicsUnit.Pixel); //释放资源(除图像对象的资源) oldImage.Dispose(); newGraphics.Dispose(); DateTime time = DateTime.Now; CreateFile.CreateFolder(ReadConfig.GetHostUrl("HostUrl") + ReadConfig.GetHostUrl(fileName) + "\\" + time.Year + "\\" + time.Month + "\\" + time.Day + "\\"); //保存新图到指定路径 //newImage.Save(ReadConfig.GetHostUrl("HostUrl") + savepath, System.Drawing.Imaging.ImageFormat.Jpeg); if (fileName == "GYS_inLOGO100_40") { newImage.ImageWinvarOptions(ReadConfig.GetHostUrl("HostUrl") + savepath, 100, 40, 100); } else { newImage.ImageWinvarOptions(ReadConfig.GetHostUrl("HostUrl") + savepath, 200, 80, 100); } //释放新图像的资源,如果在保存前释放,会造成程序出错 newImage.Dispose(); } /// <summary> /// 判断原始文件后缀是否符合要求规范 /// </summary> /// <param name="filepath">原始文件路径</param> /// <returns>true为符合</returns> bool CheckImageMime(string filepath) { int typeLastShow = filepath.LastIndexOf('.'); string[] imageType = { "jpg", "gif", "png", "bmp" }; for (int i = 0; i < imageType.Length; i++) { //如果有后缀名且后缀符合规范 if (typeLastShow > 0 && imageType[i].Equals(filepath.Substring(typeLastShow + 1), StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } /// <summary> /// 根据原始文件名返回前面加上操作时间的文件名 /// </summary> /// <param name="filepath">原文件全名(路径+文件名称)</param> /// <returns>新的文件名称</returns> string NewFileName(string filepath) { //获取文件原名 string oldFileName = filepath.Substring(filepath.LastIndexOf("\\") + 1); //获取操作时间,原使用的是yyyyMMddHHmmssffff string date = DateTime.Now.ToString("yyyyMMddHHmmss") + DateTime.Now.Millisecond.ToString(); //新文件名 string newFileName = date + oldFileName; return newFileName; } public bool IsReusable { get { return false; } } } }
压缩图片的方法
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BCommon.common { public static class ImageWinvar { /// <summary> /// 无损压缩图片 /// </summary> /// <param name="img">原图片的文件流</param> /// <param name="dFile">压缩后保存位置</param> /// <param name="dHeight">高度</param> /// <param name="dWidth"></param> /// <param name="flag">压缩质量 1-100</param> /// <returns></returns> public static bool ImageWinvarOptions(this Image img, string dFile, int dWidth, int dHeight, int flag) { ImageFormat tFormat = img.RawFormat; int sW = 0, sH = 0; //按比例缩放 Size tem_size = new Size(img.Width, img.Height); if (tem_size.Width > dHeight || tem_size.Width > dWidth) //将**改成c#中的或者操作符号 { if ((tem_size.Width * dHeight) > (tem_size.Height * dWidth)) { sW = dWidth; sH = (dWidth * tem_size.Height) / tem_size.Width; } else { sH = dHeight; sW = (tem_size.Width * dHeight) / tem_size.Height; } } else { sW = tem_size.Width; sH = tem_size.Height; } Bitmap ob = new Bitmap(dWidth, dHeight); Graphics g = Graphics.FromImage(ob); g.Clear(Color.WhiteSmoke); g.CompositingQuality = CompositingQuality.HighQuality; g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.DrawImage(img, new Rectangle((dWidth - sW) / 2, (dHeight - sH) / 2, sW, sH), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel); g.Dispose(); //以下代码为保存图片时,设置压缩质量 EncoderParameters ep = new EncoderParameters(); long[] qy = new long[1]; qy[0] = flag;//设置压缩的比例1-100 EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy); ep.Param[0] = eParam; try { ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders(); ImageCodecInfo jpegICIinfo = null; for (int x = 0; x < arrayICI.Length; x++) { if (arrayICI[x].FormatDescription.Equals("JPEG")) { jpegICIinfo = arrayICI[x]; break; } } if (jpegICIinfo != null) { ob.Save(dFile, jpegICIinfo, ep);//dFile是压缩后的新路径 } else { ob.Save(dFile, tFormat); } return true; } catch { return false; } finally { img.Dispose(); ob.Dispose(); } } } }