zoukankan      html  css  js  c++  java
  • 基于cropper.js的图片上传和裁剪

    项目中要求图片上传并裁剪的功能,之前也有接触过很多图片裁剪插件,效果体验不是很好,今天推荐一款好用的插件-cropper,超级好用,裁剪功能丰富,满足了各种需求。

    功能:

    1:点击选择图片,弹出文件夹选择桌面 文件
    2:选择文件之后,打开编辑图片的页面,开始裁剪图片
    插件下载地址:http://www.jq22.com/jquery-info18167

    插件描述:croppic图像裁剪将满足您的需求,图像加载效果、展现效果以及裁剪都非常棒,相信看到Demo后一定会喜欢上此插件.

    图片.png
    图片.png

    代码:
    1:引入相关的css和js文件,cropper.min.css,ImgCropping.css,cropper.min.js等,文件下载地址:http://www.jq22.com/jquery-info18167

    <link rel="stylesheet" href="css/cropper.min.css">
    <link rel="stylesheet" href="css/ImgCropping.css">
    <script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script>
    <script src="js/cropper.min.js"></script>

    2:具体代码如下:前端部分

    <!DOCTYPE html>
    <html lang="en">
    
        <head>
            <meta charset="UTF-8">
            <title>基于cropper.js的图片裁剪</title>
            <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
            <meta name="format-detection" content="telephone=no">
            <link rel="stylesheet" href="css/cropper.min.css">
            <link rel="stylesheet" href="css/ImgCropping.css">
    
            <style>
                .str {
                    width: 150px;
                    height: 200px;
                    border: solid 1px #e3e3e3;
                    padding: 5px;
                    margin-top: 10px
                }
            </style>
            
        </head>
    
        <body>
            <label title="上传图片" for="chooseImg" class="l-btn choose-btn">
             <input type="file" accept="image/jpg,image/jpeg,image/png" name="file" id="chooseImg" class="hidden" onchange="selectImg(this)">
                        选择图片
             </label>
            <div class="str">
                <img id="finalImg" src="" width="100%">
            </div>
    
            <!--图片裁剪框 start-->
            <div style="display: none" class="tailoring-container">
                <div class="black-cloth" onclick="closeTailor(this)"></div>
                <div class="tailoring-content">
                    <div class="tailoring-content-one">
    
                        <div class="close-tailoring" onclick="closeTailor(this)">×</div>
                    </div>
    
                    <div class="tailoring-content-two">
                        <div class="tailoring-box-parcel">
                            <img id="tailoringImg">
                        </div>
                        <div class="preview-box-parcel">
                            <p>图片预览:</p>
                            <div class="square previewImg"></div>
                            <!--  <div class="circular previewImg"></div>-->
                        </div>
                    </div>
    
                    <div class="tailoring-content-three">
                        <button class="l-btn cropper-reset-btn">复位</button>
                        <button class="l-btn cropper-rotate-btn">旋转</button>
                        <button class="l-btn cropper-scaleX-btn">换向</button>
                        <button class="l-btn sureCut" id="sureCut">确定</button>
                    </div>
                </div>
            </div>
            <!--图片裁剪框 end-->
    
            <script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script>
            <script src="js/cropper.min.js"></script>
               <script type="text/javascript">  
        //弹出框水平垂直居中  
        (window.onresize = function() {  
            var win_height = $(window).height();  
            var win_width = $(window).width();  
            if (win_width <= 768) {  
                $(".tailoring-content").css(  
                        {  
                            "top" : (win_height - $(".tailoring-content")  
                                    .outerHeight()) / 2,  
                            "left" : 0  
                        });  
            } else {  
                $(".tailoring-content").css(  
                        {  
                            "top" : (win_height - $(".tailoring-content")  
                                    .outerHeight()) / 2,  
                            "left" : (win_width - $(".tailoring-content")  
                                    .outerWidth()) / 2  
                        });  
            }  
        })();  
          
        // 选择文件触发事件  
        function selectImg(file) {  
            //文件为空,返回  
            if (!file.files || !file.files[0]) {  
                return;  
            }  
            $(".tailoring-container").toggle();  
            var reader = new FileReader();  
            reader.onload = function(evt) {  
                var replaceSrc = evt.target.result;  
                // 更换cropper的图片  
                $('#tailoringImg').cropper('replace', replaceSrc, false);// 默认false,适应高度,不失真  
            }  
            reader.readAsDataURL(file.files[0]);  
        }  
        // cropper图片裁剪  
        $('#tailoringImg').cropper({  
            aspectRatio : 1 / 1,// 默认比例  
            preview : '.previewImg',// 预览视图  
            guides : false, // 裁剪框的虚线(九宫格)  
            autoCropArea : 0.5, // 0-1之间的数值,定义自动剪裁区域的大小,默认0.8  
            movable : false, // 是否允许移动图片  
            dragCrop : true, // 是否允许移除当前的剪裁框,并通过拖动来新建一个剪裁框区域  
            movable : true, // 是否允许移动剪裁框  
            resizable : true, // 是否允许改变裁剪框的大小  
            zoomable : false, // 是否允许缩放图片大小  
            mouseWheelZoom : false, // 是否允许通过鼠标滚轮来缩放图片  
            touchDragZoom : true, // 是否允许通过触摸移动来缩放图片  
            rotatable : true, // 是否允许旋转图片  
            crop : function(e) {  
                // 输出结果数据裁剪图像。  
            }  
        });  
        // 旋转  
        $(".cropper-rotate-btn").on("click", function() {  
            $('#tailoringImg').cropper("rotate", 45);  
        });  
        // 复位  
        $(".cropper-reset-btn").on("click", function() {  
            $('#tailoringImg').cropper("reset");  
        });  
        // 换向  
        var flagX = true;  
        $(".cropper-scaleX-btn").on("click", function() {  
            if (flagX) {  
                $('#tailoringImg').cropper("scaleX", -1);  
                flagX = false;  
            } else {  
                $('#tailoringImg').cropper("scaleX", 1);  
                flagX = true;  
            }  
            flagX != flagX;  
        });  
          
        // 确定按钮点击事件  
        $("#sureCut").on("click", function() {  
            if ($("#tailoringImg").attr("src") == null) {  
                return false;  
            } else {  
                var cas = $('#tailoringImg').cropper('getCroppedCanvas');// 获取被裁剪后的canvas  
                var base64 = cas.toDataURL('image/jpeg'); // 转换为base64  
          
                    $("#finalImg").prop("src", base64);// 显示图片  
                uploadFile(encodeURIComponent(base64))//编码后上传服务器  
                closeTailor();// 关闭裁剪框  
                }  
            });  
          
            // 关闭裁剪框  
            function closeTailor() {  
                $(".tailoring-container").toggle();  
            }  
          
            //ajax请求上传  
            function uploadFile(file) {  
                $.ajax({  
                    url : '/demo/upload.do',  
                    type : 'POST',  
                    data : "file=" + file,  
                    async : true,  
                    success : function(data) {  
                        console.log(data)  
                    }  
                });  
            }  
        </script>  
    
        </body>
    
    </html>
    

    3:后台Java代码:
    利用cropper插件裁剪本地图片,接下来的问题就是将裁剪过后的base64图片上传至后台。

    1:去掉base64编码的头部 如:"data:image/jpeg;base64," 如果不去,转换的图片不可以查看
    2:解码
    3:在tomcat目录下创建picture文件夹保存图片
    4:判断文件目录是否存在
    5:根据系统的不同获取文件路径的分隔符
    6:输出文件路径

        package com.debo.cropper;  
          
        import java.io.FileOutputStream;  
        import java.text.SimpleDateFormat;  
        import java.util.Base64;  
        import java.util.Base64.Decoder;  
        import java.util.Date;  
          
        import javax.servlet.http.HttpServletRequest;  
          
        import org.apache.commons.lang.RandomStringUtils;  
        import org.springframework.stereotype.Controller;  
        import org.springframework.web.bind.annotation.RequestMapping;  
        import org.springframework.web.bind.annotation.RequestMethod;  
        import org.springframework.web.bind.annotation.RequestParam;  
        import org.springframework.web.bind.annotation.ResponseBody;  
          
        @Controller  
        @RequestMapping("upload")  
        public class Cropper {  
          
            /**  
             * 注释的代码可以忽略  
             * @throws  
             */  
            @RequestMapping(method = RequestMethod.POST)  
            @ResponseBody  
            public String cropper(@RequestParam("file") String file,  
                    HttpServletRequest request) throws Exception {  
                  
                Decoder decoder = Base64.getDecoder();  
                // 去掉base64编码的头部 如:"data:image/jpeg;base64," 如果不去,转换的图片不可以查看  
                file = file.substring(23);  
                        //解码  
                byte[] imgByte = decoder.decode(file);  
          
                /*//在tomcat目录下创建picture文件夹保存图片  
                String path = request.getSession().getServletContext()  
                        .getRealPath("");  
                String contextPath = request.getContextPath();  
                path = path.replace(contextPath.substring(1), "")  + "picture";  
                File dir = new File(path);  
                if (!dir.exists()) {// 判断文件目录是否存在  
                    dir.mkdirs();  
                }  
                        //因为windows和linux路径不同,window:D:dir   linux:opt/java  
                //System.getProperty("file.separator")能根据系统的不同获取文件路径的分隔符  
                String fileName = getFileName();  
                path = path + System.getProperty("file.separator") + fileName;  
                        */  
                  
                try {  
                    FileOutputStream out = new FileOutputStream("D:/1.jpg"); // 输出文件路径  
                    out.write(imgByte);  
                    out.close();  
                } catch (Exception e) {  
                    e.printStackTrace();  
                }  
                  
                return "success";  
          
                /*String url = request.getScheme() + "://" + request.getServerName()  
                        + ":" + request.getServerPort() + "/picture/" + fileName;  
                return url; */  
            }  
          
            /**  
             * 创建文件名称 内容:时间戳+随机数  
             *   
             * @param @return  
             * @throws  
             */  
            private String getFileName() {  
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");  
                String timeStr = sdf.format(new Date());  
                String str = RandomStringUtils.random(5,  
                        "abcdefghijklmnopqrstuvwxyz1234567890");  
                String name = timeStr + str + ".jpg";  
                return name;  
            }  
          
        }  
    

    RandomStringUtils需要导入依赖

        <dependency>  
            <groupId>commons-lang</groupId>  
            <artifactId>commons-lang</artifactId>  
            <version>2.6</version>  
        </dependency>  
    

    原文作者:祈澈姑娘
    技术博客:https://www.jianshu.com/u/05f416aefbe1

    90后前端妹子,爱编程,爱运营,爱折腾。
    坚持总结工作中遇到的技术问题,坚持记录工作中所所思所见,欢迎大家一起探讨交流。
    文末福利:关注「编程微刊」公众号 ,在微信后台回复「领取资源」,获取IT资源200G干货大全。公众号回复“1”,拉你进程序员技术讨论群

  • 相关阅读:
    UVa 1151 Buy or Build【最小生成树】
    UVa 216 Getting in Line【枚举排列】
    UVa 729 The Hamming Distance Problem【枚举排列】
    HDU 5214 Movie【贪心】
    HDU 5223 GCD
    POJ 1144 Network【割顶】
    UVa 11025 The broken pedometer【枚举子集】
    HDU 2515 Yanghee 的算术【找规律】
    Java基本语法
    Java环境变量,jdk和jre的区别,面向对象语言编程
  • 原文地址:https://www.cnblogs.com/ting6/p/9725486.html
Copyright © 2011-2022 走看看