关闭

cropbox + springmvc +ajax 裁剪上传

标签: spring mvccropbox
1767人阅读 评论(4) 收藏 举报
分类:

最近用到了裁剪上传,用最简单的方式进行实现。发现好多用jcrop的,那个是根据坐标切割原图,而cropbox是转成base64码。 接下来看实现

cropbox.js 从网上下下来的 ,代码很少就直接复制 贴上来

/**
 * Created by ezgoing on 14/9/2014.
 */

"use strict";
(function (factory) {
    if (typeof define === 'function' && define.amd) {
        define(['jquery'], factory);
    } else {
        factory(jQuery);
    }
}(function ($) {
    var cropbox = function(options, el){
        var el = el || $(options.imageBox),
            obj =
            {
                state : {},
                ratio : 1,
                options : options,
                imageBox : el,
                thumbBox : el.find(options.thumbBox),
                spinner : el.find(options.spinner),
                image : new Image(),
                getDataURL: function ()
                {
                    var width = this.thumbBox.width(),
                        height = this.thumbBox.height(),
                        canvas = document.createElement("canvas"),
                        dim = el.css('background-position').split(' '),
                        size = el.css('background-size').split(' '),
                        dx = parseInt(dim[0]) - el.width()/2 + width/2,
                        dy = parseInt(dim[1]) - el.height()/2 + height/2,
                        dw = parseInt(size[0]),
                        dh = parseInt(size[1]),
                        sh = parseInt(this.image.height),
                        sw = parseInt(this.image.width);

                    canvas.width = width;
                    canvas.height = height;
                    var context = canvas.getContext("2d");
                    context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh);
                    var imageData = canvas.toDataURL('image/png');
                    return imageData;
                },
                getBlob: function()
                {
                    var imageData = this.getDataURL();
                    var b64 = imageData.replace('data:image/png;base64,','');
                    var binary = atob(b64);
                    var array = [];
                    for (var i = 0; i < binary.length; i++) {
                        array.push(binary.charCodeAt(i));
                    }
                    return  new Blob([new Uint8Array(array)], {type: 'image/png'});
                },
                zoomIn: function ()
                {
                    this.ratio*=1.1;
                    setBackground();
                },
                zoomOut: function ()
                {
                    this.ratio*=0.9;
                    setBackground();
                }
            },
            setBackground = function()
            {
                var w =  parseInt(obj.image.width)*obj.ratio;
                var h =  parseInt(obj.image.height)*obj.ratio;

                var pw = (el.width() - w) / 2;
                var ph = (el.height() - h) / 2;

                el.css({
                    'background-image': 'url(' + obj.image.src + ')',
                    'background-size': w +'px ' + h + 'px',
                    'background-position': pw + 'px ' + ph + 'px',
                    'background-repeat': 'no-repeat'});
            },
            imgMouseDown = function(e)
            {
                e.stopImmediatePropagation();

                obj.state.dragable = true;
                obj.state.mouseX = e.clientX;
                obj.state.mouseY = e.clientY;
            },
            imgMouseMove = function(e)
            {
                e.stopImmediatePropagation();

                if (obj.state.dragable)
                {
                    var x = e.clientX - obj.state.mouseX;
                    var y = e.clientY - obj.state.mouseY;

                    var bg = el.css('background-position').split(' ');

                    var bgX = x + parseInt(bg[0]);
                    var bgY = y + parseInt(bg[1]);

                    el.css('background-position', bgX +'px ' + bgY + 'px');

                    obj.state.mouseX = e.clientX;
                    obj.state.mouseY = e.clientY;
                }
            },
            imgMouseUp = function(e)
            {
                e.stopImmediatePropagation();
                obj.state.dragable = false;
            },
            zoomImage = function(e)
            {
                e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0 ? obj.ratio*=1.1 : obj.ratio*=0.9;
                setBackground();
            }

        obj.spinner.show();
        obj.image.onload = function() {
            obj.spinner.hide();
            setBackground();

            el.bind('mousedown', imgMouseDown);
            el.bind('mousemove', imgMouseMove);
            $(window).bind('mouseup', imgMouseUp);
            el.bind('mousewheel DOMMouseScroll', zoomImage);
        };
        obj.image.src = options.imgSrc;
        el.on('remove', function(){$(window).unbind('mouseup', imgMouseUp)});

        return obj;
    };

    jQuery.fn.cropbox = function(options){
        return new cropbox(options, this);
    };
}));

cropbox.css

@charset "utf-8";
.container {
    position: relative;
    font-family: 微软雅黑;
    font-size: 12px;
}
.container p {
    line-height: 12px;
    line-height: 0px;
    height: 0px;
    margin: 10px;
    color: #bbb;
}
.action {
    width: 325px;
    height: 30px;
    margin: 10px 0;
}
.cropped {
    position: absolute;
    right: 0px;
    top: 20px;
    font-size: 18px;
    width: 250px;
    /*border: 1px #ddd solid;*/
    height: 300px;
    padding: 4px;
/*  box-shadow: 0px 0px 12px #ddd;*/
    text-align: center;
}
.photo{margin: 50px;}
.photo p{    margin: 20px;
    font-size: 14px;}
.imageBox {float: left;margin: 20px;
    position: relative;
    height: 304px;
    width: 304px;
    border: 1px solid #aaa;
    background: #fff;
    overflow: hidden;
    background-repeat: no-repeat;
    cursor: move;
}
.imageBox .thumbBox {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 200px;
    height: 200px;
    margin-top: -100px;
    margin-left: -100px;
    box-sizing: border-box;
    border: 1px solid rgb(102, 102, 102);
    box-shadow: 0 0 0 1000px rgba(0, 0, 0, 0.5);
    background: none repeat scroll 0% 0% transparent;
}
.imageBox .spinner {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    text-align: center;
    line-height: 400px;
    background: rgba(0,0,0,0.5);
}
.Btnsty_peyton{ float: right;
   width: 40px;
  display: inline-block;
  margin-bottom: 10px;
  height: 40px;
  line-height: 40px;
  font-size: 14px;
  color: #FFFFFF;
  margin:0px 2px;
  background-color: #50d2c2;
  border-radius: 3px;
  text-decoration: none;
  cursor: pointer;
  border:0px solid #fff;}
  #btnCrop{
    width:65px;
  }
/*选择文件上传*/
.new-contentarea {
    width: 100px;
    overflow:hidden;
    margin: 0 auto;
    margin-left: 20px;
    position:relative;float:left;
    cursor: pointer;
}
.new-contentarea label {
    width:100%;
    height:100%;
    display:block;
    cursor: pointer;
}
.new-contentarea input[type=file] {
    width:100px;
    height:40px;
    background:#333;
    margin: 0 auto;
    position:absolute;
    right:50%;
    margin-right:-50px;
    top:0;
    right/*\**/:0px\9;
    margin-right/*\**/:0px\9;
    width/*\**/:10px\9;
    opacity:0;
    filter:alpha(opacity=0);
    z-index:2;
}
a.upload-img{
    width:100px;
    display: inline-block;
    margin-bottom: 10px;
    height:40px;
    line-height: 40px;
    font-size: 14px;
    color: #FFFFFF;
    background-color: #50d2c2;
    border-radius: 3px;
    text-decoration:none;
    cursor:pointer;
}
a.upload-img label{color: #fff;}

.tc{text-align:center;}

html代码 也是比较模式化的代码,只贴了裁剪窗口的,控制裁剪弹出的父窗口,可以自己简单实现

<div class="applyBox edit_photo">
            <div class="tlt"><i></i>编辑头像
                <a href="javascript:clearPhoto();" class="a-closed"></a>
            </div>
            <div class="container">
                <div class="imageBox">
                    <div class="thumbBox"></div>
                    <div class="spinner" style="display: none">Loading...</div>
                </div>
                <div class="action">
                    <div class="new-contentarea tc">
                        <a href="javascript:void(0)" class="upload-img">
                            <label for="upload-file">上传图片</label>
                        </a>
                        <input type="file" class="" name="upload-file" id="upload-file" />
                    </div>
                    <input type="button" id="btnCrop" class="Btnsty_peyton" value="裁切">
                    <input type="button" id="btnZoomIn" class="Btnsty_peyton" value="+">
                    <input type="button" id="btnZoomOut" class="Btnsty_peyton" value="-">
                </div>
                <div class="cropped">
                    <div class="photo_top">
                        图片预览
                    </div>
                    <div class="photo">
                    </div>
                </div>
                <div class="clear"></div>
                <div class="photo_size">
                    <p>最佳尺寸100×100,可以上传高质量图片进行裁剪</p>
                    <div class="photo_btn">
                        <input type="button" class="cancle" value="取消" />
                        <input type="button" onclick="backImg();" value="保存" />
                    </div>
                </div>
            </div>

        </div>

js

$(window).load(function() {
    var options =
    {
        thumbBox: '.thumbBox',
        spinner: '.spinner',
        imgSrc: ''
    }
    var cropper = $('.imageBox').cropbox(options);
    $('#upload-file').on('change', function(){
        var reader = new FileReader();
        reader.onload = function(e) {
            options.imgSrc = e.target.result;
            cropper = $('.imageBox').cropbox(options);
        }
        reader.readAsDataURL(this.files[0]);
        this.files = [];//存在兼容问题  不过没解决 就是上传后关闭 再打开文件还在
    })
    $('#btnCrop').on('click', function(){
        // $(".cropped .photo").empty(); //可有可不有 被我注释了
        var img = cropper.getDataURL();
        $('.cropped .photo').html('<img id="imgCroop" src="'+img+'">');
    })
    $('#btnZoomIn').on('click', function(){
        cropper.zoomIn();
    })
    $('#btnZoomOut').on('click', function(){
        cropper.zoomOut();
    })
});


//清空裁剪区 取消的时候   保存操作中 关闭裁剪窗口的时候都要清空下
    function clearPhoto(){
        $(".cropped .photo").empty();
    }   
    //点击保存到后台 加回显
        function uploadImg(){
            var imgStr = $("#imgCroop").attr("src");
            if(str==null){alert("请裁剪后保存");return;}
            $(".edit_photo").hide();   
            clearPhoto();
                //其实做的时候是三个窗口,这样我可以根据一二窗口的src判断上是否换了图片  若是没变 就没必要保存数据库了 这里就不判断了 但是代码还是贴上来 做个标记
                //var imgStr2 = $("#imageUrl2").attr("src");
                //if($("#imageUrl").attr("src")== $("#imageUrl2").attr("src")){              
                //  imgStr = "#nochange*";
                //}             

            var companyName = $("#editComName").val();
             $.ajax({
                type: 'post',
                url: '<%=request.getContextPath()%>/home/uploadImg',
                dataType: 'json', 
                data:{imgStr :imgStr,companyName:companyName},
                success: function (result) {
                    $("#imgshow").attr("src",result.imgurl);
                    $("#displayComName").text(result.companyName);
                }
                });
        }

后台代码

@ResponseBody
    @RequestMapping(value = "/uploadImg")
    public String uploadImg(@RequestParam("imgStr") String imgStr,@RequestParam("companyName") String companyName){
        if(!"#nochange*".equals(imgStr)){
            BASE64Decoder decoder = new BASE64Decoder();
            String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
            String filePath = getRequest().getSession().getServletContext().getRealPath("/");
            filePath = filePath.replace(getRequest().getContextPath(), "") + "/companyImages/" + uuid + ".jpg";

            // Base64解码
            byte[] b;
            try {
                b = decoder.decodeBuffer(imgStr.split(",")[1]);

                for (int i = 0; i < b.length; ++i) {
                    if (b[i] < 0) {// 调整异常数据
                        b[i] += 256;
                    }
                }
                // 生成jpeg图片
                OutputStream out = new FileOutputStream(filePath);
                out.write(b);
                out.flush();
                out.close();
                companyMapper.setUrlYzs(companyName, uuid + ".jpg", companyId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        else{
            companyMapper.setUrlYzs(companyName,company.getImgUrlYzs(), companyId);
        }
            return companyName;
    }
    //懒得改了 很明显返回的数据少了 大家自己改吧
1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2932次
    • 积分:85
    • 等级:
    • 排名:千里之外
    • 原创:5篇
    • 转载:1篇
    • 译文:0篇
    • 评论:4条
    文章分类
    最新评论