C#MVC和cropper.js实现剪裁图片ajax上传的弹出层

2021-02-15 22:21

阅读:410

 

   首先使用cropper.js插件,能够将剪裁后的图片返回为base64编码,后台根据base64编码解析保存图片。

jQuery.cropper:

   是一款使用简单且功能强大的图片剪裁jquery插件。该图片剪裁插件支持图片放大缩小,支持图片旋转,支持触摸屏设备,支持canvas,并且支持跨浏览器使用

  网站:http://fengyuanchen.github.io/cropper/

  可以自己搜索中文API

前台代码:

@{
    Layout = null;
}

DOCTYPE html>
html lang="en">

head>
    meta charset="UTF-8">
    title>上传图片title>

    script src="~/Content/js/jquery.min.js">script>

    link rel="stylesheet" type="text/css" href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.css">

    link href="~/Content/css/cropper.min.css" rel="stylesheet" />

    link href="~/Content/css/sitelogo.css" rel="stylesheet" />
    link rel="stylesheet" type="text/css" href="http://cdn.bootcss.com/font-awesome/4.6.0/css/font-awesome.min.css">

    script src="~/Content/js/bootstrap.min.js">script>
    script src="~/Content/js/cropper.js">script>
    script src="~/Content/js/sitelogo.js">script>


    style type="text/css">
        .avatar-btns button {
            height: 35px;
        }
    style>


head>

body>

    button type="button" class="btn btn-primary" data-toggle="modal" data-target="#avatar-modal" style="margin: 10px;">修改头像button>

    div class="user_pic" style="margin: 10px;">
        img src="" />
    div>

    div class="modal fade" id="avatar-modal" aria-hidden="true" aria-labelledby="avatar-modal-label" role="dialog" tabindex="-1">
        div class="modal-dialog modal-lg">
            div class="modal-content">
                div class="avatar-form" @*action="" enctype="multipart/form-data" method="post"*@ >
                    @*                    form class="avatar-form">*@
                    div class="modal-header">
                        button class="close" data-dismiss="modal" type="button">×button>
                        h4 class="modal-title" id="avatar-modal-label">上传图片h4>
                    div>
                    div class="modal-body">
                        div class="avatar-body">
                            div class="avatar-upload">
                                input class="avatar-src" name="avatar_src" type="hidden">
                                input class="avatar-data" name="avatar_data" type="hidden">
                                label for="avatarInput" style="line-height: 35px;">图片上传label>
                                button class="btn btn-danger" type="button" style="height: 35px;" onclick="$(‘input[id=avatarInput]‘).click();">请选择图片button>
                                span id="avatar-name">span>
                                input class="avatar-input hide" id="avatarInput" name="avatar_file" type="file">
                            div>
                        div>
                        div class="row">
                            div class="col-md-9">
                                div class="avatar-wrapper">div>
                            div>
                            div class="col-md-3">
                                div class="avatar-preview preview-lg" id="imageHead">div>
                                
                            div>
                        div>
                        div class="row avatar-btns">
                            div class="col-md-4">
                                div class="btn-group">
                                    button class="btn btn-danger fa fa-undo" data-method="rotate" data-option="-90" type="button" title="Rotate -90 degrees">向左旋转button>
                                div>
                                div class="btn-group">
                                    button class="btn  btn-danger fa fa-repeat" data-method="rotate" data-option="90" type="button" title="Rotate 90 degrees">向右旋转button>
                                div>
                            div>
                            div class="col-md-5" style="text-align: right;">
                                button class="btn btn-danger fa fa-arrows" data-method="setDragMode" data-option="move" type="button" title="移动">
                                    span class="docs-tooltip" data-toggle="tooltip" title="" data-original-title="$().cropper("setDragMode", "move")">span>
                                button>
                                button type="button" class="btn btn-danger fa fa-search-plus" data-method="zoom" data-option="0.1" title="放大图片">
                                    span class="docs-tooltip" data-toggle="tooltip" title="" data-original-title="$().cropper("zoom", 0.1)">
                                        
                                    span>
                                button>
                                button type="button" class="btn btn-danger fa fa-search-minus" data-method="zoom" data-option="-0.1" title="缩小图片">
                                    span class="docs-tooltip" data-toggle="tooltip" title="" data-original-title="$().cropper("zoom", -0.1)">
                                        
                                    span>
                                button>
                                button type="button" class="btn btn-danger fa fa-refresh" data-method="reset" title="重置图片">
                                    span class="docs-tooltip" data-toggle="tooltip" title="" data-original-title="$().cropper("reset")" aria-describedby="tooltip866214">span>
                                button>
                            div>
                            div class="col-md-3">
                                button class="btn btn-danger btn-block avatar-save fa fa-save" type="button" data-dismiss="modal">保存修改button>
                            div>
                        div>
                    div>
                div>
            div>

        div>
    div>

    script src="~/Content/js/html2canvas.min.js" type="text/javascript" charset="utf-8">script>

    script type="text/javascript">

        //做个下简易的验证  大小 格式 
        $(#avatarInput).on(change, function (e) {
            var filemaxsize = 1024 * 5;//5M
            var target = $(e.target);
            var Size = target[0].files[0].size / 1024;//获取image的尺寸
            if (Size > filemaxsize) {
                alert("图片过大,请重新选择(");
                $(".avatar-wrapper").empty();//清除
                return false;
            }//验证格式png,jpeg
            if (!this.files[0].type.match(/image.(png|jpeg)/)) {
                alert("请选择正确的图片(.jpg/.png/.jpeg)");
            } else {
                var filename = document.querySelector("#avatar-name");
                var texts = document.querySelector("#avatarInput").value;
                var teststr = texts; //你这里的路径写错了
                testend = teststr.match(/[^\\]+\.[^\(]+/i); //直接完整文件名的
                filename.innerHTML = testend;
            }

        });

        //保存
        $(".avatar-save").on("click", function () {
            var img_lg = document.getElementById(imageHead);
            // 截图小的显示框内的内容
            html2canvas(img_lg, {
                allowTaint: true,
                taintTest: false,
                onrendered: function (canvas) {
                    canvas.id = "mycanvas";
                    //生成base64图片数据
                    var type = document.getElementById(avatarInput).files[0].type;
                    var dataUrl = canvas.toDataURL(type);
                    imagesAjax(dataUrl);
                }
            });
        });



        //ajax提交
        function imagesAjax(src) {
            var data = {};
            data.img = src;
            $.ajax({
                url: @Url.Action("UploadBase"),
                data: data,
                type: "POST",
                dataType: text,
                success: function (result) {
                    $(.user_pic img).attr(src, result);
                },
                error: function (x, s, e) {
                    //请求出错处理
                    alert(x.status + " " + s + " " + e);
                }
            });
        }
    script>
body>

html>

 

后台代码:

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

using System.IO;
using System.Xml;
using System.Xml.Schema;



using System.Drawing;
using System.Net;
using System.Net.Http;
using System.Runtime.Serialization.Formatters.Binary;
using System.Web.Http;

namespace MvcDemo.Controllers
{
    public class UploadImagesController : Controller
    {
        //
        // GET: /UploadImages/

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Upload()
        {
            return View();
        }

        /// 
        /// 接收前台传来的Base64编码
        /// 
        public string UploadBase(string img)
        {
            string path = Common.UploadFile.Upload(img);
            return path;
        }

        public ActionResult UploadImg()
        {
            //上传文件
            HttpPostedFileBase img = Request.Files["btnfile"];
            string s = img.FileName;
            string fileExtension = Path.GetExtension(s);
            string path = "/Temp/";
            if (Directory.Exists(Server.MapPath(path)) == false)//如果不存在就创建file文件夹
            {
                Directory.CreateDirectory(Server.MapPath(path));
            }

            string virpath = path + Guid.NewGuid() + fileExtension;

            img.SaveAs(Server.MapPath(virpath));
            return Content(virpath);
        }

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Drawing;
using System.IO;


namespace Common
{
    /// 
    /// 上传文件公共类
    /// 
    public static class UploadFile
    {
        //静态 当前项目的路径
        private static string rootPath = AppDomain.CurrentDomain.BaseDirectory;

        //静态 要保存的路径
        private static string path = "/UploadImages/";

        /// 
        /// 接收Base64编码格式的图片
        /// 
        /// 图片Base64字符串
        /// 图片路径
        public static string Upload(string img)
        {

            if (!IsBase64(img))//判断是否是base64字符串
                return null;

            //获取文件后缀,判断格式
            string suffix = GetSuffixFromBase64Str(img);
            string pattren = @"png|jpeg+$";//正则验证
            if (!System.Text.RegularExpressions.Regex.IsMatch(suffix, pattren))
            {
                return null;
            }

            //如果不存在就创建file文件夹
            if (Directory.Exists(rootPath + path) == false)
            {

                Directory.CreateDirectory(rootPath + path);
            }

            //防止同名的两种方法,一是获取当前时间与指定时间的毫秒差作为名字
            //而是通过唯一的GUID 
            //图片名
            //string datetime = GetTimeStamp();
            //            文件夹      图片名        后缀名
            //string dbPath = path + GetTimeStamp() + suffix;

            //             生成一个新的 GUID 唯一值
            string dbPath = path + Guid.NewGuid() + "." + suffix;

            //保存路径               
            string savePath = rootPath + dbPath;


            try
            {
                //截取base64串
                //string strBase = img.Split(‘,‘)[1];
                //获取图片并保存
                Base64ToImg(img.Split(,)[1]).Save(savePath);
            }
            catch (Exception)
            {
                return null;
            }

            return dbPath;
        }

        /// 
        /// 删除文件 
        /// 
        /// 路径
        public static void DeleteImgFile(string fileUrl)
        {
            string file = System.Web.HttpContext.Current.Server.MapPath(fileUrl);
            //文件是否存在
            if (File.Exists(file))
            {
                File.Delete(file);
            }
        }



        //解析base64编码获取图片 
        private static Bitmap Base64ToImg(string base64Code)
        {
            MemoryStream stream = new MemoryStream(Convert.FromBase64String(base64Code));
            return new Bitmap(stream);
        }

        //获取当前时间段额时间戳
        private static string GetTimeStamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalMilliseconds).ToString();
        }

        //判读是否是base64编码
        private static char[] base64CodeArray = new char[]  
        {  
            A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,  
            a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,  
            0, 1, 2, 3, 4,  5, 6, 7, 8, 9, +, /, =  
        };

        ///   
        /// 是否base64字符串  
        ///   
        /// 要判断的字符串  
        ///   
        private static bool IsBase64(string base64Str)
        {
            byte[] bytes = null;
            return IsBase64(base64Str, out bytes);
        }

        ///   
        /// 是否base64字符串  
        ///   
        /// 要判断的字符串  
        /// 字符串转换成的字节数组  
        ///   
        private static bool IsBase64(string base64Str, out byte[] bytes)
        {
            //string strRegex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";  
            bytes = null;
            if (string.IsNullOrEmpty(base64Str))
                return false;
            else
            {
                if (base64Str.Contains(","))
                    base64Str = base64Str.Split(,)[1];
                if (base64Str.Length % 4 != 0)
                    return false;
                if (base64Str.Any(c => !base64CodeArray.Contains(c)))
                    return false;
            }
            try
            {
                bytes = Convert.FromBase64String(base64Str);
                return true;
            }
            catch (FormatException)
            {
                return false;
            }
        }

        ///   
        /// 把base64字符串转换成Bitmap  
        ///   
        /// 要转换的base64字符串  
        ///   
        private static Bitmap Base64ToBitmap(string base64Str)
        {
            Bitmap bitmap = null;
            byte[] bytes = null;
            try
            {
                if (IsBase64(base64Str, out bytes))
                {
                    using (MemoryStream stream = new MemoryStream(bytes))
                    {
                        stream.Seek(0, SeekOrigin.Begin);//为了避免有时候流指针定位错误,显式定义一下指针位置  
                        bitmap = new Bitmap(stream);
                    }
                }
            }
            catch (Exception)
            {
                bitmap = null;
            }
            return bitmap;
        }

        ///   
        /// 根据base64字符串获取文件后缀(图片格式)  
        ///   
        /// base64  
        ///   
        private static string GetSuffixFromBase64Str(string base64Str)
        {
            string suffix = string.Empty;
            string prefix = "data:image/";
            if (base64Str.StartsWith(prefix) && base64Str.Contains(";") && base64Str.Contains(","))
            {
                base64Str = base64Str.Split(;)[0];
                suffix = base64Str.Substring(prefix.Length);
            }
            return suffix;
        }
    }
}

 

 

 

Data URI scheme

  Data URI scheme是在RFC2397中定义的,目的是将一些小的数据,直接嵌入到网页中,从而不用再从外部文件载入。 在上面的Data URI中,data表示取得数据的协定名称,image/png 是数据类型名称,base64 是数据的编码方法,逗号后面就是这个image/png文件base64编码后的数据。  支持的格式:data:image/png;base64,base64编码的png图片数据 data:image/jpeg;base64,base64编码的jpeg图片数据 把图像文件的内容直接写在了HTML 文件中,这样做的好处是,节省了一个HTTP 请求。坏处是浏览器不会缓存这种图像。 Jpg和jpeg格式,扩展名的实质是相同的  

 

GUID

  GUID(全球唯一标识符) 是一种由算法生成的二进制长度为128位的数字标识符,在理想情况下,任何计算机和计算机集群都不会生成两个相同的GUID,。随机生成两个相同GUID的可能性是非常小的,但并不为0。所以,用于生成GUID的算法通常都加入了非随机的参数(如时间),以保证这种重复的情况不会发生 

 

这是通过ajax直接上传的没有经过剪裁: https://www.cnblogs.com/bubugao/p/MyAjaxForm.html 


评论


亲,登录后才可以留言!