【jquery】使用canvas實現前端裁剪圖片,並上傳到服務器

這裏需要用到jquery Jcrop 插件實現前端選擇圖片區域效果

然後使用canvas裁剪圖片,並把base64位的toDataURL圖片轉換成blob

最後使用XMLHttpRequest上傳到服務器。


預覽效果:


整體代碼:

<!doctype html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"/>
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
  <meta name="description" id="description1" content="1">
  <meta name="renderer" content="webkit">
  <meta name="format-detection" content="telephone=no">
  <title>圖片上傳</title>


    <style type="text/css">
    * {
        box-sizing: border-box; /* h5 */
        -moz-box-sizing: border-box; /* Firefox */
        -webkit-box-sizing: border-box; /* Safari */
        margin: 0;
        padding: 0;
        outline: 0 none;
        font-weight: inherit;
        font-style: inherit;
        font-family: inherit;
        vertical-align: baseline;
    }
    .jcrop-holder {
        direction: ltr;
        text-align: center;
        margin: 0 auto;
        /* IE10 touch compatibility */
        -ms-touch-action: none;
    }
        /* Selection Border */
    .jcrop-vline,
    .jcrop-hline {
        background: #ffffff url("Jcrop.gif");
        font-size: 0;
        position: absolute;
    }
    .jcrop-vline {
        height: 100%;
        width: 1px !important;
    }
    .jcrop-vline.right {
        right: 0;
    }
    .jcrop-hline {
        height: 1px !important;
        width: 100%;
    }
    .jcrop-hline.bottom {
        bottom: 0;
    }
        /* Invisible click targets */
    .jcrop-tracker {
        height: 100%;
        width: 100%;
        /* "turn off" link highlight */
        -webkit-tap-highlight-color: transparent;
        /* disable callout, image save panel */
        -webkit-touch-callout: none;
        /* disable cut copy paste */
        -webkit-user-select: none;
    }
        /* Selection Handles */
    .jcrop-handle {
        background-color: #333333;
        border: 1px #eeeeee solid;
        width: 7px;
        height: 7px;
        font-size: 1px;
    }
    .jcrop-handle.ord-n {
        left: 50%;
        margin-left: -4px;
        margin-top: -4px;
        top: 0;
    }
    .jcrop-handle.ord-s {
        bottom: 0;
        left: 50%;
        margin-bottom: -4px;
        margin-left: -4px;
    }
    .jcrop-handle.ord-e {
        margin-right: -4px;
        margin-top: -4px;
        right: 0;
        top: 50%;
    }
    .jcrop-handle.ord-w {
        left: 0;
        margin-left: -4px;
        margin-top: -4px;
        top: 50%;
    }
    .jcrop-handle.ord-nw {
        left: 0;
        margin-left: -4px;
        margin-top: -4px;
        top: 0;
    }
    .jcrop-handle.ord-ne {
        margin-right: -4px;
        margin-top: -4px;
        right: 0;
        top: 0;
    }
    .jcrop-handle.ord-se {
        bottom: 0;
        margin-bottom: -4px;
        margin-right: -4px;
        right: 0;
    }
    .jcrop-handle.ord-sw {
        bottom: 0;
        left: 0;
        margin-bottom: -4px;
        margin-left: -4px;
    }
        /* Dragbars */
    .jcrop-dragbar.ord-n,
    .jcrop-dragbar.ord-s {
        height: 7px;
        width: 100%;
    }
    .jcrop-dragbar.ord-e,
    .jcrop-dragbar.ord-w {
        height: 100%;
        width: 7px;
    }
    .jcrop-dragbar.ord-n {
        margin-top: -4px;
    }
    .jcrop-dragbar.ord-s {
        bottom: 0;
        margin-bottom: -4px;
    }
    .jcrop-dragbar.ord-e {
        margin-right: -4px;
        right: 0;
    }
    .jcrop-dragbar.ord-w {
        margin-left: -4px;
    }
        /* The "jcrop-light" class/extension */
    .jcrop-light .jcrop-vline,
    .jcrop-light .jcrop-hline {
        background: #ffffff;
        filter: alpha(opacity=70) !important;
        opacity: .70!important;
    }
    .jcrop-light .jcrop-handle {
        -moz-border-radius: 3px;
        -webkit-border-radius: 3px;
        background-color: #000000;
        border-color: #ffffff;
        border-radius: 3px;
    }
        /* The "jcrop-dark" class/extension */
    .jcrop-dark .jcrop-vline,
    .jcrop-dark .jcrop-hline {
        background: #000000;
        filter: alpha(opacity=70) !important;
        opacity: 0.7 !important;
    }
    .jcrop-dark .jcrop-handle {
        -moz-border-radius: 3px;
        -webkit-border-radius: 3px;
        background-color: #ffffff;
        border-color: #000000;
        border-radius: 3px;
    }
        /* Simple macro to turn off the antlines */
    .solid-line .jcrop-vline,
    .solid-line .jcrop-hline {
        background: #ffffff;
    }
        /* Fix for twitter bootstrap et al. */
    .jcrop-holder img,
    img.jcrop-preview {
        max-width: none;
    }
        .uploadPics {
            position: relative;
            margin: 0 auto;
            width: 380px;
            background-color: #fff;
            border-top: 3px solid #ed2828;
            height: 460px;
            overflow: hidden;
        }

        .uploadPics > img {
            position: absolute;
            top: 20px;
            right: 10px;
            cursor: pointer;
        }

        .uploadPics .picTil {
            padding: 20px;
            font-size: 16px;
            color: #323232;
            border-bottom: 1px solid #f3f3f3;
        }

        .uploadPics .picCont {
            margin: 20px;
            padding: 15px;
            width: 300px;
            height: 337px;
            background-color: #f2f2f5;
        }

        .uploadPics .picCont > p {
            margin-top: 20px;
            text-align: center;
        }


        .uploadPics .picFooter {
            text-align: center;
        }

        .uploadPics .picFooter .btn {
            display: inline-block;
            margin: 20px;
            width: 130px;
            height: 35px;
            font-size: 18px;
            line-height: 35px;
            color: #fff;
            border-radius: 5px;
            cursor: pointer;
        }

        .uploadPics .picFooter .upload {
            background-color: #aaa;
        }

        .uploadPics .picFooter .confirm {
            background-color: #ed2828;
        }
        #myCan{
            position: absolute;
            top: 50px;
            right: 50px;
        }
    </style>
</head>
<body>

<div class="uploadPics">
    <img src="../images/AvatarClose.png" alt="" onclick="ClosePage()" />
    <div class="picTil">上傳頭像</div>
    <div class="picCont" style="width:300px;height:300px;margin:20px auto 0;padding:0;" >
        <div id=imgfield  style=overflow:hidden;width:100%;height:100% ></div>
    </div>
    <div class="picFooter">
        <input type="file" id="fileimg" name="fileimg" style="display:none" onchange="imgchange()" />

        <span class="btn upload"  onclick="getimg()">上傳</span>
        <span class="btn confirm" onclick="subform()">確認</span>

    </div>

</div>

<canvas id="myCan" width="200" height="200"></canvas>

</body>
<script type="text/javascript" src="http://182.92.213.51:1070/html/js/inc/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="http://182.92.213.51:1070/html/js/inc/jquery.Jcrop.js"></script>

<script type="text/javascript">


    function subform() {

        if($("#imgfield").html()){
            //獲取裁剪完後的base64圖片url,轉換爲blob
            var data=document.getElementById("myCan").toDataURL();
            var formData=new FormData();
            formData.append("imageName",dataURLtoBlob(data));


            var httprequest=new XMLHttpRequest();
            var apiurl=""; //上傳圖片的api接口,自行填寫
            httprequest.open('POST',apiurl,true);
            httprequest.send(formData);
            httprequest.onreadystatechange= function () {
                if(httprequest.status==200 && httprequest.readyState==4){

                    var json=JSON.parse(httprequest.responseText);
                    console.log(json)
                }else{
                    alert("上傳圖片失敗!api錯誤")
                }
            };


        }else{

            alert("請選擇圖片!")
        }


    }


    function getimg() {

        $("#fileimg").click();

    }
    function imgchange() {

        var localimg = $("#fileimg").get(0).files[0];

        if(!localimg){
            return;
        }

        var fileName = localimg.name;
        var fileSize = localimg.size;
        var fileType=fileName.substring(fileName.lastIndexOf('.'),fileName.length).toLowerCase();
        if(fileType!='.gif' && fileType!='.jpeg' && fileType!='.png' && fileType!='.jpg')
        {
            alert("上傳失敗,請上傳jpg,png格式的圖片");
            return;
        }

        var size=3*1024*1024;
        if(fileSize>size){
            alert("上傳失敗,請上傳3MB以內的圖片。");
            return;
        }

        var reader=new FileReader();
        //將文件讀取爲DataURL
        reader.readAsDataURL(localimg);
        reader.onload= function (e) {
            var localimghtml = '<img id="cropbox" src="' +  e.target.result + '" >';
            $("#imgfield").html(localimghtml);
            initJcrop();
        };

    }


    function initJcrop(){
        $('#cropbox').Jcrop({
            onSelect: updateCoords,
            aspectRatio: 1,
            boxWidth: 300,
            boxHeight: 300
        }, function () {

            //圖片實際尺寸
            var bb = this.getBounds();
            var bWidth= Number(bb[0]) / 2;
            var bHeight= Number(bb[1]) / 2;

            this.setSelect([0, 0, bWidth,bHeight]);


            var ss = this.getWidgetSize();
            var aheight = (300 - Number(ss[1])) / 2 + "px";
            $(".jcrop-holder").css("margin-top", aheight);


        });
    }
    function updateCoords(c){
//      console.log(c);
        var img=document.getElementById("cropbox");
        var ctx=document.getElementById("myCan").getContext("2d");

        //img,開始剪切的x,Y座標寬高,放置圖像的x,y座標寬高。
        ctx.drawImage(img,c.x,c.y, c.w, c.h,0,0,200,200);
    }



    //**dataURL to blob**
    function dataURLtoBlob(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 Blob([u8arr], { type: mime });
    }


</script>


</html>



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章