Input上传图片并裁剪

input上传图片,裁剪处理。裁剪图片页面效果为src='base64',上传input需要转换成二进制流。也可以直接上传base64,后端转换。

HTML

html中引用了jquery.min.js 随便一个jq即可;

引用的photoCrop.js参见末尾文件;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Cropper.js</title>
    <script src="./src/js/jquery.min.js"></script>
    <script src="./src/js/photoCrop.js"></script>
    <style type="text/css">
        .bg_content{text-align:center;margin:10px;}
        .bg_box{margin-bottom:15px;}
        .bg_img_box{display:inline-block;width:200px;min-height:120px;padding: 10px;position:relative;background:rgba(0,0,0,.3);}
        .bg_preview{width:100%;}
        .bg_file{width:100%;height:100%;position: absolute;left:0;top:0;opacity:0.1;cursor:pointer;}
        .bg_main{background:#fff;color:#0f77ea;padding:3px 12px;border:1px solid #0f77ea;border-radius:3px;cursor:pointer;}
        .bg_main:hover{background:#0f77ea;color:#fff;}
    </style>
</head>

<body>
<div class="bg_content">
    <form id="info" method="post" action="upload" enctype="multipart/form-data">
        <div class="bg_box">
            <div class="bg_img_box">
                <img class=" bg_preview cropImg" id="cropImg" ><!-- 过渡 -->
                <input class="bg_file" id="file" type="file" name="avatarsImg" onchange="chang()" accept="image/*" />
            </div>
        </div>
        <div class="bg_box">
            <button class="button bg_main" id="submit" type="button"> 提交</button>
        </div>
    </form>
</div>
</body>

</html>

JQ

//文件预览(图片预览)
function chang() {
    var f = $("input[name='avatarsImg']").prop('files')[0];
    let reader = new FileReader();
    reader.onload = function (e) {
        let img = this.result;//同:let img = e.target.result;
        $(".cropImg").attr("src", img);
        //裁剪
        $(".cropImg").photoCrop({
            fixedScale: 5 / 5, //宽高比例
            isHead: false,
            callBack: function (url) {
                $('.cropImg').attr('src', url);
            },
        });
        $("#photoCropBox-start").click()//自动裁剪
    };
}


//上传图片
$('#submit').on('click', function () {
    let data = new FormData();
    let obj = dataURLtoBlob($(".cropImg").attr("src"));//base64转二进制流
    data.append("file", obj);
    $.ajax({
        type: 'POST',
        url: '/url',
        data: data,
        cache: false,
        processData: false,
        contentType: false,
        success: function (res) {
            console.log(res);
        }
    });
})

//js,JQ 图片转换base64 base64转换为file对象,blob对象
function dataURLtoBlob(dataurl) {
    console.log(dataurl);
    var arr = dataurl.split(","),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], {
        type: mime,
    });
}

photoCrop.js

(function ($) {
    $.fn.photoCrop=function (option) {
        var opt={
            img:'',
            fixedScale:9/5,
            isHead:null,
            maxWidth:'1400',
            maxHeight:'800',
            callBack:function () {}
        }
        opt=$.extend(opt,option);
        var _this=this;
        var imgSrc=opt.img ? opt.img:_this.attr('src');
        var photoCropBox=$('<div id="photoCropBox" style="position: fixed;width: 100%;height: 100%;top: 0;left: 0;background: rgba(0,0,0,0.5);z-index: 99999;padding: 20px;">' +
            '<canvas id="cropCanvas" style="position: absolute;opacity:1;left: 0;top: 0;z-index: 100"></canvas><img id="dataImg" src="'+imgSrc+'" style="opacity: 0;position: absolute" alt=""><div id="photoCropBox-panel-box" style="position: relative;width: 100%;height: 100%;">' +
            '<div id="photoCropBox-panel" style="opacity:0;background: #eee;border-radius: 5px;max-width: '+opt.maxWidth+'px;max-height: '+opt.maxHeight+'px;position: absolute;text-align: center"><div id="photoCropBox-img" style="margin: 40px 60px 20px;display: inline-block;position: relative">' +
            '<img src="'+imgSrc+'" style="max-width: 100%;display: block;max-height: 100%;max-height: '+(opt.maxHeight-110)+'px;" alt=""></div><div id="photoCropBox-option" style="text-align: right;padding-right: 50px;padding-bottom: 20px;position: relative;z-index: 2"><span id="photoCropBox-start">手动裁剪</span><span id="photoCropBox-cancel">取消</span><span id="photoCropBox-end">裁剪</span></div></div>' +
            '</div></div>');
        $('body').append(photoCropBox);
        var _box=$('#photoCropBox-img');
        var imgWidth=_box.find('img').width();
        $('#photoCropBox-option span').css({
            lineHeight:'30px',
            background:'#000',
            color:'#fff',
            display:'inline-block',
            paddingLeft:'20px',
            paddingRight:'20px',
            marginRight:'5px',
            cursor:'pointer'
        })
        var cropBox=$('<div id="photoCropBox-cropBox" style="position: absolute;z-index: 5;cursor: Move;display: none">' +
            '<div id="cropBoxLine" style="overflow: hidden;position: absolute;width: 100%;height: 100%;">' +
            '<img src="'+imgSrc+'" style="display: block;width: '+_box.find('img').width()+'px;position: absolute;max-height: none;max-width: none" alt="">' +
            '<div class="top line" style="width: 100%;height: 1px;top: 0;left: 0;"></div><div class="right line" style="height: 100%;width: 1px;top: 0;right: 0"></div>' +
            '<div class="line bottom" style="width: 100%;height: 1px;bottom: 0px;left: 0"></div><div class="left line" style="height: 100%;width: 1px;top: 0;left: 0"></div></div>' +
            '<div id="cropBoxLine2"><div class="left line2" style="height: 100%;width: 1px;top: 0;left: 0;cursor: w-resize"></div><div class="right line2" style="height: 100%;width: 1px;top: 0;right: 0;cursor: e-resize"></div><div class="top line2" style="width: 100%;height: 1px;top: 0;left: 0;cursor: n-resize;position: absolute"></div><div class="bottom line2" style="width: 100%;height: 1px;bottom: 0px;left: 0;cursor: s-resize"></div>' +
            '<div class="left bot" style="left: -3px;top: 50%;margin-top: -4px;cursor: w-resize"></div><div class="right bot" style="right: -3px;top: 50%;margin-top: -4px;cursor: e-resize"></div><div class="bottom bot" style="bottom: -3px;left: 50%;margin-left: -4px;cursor: s-resize"></div><div class="top bot" style="top: -3px;left: 50%;margin-left: -4px;cursor: n-resize"></div>' +
            '<div class="left-top bot" style="left: -3px;top: -3px;cursor: nw-resize"></div><div class="left-bottom bot" style="left: -3px;bottom: -3px;cursor: sw-resize"></div><div class="right-top bot" style="right: -3px;top: -3px;cursor: ne-resize"></div><div class="right-bottom bot"style="right: -3px;bottom: -3px;cursor: se-resize"></div></div></div>');
        var screen=$('<div id="photoCropBox-bg" style="background: rgba(0,0,0,.5);position: absolute;left: 0;top: 0;width: 100%;height: 100%;z-index: 4;cursor: crosshair;display: none"></div>')
        _box.append(cropBox);
        _box.append(screen);
        var _corp=$('#photoCropBox-cropBox');
        var cropBoxLine=$('#cropBoxLine');
        setTimeout(function () {
            console.log(imgWidth)
            cropBoxLine.find('img').css('width',_box.find('img').width()+'px')
        },20)
        if(opt.isHead){
            cropBoxLine.css({borderRadius:'100%'})
        }
        $('#photoCropBox-cropBox .line,#photoCropBox-cropBox .line2').css({
            background:'url(./img/Jcrop.gif)',
            position:'absolute',
            opacity:.5
        })
        $('#photoCropBox-cropBox .bot').css({
            background:'rgba(0,0,0,0.5)',
            position:'absolute',
            width:7,
            height:7,
            border:'1px #999 solid'
        })
        setTimeout(function () {
            init();
        },10)
        $(window).on('resize',function () {
            setPosition();
        })
        $('#photoCropBox-cancel').on('click',function () {
            closeBox();
        })
        $('#photoCropBox-bg').on('mousedown',function (e) {
            if(opt.fixedScale) return //固定
            $('#cropBoxLine2').hide();
            var _this=$(this);
            var _sx=e.pageX,_sy=e.pageY;
            var _tx=_this.offset().left;
            var _ty=_this.offset().top;
            $(document).on('mousemove',function (e) {
                e.preventDefault();
                var _ex=e.pageX,_ey=e.pageY;
                getPosition(_ex,_ey,_ty,_tx,_sx,_sy,_this)
            })
            $(document).on('mouseup',function () {
                $(document).unbind('mousemove');
                $('#cropBoxLine2').show();
            })
        })
        var lock=false;
        _corp.on('mousedown',function (e) {
            if(lock){return}
            var _sx=e.pageX,_sy=e.pageY;
            var pW=$('#photoCropBox-bg').width(),pH=$('#photoCropBox-bg').height();
            var _this=$(this),_thisX=parseInt(_this.css('left')),_thisY=parseInt(_this.css('top')),_thisW=parseInt(_this.css('width')),_thisH=parseInt(_this.css('height'));
            $(document).on('mousemove',function (e) {
                e.preventDefault();
                var _ex=e.pageX,_ey=e.pageY;
                var _x=_ex-_sx,_y=_ey-_sy;
                _x+=_thisX;_y+=_thisY;
                if(_x<0) _x=0;
                if(_y<0) _y=0;
                if(_y>pH-_thisH) _y=pH-_thisH;
                if(_x>pW-_thisW) _x=pW-_thisW;
                resizeCropBox("","",_y,_x,true)
            })
            $(document).on('mouseup',function () {
                $(document).unbind('mousemove');
            })
        })
        //控制大小
        $('#cropBoxLine2 .bot').on("mousedown",function (e) {
            lock=true;
            var _esx=e.pageX,_esy=e.pageY;
            var _that=$(this);
            var _this=$('#photoCropBox-bg');
            var _tx=_this.offset().left;
            var _ty=_this.offset().top;
            var _sx=_corp.offset().left,_sy=_corp.offset().top;//裁剪框
            if(_that.hasClass('right-top')) _sy+=_corp.height();
            if(_that.hasClass('left-top')){
                _sy+=_corp.height();
                _sx+=_corp.width();
            }
            if(_that.hasClass('left-bottom')) _sx+=_corp.width();
            $(document).on('mousemove',function (e) {
                e.preventDefault();
                var _ex=e.pageX,_ey=e.pageY;
                if(opt.fixedScale){
                    _ey=(_ex-_esx)/opt.fixedScale+_esy;
                    if(_that.hasClass('right-top') || _that.hasClass('left-bottom')){
                        _ey=(_esx-_ex)/opt.fixedScale+_esy;
                    }
                }
                getPosition(_ex,_ey,_ty,_tx,_sx,_sy,_this)
            })
            $(document).on('mouseup',function () {
                $(document).unbind('mousemove');
                lock=false;
            })
        })
        $('#cropBoxLine2 .left,#cropBoxLine2 .top,#cropBoxLine2 .right,#cropBoxLine2 .bottom').on('mousedown',function (e) {
            if(opt.fixedScale) return //固定
            lock=true;
            var _that=$(this);
            var _this=$('#photoCropBox-bg');
            var _tx=_this.offset().left;//
            var _ty=_this.offset().top;
            var _sx=_corp.offset().left,_sy=_corp.offset().top;
            var ch=_corp.height(),cw=_corp.width();
            if(_that.hasClass('top')){
                _sy+=ch;
            }else if(_that.hasClass('left')) {
                _sx+=cw;
            }
            $(document).on('mousemove',function (e) {
                e.preventDefault();
                var _ex=e.pageX,_ey=e.pageY;
                if(_that.hasClass('top') || _that.hasClass('bottom')){
                    if(!(_ey-_sy>0)){
                        var _x=_sx-_tx,_y=_ey-_ty,_w=cw,_h=-(_ey-_sy);
                        if(_y<0) {_y=0;_h=_sy-_ty;}
                    }else{
                        var _x=_sx-_tx,_y=_sy-_ty,_w=cw,_h=_ey-_sy;
                        if(_h>_this.height()-_y) _h=_this.height()-_y;
                    }
                }else {
                    if(_ex-_sx>0 && _ey-_sy>0){
                        var _x=_sx-_tx,_y=_sy-_ty,_w=_ex-_sx,_h=ch;
                        if(_w>_this.width()-_x) _w=_this.width()-_x;
                    }else if(!(_ex-_sx>0) && _ey-_sy>0){
                        var _x=_ex-_tx,_y=_sy-_ty,_w=-(_ex-_sx),_h=ch;
                        if(_x<0) {_x=0;_w=_sx-_tx;}
                    }
                }
                resizeCropBox(_w,_h,_y,_x);
            })
            $(document).on('mouseup',function () {
                $(document).unbind('mousemove');
                lock=false;
            })
        })
        $('#photoCropBox-start').on('click',function () {
            _corp.css('display','block')
            $('#photoCropBox-bg').css('display','block')
        })
        $('#photoCropBox-end').on('click',function () {
            getImage()
            closeBox()
        })
        function init() {
            setPosition()
            if(opt.fixedScale){
                if((_box.height()-_box.width()/opt.fixedScale/2)<0){
                    resizeCropBox(_box.height()*opt.fixedScale,_box.height(),0,(_box.width()-_box.height()*opt.fixedScale)/2)
                }else {
                    resizeCropBox(_box.width()/2,_box.width()/opt.fixedScale/2,(_box.height()-_box.width()/opt.fixedScale/2)/2,_box.width()/4)
                }
            }else {
                resizeCropBox(_box.width()/2,_box.height()/2,_box.height()/4,_box.width()/4)
            }
            if(opt.fixedScale) {
                $('.bot.top,.bot.left,.bot.bottom,.bot.right').remove();//固定
            }
        }
        function setPosition() {
            $('#photoCropBox-panel').css({
                top:($('#photoCropBox-panel-box').height()-$('#photoCropBox-panel').height())/2+'px',
                left:($('#photoCropBox-panel-box').width()-$('#photoCropBox-panel').width())/2+'px',
                opacity:1
            })
        }
        //结束x,y 背景x,y
        function getPosition(_ex,_ey,_ty,_tx,_sx,_sy,_this) {
            if(_ex-_sx>0 && _ey-_sy>0){
                var _x=_sx-_tx,_y=_sy-_ty,_w=_ex-_sx,_h=_ey-_sy;
                if(_w>_this.width()-_x) _w=_this.width()-_x;
                if(_h>_this.height()-_y) _h=_this.height()-_y;
            }else if(!(_ex-_sx>0) && _ey-_sy>0){
                var _x=_ex-_tx,_y=_sy-_ty,_w=-(_ex-_sx),_h=_ey-_sy;
                if(_x<0) {_x=0;_w=_sx-_tx;}
                if(_h>_this.height()-_y) _h=_this.height()-_y;
            }else if(!(_ex-_sx>0) && !(_ey-_sy>0)){
                var _x=_ex-_tx,_y=_ey-_ty,_w=-(_ex-_sx),_h=-(_ey-_sy);
                if(_x<0) {_x=0;_w=_sx-_tx;}
                if(_y<0) {_y=0;_h=_sy-_ty;}
            }else if(_ex-_sx>0 && !(_ey-_sy>0)){
                var _x=_sx-_tx,_y=_ey-_ty,_w=_ex-_sx,_h=-(_ey-_sy);
                if(_y<0) {_y=0;_h=_sy-_ty;}
                if(_w>_this.width()-_x) _w=_this.width()-_x;
            }
            if(opt.fixedScale){
                if(_w/opt.fixedScale>_h){
                    _w=_h*opt.fixedScale
                }else if (_w<opt.fixedScale*_h){
                    _h=_w/opt.fixedScale
                }
            }
            resizeCropBox(_w,_h,_y,_x);
        }
        var c=document.getElementById("cropCanvas");
        var ctx=c.getContext("2d");
        var img=$('#dataImg');
        function getImage() {
            var scale=$('#photoCropBox-img').width()/$('#dataImg').width();
            var sx=parseInt(_corp.css('left'))/scale;
            var sy=parseInt(_corp.css('top'))/scale;
            var swidth=parseInt(_corp.css('width'))/scale;
            var sheight=parseInt(_corp.css('height'))/scale;
            var c_img = new Image;
            c_img.onload = function () {
                ctx.drawImage(c_img,sx,sy,swidth,sheight,0,0,swidth,sheight);
                var url=c.toDataURL("image/jpeg");
                opt.callBack(url);
            };
            c_img.crossOrigin = 'anonymous'; //可选值:anonymous,*
            c_img.src = imgSrc
            c.width = swidth;
            c.height = sheight;
        }
        //宽,高,top,left,m-是否是拖拽
        function resizeCropBox(w,h,t,l,m) {
            _corp.css(prefix()+'transition','all 0s');
            if(!m){
                _corp.css({
                    width:w,
                    height:h,
                    top:t+'px',
                    left:l+'px'
                })
            }else {
                _corp.css({
                    top:t+'px',
                    left:l+'px'
                })
            }
            cropBoxLine.find('img').css({
                top:-t+'px',
                left:-l+'px'
            })
        }
        function closeBox() {
            $('#photoCropBox').remove();
        }
        function prefix() {
            var prefixes=['','-ms-','-moz-','-webkit-','-o-'],i=0;
            while (i < prefixes.length){
                if($('body').css(prefixes[i]+'transition')){
                    return prefixes[i];
                }
                i++;
            }
        }
    }
})(jQuery) 
Licensed under 京ICP备17003353号-3