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();
            }
        }


    }
}

 

posted @ 2015-09-02 18:07  流浪的狸猫  阅读(2447)  评论(0编辑  收藏  举报