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


       首先使用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">&times;</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 class="avatar-preview preview-md"></div>
                                    <div class="avatar-preview preview-sm"></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(&quot;setDragMode&quot;, &quot;move&quot;)"></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(&quot;zoom&quot;, 0.1)">
                                            <!--<span class="fa fa-search-plus"></span>-->
                                        </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(&quot;zoom&quot;, -0.1)">
                                            <!--<span class="fa fa-search-minus"></span>-->
                                        </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(&quot;reset&quot;)" 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("图片过大,请重新选择(<5M)");
                    $(".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();
            }
    
            /// <summary>
            /// 接收前台传来的Base64编码
            /// </summary>
            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
    {
        /// <summary>
        /// 上传文件公共类
        /// </summary>
        public static class UploadFile
        {
            //静态 当前项目的路径
            private static string rootPath = AppDomain.CurrentDomain.BaseDirectory;
    
            //静态 要保存的路径
            private static string path = "/UploadImages/";
    
            /// <summary>
            /// 接收Base64编码格式的图片
            /// </summary>
            /// <param name="img">图片Base64字符串</param>
            /// <returns>图片路径</returns>
            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;
            }
    
            /// <summary>
            /// 删除文件 
            /// </summary>
            /// <param name="fileUrl">路径</param>
            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', '+', '/', '='  
            };
    
            /// <summary>  
            /// 是否base64字符串  
            /// </summary>  
            /// <param name="base64Str">要判断的字符串</param>  
            /// <returns></returns>  
            private static bool IsBase64(string base64Str)
            {
                byte[] bytes = null;
                return IsBase64(base64Str, out bytes);
            }
    
            /// <summary>  
            /// 是否base64字符串  
            /// </summary>  
            /// <param name="base64Str">要判断的字符串</param>  
            /// <param name="bytes">字符串转换成的字节数组</param>  
            /// <returns></returns>  
            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;
                }
            }
    
            /// <summary>  
            /// 把base64字符串转换成Bitmap  
            /// </summary>  
            /// <param name="base64Str">要转换的base64字符串</param>  
            /// <returns></returns>  
            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;
            }
    
            /// <summary>  
            /// 根据base64字符串获取文件后缀(图片格式)  
            /// </summary>  
            /// <param name="base64Str">base64</param>  
            /// <returns></returns>  
            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 

  • 相关阅读:
    HttpClient后台post 请求webapi
    [SQL Server] 复制数据库任务
    C# js 在页面能执行,放在单独js文件不能执行
    Flink 中的kafka何时commit?
    jar依赖
    AI重要算法
    NonWindowJoin
    Rocket MQ 源码解析
    linear algebra
    Theories of Deep Learning
  • 原文地址:https://www.cnblogs.com/mslalan/p/8423100.html
Copyright © 2020-2023  润新知