1. 程式人生 > >基於jquery的圖片裁剪外掛詳解

基於jquery的圖片裁剪外掛詳解

cropper外掛的使用參考

cropper介紹

相容所有支援了Canvas的瀏覽器(IE9+),一小部分功能例外,對移動端操作也有適配,支援裁剪、旋轉、翻轉等,具體請檢視官方文件。

但是它並沒有對圖片真正的處理,只是記錄了使用者做了哪些變換,然後需要自己再去處理

cropper使用

一、使用前準備:

二、option引數:var options = { '引數1': '值1', '引數2': '值2'}; $("#photo").cropper(options); 不完整,想了解全部引數可檢視官方API文件

  • viewMode:0(預設) [1 / 2 / 3] 對需裁剪圖片縮放&移動的限制。其中:0(沒有限制)、1(圖片縮放時最小不能小於裁剪框,可任意移動)、2(圖片縮放時最小不能小於它的外容器,圖片移動時上下或左右必須貼著外容器)、3(圖片縮放時最小不能小於它的外容器,圖片移動時上下左右都必須貼著外容器)
  • dragMode: 'crop'(預設) ['move' / 'none'] 其中:crop(當滑鼠點選裁剪框外的一處時根據這個點重新生成一個 裁剪框)、move(可以拖動圖片)、none(什麼也不做)
  • aspectRatio: 寬 / 高 值為裁剪框的寬高比(預設NaN)
  • preview: str 值為顯示預覽圖的容器選擇器,如 div.box
  • responsive: true [false] 是否響應式,在調整視窗大小時重新渲染裁剪器
  • modal: true [false] 是否顯示裁剪框外的黑色半透明背景
  • cropBoxMovable: true [false] 是否允許拖動改變裁剪框大小,預設true
  • guides: true [false] 是否顯示裁剪框上的虛線
  • center:true [false] 是否顯示裁剪框上的中心指示器
  • highlight: true [false] 是否高亮顯示裁剪框中的影象
  • movable: true [false] 是否允許移動影象
  • rotatable: true [false] 是否允許旋轉影象
  • scalable: true [false] 是否允許縮放影象

事件相關

  • ready:初始化完成,只調用一次
  • cropstart:移動(裁剪框或圖片)開始
  • cropmove:移動(裁剪框或圖片)
  • cropend:移動(裁剪框或圖片)結束
  • crop:當畫布或裁剪框改變時
  • zoom:圖片縮放事件

三、Methods方法(如需要將裁剪後的影象上傳給伺服器,請仔細看下面的getCroppedCanvas方法

由於cropper是非同步載入的,所以除 setAspectRatio 和 destroy 之外的事件都應該放在ready事件引數中(下面的方法列表說明都是放在ready內的,重複的程式碼就不再寫了):

$("#photo").cropper({
  ready: function () {
    $(this).cropper('method', argument1, , argument2, ..., argumentN);
  }
});
  • crop():手動顯示裁剪框
autoCrop: false,
ready: function () {
    $(this).cropper('crop');
}
  • reset():將影象和裁剪框重置為初始狀態

  • clear():清除裁剪框

  • replace(url[, onlyColorChanged]):替換影象的 url 並重建cropper
    • url:新的圖片url地址
    • onlyColorChanged :預設值為false,如果只改變顏色,而不改變大小,那麼cropper只需要改變所有相關影象的src,而不需要重建cropper。這可以用於filters應用
  • disable():凍結(禁用)cropper
  • enable():解凍 cropper
  • destroy():銷燬cropper,並從影象中刪除例項
  • move(offsetX[, offsetY]):值為number型別,分別表示水平/垂直 方向的移動尺寸(px值,offsetY預設值同offsetX)。$(this).cropper('move', 1, -1);
  • moveTo(x[, y]):將畫布(影象的容器)移動到絕對點。值為number型別,x, y分別表示畫布的 left / top 值(y預設值同x)
  • zoom(ratio):以相對比例縮放畫布(影象的容器)。值為number型別,ratio>0時放大,ratio<0時縮小。$(this).cropper('zoom', -0.1);
  • zoomTo(ratio):縮放畫布(影象的容器)到絕對比率。值為number型別
  • rotate(degree):以相對角度旋轉影象。值為number型別,正數向右旋轉,負數向左旋轉。$(this).cropper('rotate', 90);
  • rotateTo(degree):旋轉影象到絕對角度
  • scale(scaleX[, scaleY]):縮放影象。值為number型別,引數分別表示影象在橫 / 縱座標上的縮放(scaleX預設值為1、scaleY預設值同scaleX)。$(this).cropper('scale', -1, 1);
  • scaleX(scaleX):影象在橫座標上的縮放。值為number型別(預設值為1)
  • scaleY(scaleY):影象在縱座標上的縮放。值為number型別(預設值為1)
  • getData([rounded]):預設值為false,設定true可獲得舍入值。var getData = $image.cropper("getData");有object型別的記錄使用者操作的返回值,可將此返回值傳送給伺服器端以直接輸出影象。其中:
    • x:裁剪框左邊的偏移量
    • y:裁剪框頂部的偏移量
    • width:裁剪框的寬
    • height:裁剪框的高
    • rotate:影象旋轉角度
    • scaleX:影象在橫座標上的縮放
    • scaleY:影象在縱座標上的縮放
  • setData(data):用新資料(基於原始影象)改變裁剪框的位置和大小(注意:此方法僅在 viewmode 選項大於或等於1時可用)。data引數為與getData()返回值相同的Object物件,如:$(this).cropper("setData", { x: 203, y: 491, width: 393, height: 393, rotate: 90, scaleX: 2, scaleY: 2 });
  • getContainerData():返回容器大小資料,object型別,引數為:包含容器的當前寬 / 高度
  • getImageData():返回object型別的影象的位置、大小等相關資料:{ left: 0, top: 0, width: 700, height: 393.75, naturalWidth: 1280, naturalHeight: 720, aspectRatio: 1.7, rotate: 0, scaleX: 1, scaleY: 1 }。引數為:影象的左偏移量、影象的上偏移量、影象的寬、影象的高、影象的自然寬度、影象的自然高度、影象的縱橫比、影象的旋轉角度、影象在橫座標上的縮放、影象在縱座標上的縮放
  • getCanvasData():返回object型別的畫布(影象的容器)的位置和大小資料:{ left: 115.7, top: -241.4, width: 476.4, height: 847.0, naturalWidth: 720, naturalHeight: 1280 }。引數為:影象的左偏移量、影象的上偏移量、影象的寬、影象的高、影象的自然寬度、影象的自然高度
  • setCanvasData(data):用新資料更改畫布(影象包裝器)的位置和大小。data引數為Object型別:{ left: 畫布左邊的新偏移量, top: 畫布上邊的新偏移量, width: 畫布的新寬度, height: 畫布的新高度 }
  • getCropBoxData():輸出object型別的裁剪框的位置和大小資料:{ left: 裁剪框左側的偏移量, top: 裁剪框上邊的偏移量, width: 裁剪框的寬度, height: 裁剪框的高度 }
  • setCropBoxData(data):用新資料更改裁剪框的位置和大小。data引數為Object型別:{ left: 裁剪框左邊的新偏移量, top: 裁剪框上邊的新偏移量, width: 裁剪框的新寬度, height: 裁剪框的新高度 }
  • getCroppedCanvas([options])
    • options物件引數:width(輸出畫布的指定寬度)、height(輸出畫布的指定高度)、minWidth(輸出畫布的最小目標寬度,預設值為0)、minHeight(輸出畫布的最小目標高度,預設值為0)、maxWidth(輸出畫布的最大目標寬度,預設值為0)、maxHeight(輸出畫布的最大目標高度,預設值為0)、fillColor(用於填充輸出畫布中任何alpha值的顏色,預設值是透明的)、imageSmoothingEnabled(設定影象是否平滑,預設true)、imageSmoothingQuality(設定影象平滑的質量,low(預設) / high)
    • 返回值:畫出剪裁影象的畫布(一個canvas DOM)
    • 注意:1)輸出畫布的長寬比將自動擬合到裁剪框的長寬比(可以理解為把裁剪框內的影象拉伸為options中指定的寬高);2) 如果希望從輸出畫布中獲取JPEG影象,應該首先設定fillColor選項,否則JPEG影象中的透明部分將預設為黑色;
    • 重要:可以用此返回值呼叫(如果瀏覽器支援這些API):1) HTMLCanvasElement .toDataURL 獲取base64格式的資料、2) HTMLCanvasElement .toBlob 獲取blob,直接將畫布顯示為影象,且可使用FormData將其上傳到伺服器
//var base64 = $(this).cropper('getCroppedCanvas',{ width:750, height:582 }).toDataURL('image/png');
//$target.attr('src', base64);

$(this).cropper('getCroppedCanvas', {
  width: 160,
  height: 90,
  fillColor: '#fff'
}).toBlob(function (blob) {
  var formData = new FormData();
  formData.append('croppedImage', blob);
  $.ajax('/path/to/upload', {
    method: "POST",
    data: formData,
    processData: false,
    contentType: false,
    success: function () {
      console.log('Upload success');
    },
    error: function () {...}
  });
});;
  • setAspectRatio(aspectRatio):改變裁剪框的長寬比,引數為一個正數
  • setDragMode([mode]):改變拖曳模式。可以通過雙擊裁剪框來切換crop和move。mode可選:’none’ / ‘crop’ / ‘move’,預設none

cropper示例

  • 基礎例項
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <link href="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.css" rel="stylesheet">
    <style>
        #imgBox { width: 700px }
        #photo { max-width: 100% }
        .img-preview { width: 150px; height: 150px; display: inline-block; margin-top: 10px; overflow: hidden }
        .showImgBox { width: 140px; height: 140px; display: inline-block }
        #showImg { max-width: 100% }
    </style>
</head>
<body>
    <div id="imgBox">
        <img src="http://oyd8w2s7w.bkt.clouddn.com/2018/08/23/3147b2e4-748e-4c22-95fc-62695c2d3320.jpg" alt="" id="photo">
    </div>
    <div class="img-preview"></div>
    <button type="button" id="clipImg">裁剪圖片</button>
    <div class="showImgBox">
        <img src="" id="showImg" alt="裁剪結果">
    </div>
    <br>
    <button type="button" id="toLeft">左轉90度</button>
    <button type="button" id="toRight">右轉90度</button>

<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.js"></script>
<script>
    $(function(){
        var $image = $("#photo");
        $image.cropper({
            aspectRatio: 1,
            dragMode: 'move',
            viewMode: 1,
            cropBoxResizable: false,
            preview: '.img-preview',
            ready: function(){
                $("#toRight").on("click", function(){ $image.cropper('rotate', 90) });
                $("#toLeft").on("click", function(){ $image.cropper('rotate', -90) });
                $("#clipImg").on("click", function(){
                    $image.cropper('getCroppedCanvas',{
                        width:140,   // 裁剪後的長寬
                        height:140
                    }).toBlob(function(blob){
                        $("#showImg").attr('src', URL.createObjectURL(blob));    // 將裁剪後的圖片放到指定標籤展示
                    });
                });
            }
        });
    });
</script>
</body>
</html>
  • input type=file上傳檔案並上傳到伺服器
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>裁剪圖片</title>
    <link href="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.css" rel="stylesheet">
    <style>
        #photo { max-width: 100% }
        .img-preview { width: 100px; height: 100px; overflow: hidden }
        #selectImg { width: 375px; height: 150px }
    </style>
</head>
<body>
<form id="form">
    <!--表單部分-->
    <div>
        <label>選擇圖片</label>
        <span>
            <img src="" alt="裁剪結果" id="selectImg" style="display: none">
            <input type="file" id="imgInp" class="sr-only" style="display: none">
            <button type="button" class="pictureUrl" onclick="$('#imgInp').click()" id="uploadImg">選擇圖片</button>
        </span>
    </div>
</form>

<div id="cropperBox">
    <!--裁剪部分-->
    <div>
        <img src="" id="photo">
    </div>
    <!--預覽提示、裁剪操作-->
    <p>預覽 <button class="btn btn-primary" onclick="crop()">裁剪圖片</button></p>
    <!--預覽-->
    <div class="img-preview"></div>
</div>

<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.js"></script>
<script>
    var initCropper = function (img, input){
        var $image = img;
        var options = {
            aspectRatio: 5 / 2,
            dragMode: 'move',
            viewMode: 1,
            cropBoxResizable: false,
            preview: '.img-preview'
        };
        $image.cropper(options);
        var $inputImage = input;
        var uploadedImageURL;
        if (URL) {
            $inputImage.change(function () {  // 給input新增監聽
                $("#form").hide();
                $("#cropperBox").slideDown();
                var files = this.files;
                var file;
                if (!$image.data('cropper')) {
                    return;
                }
                if (files && files.length) {
                    file = files[0];
                    if (/^image\/\w+$/.test(file.type)) {   // 判斷是否是影象檔案
                        if (uploadedImageURL) {   // 如果URL已存在就先釋放
                            URL.revokeObjectURL(uploadedImageURL);
                        }
                        uploadedImageURL = URL.createObjectURL(file);
                        // 銷燬cropper後更改src屬性再重新建立cropper
                        $image.cropper('destroy').attr('src', uploadedImageURL).cropper(options);
                        $inputImage.val('');
                    } else {
                        window.alert('請選擇一個影象檔案!');
                    }
                }
            });
        } else {
            $inputImage.prop('disabled', true).addClass('disabled');
        }
    };
    var crop = function(){
        var $image = $('#photo');
        var $target = $('#selectImg');
        $image.cropper('getCroppedCanvas',{
            width:750,
            height:300
        }).toBlob(function(blob){
            $("#form").show();
            $("#cropperBox").slideUp();
            $("#selectImg").show();
            $target.attr('src', URL.createObjectURL(blob));    // 將裁剪後的圖片放到指定標籤
            var formData = new FormData();      // 將裁剪後的圖片上傳到伺服器
            formData.append('croppedImage', blob);
            $.ajax('/uploadImg', {
                method: "POST",
                data: formData,
                processData: false,
                contentType: false,
                success: function () { }
            });
        });
    };
    $(function(){
        initCropper($('#photo'),$('#imgInp'));
    });
</script>
</body>
</html>
  • 使用微信JSSDK選擇圖片並得到裁剪後的base64位的圖片(可直接將base64的資料傳給伺服器)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>裁剪圖片</title>
    <link href="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.css" rel="stylesheet">
    <style>
        #photo { max-width: 100% }
        .img-preview { width: 100px; height: 100px; overflow: hidden }
        #selectImg { width: 375px; height: 150px }
    </style>
</head>
<body>
    <form id="form">
        <img src="" alt="裁剪結果" id="selectImg" style="display: none">
        <button type="button" class="pictureUrl" id="uploadImg">選擇圖片</button>
    </form>
    <!--裁剪部分-->
    <div id="cropperBox">
        <div><img src="" id="photo"></div>
        <button class="btn btn-primary" onclick="crop()">裁剪圖片</button>
        <!--預覽-->
        <div class="img-preview"></div>
    </div>

    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
    <script src="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.js"></script>
        $.ajax({   //微信驗證
           url: "wechat/getSignature",
            type: "post",
            data: { "url": window.location.href },
            dataType: "json",
            success: function (data) {
                wx.config({
                    appId: data.data.appId,
                    timestamp: data.data.timestamp,
                    nonceStr: data.data.nonceStr,
                    signature: data.data.signature,
                    jsApiList: ['chooseImage','uploadImage']
                });
            }
        });
        $("#uploadImg").on("click", function(){    //點選選擇圖片
            wx.chooseImage({
                count: 1,
                sizeType: ['original'],
                success: function(res) {
                    var url = res.localIds[0];
                    $("#photo").cropper('destroy').attr('src', url).get(0).onload = function(){
                        $(this).cropper({
                            aspectRatio: 125 / 97,
                            dragMode: 'move',
                            viewMode: 1,
                            cropBoxResizable: false,
                            preview: '.img-preview'
                        });
                    };
                    $("#coupon").hide();
                    $("#cropperBox").show();
                }
            });
        });
        var crop = function(){     //開始裁剪圖片
            var $image = $('#photo');
            var $target = $('#selectImg');
            var base64 = $image.cropper('getCroppedCanvas',{
                width:750,     //裁剪後的寬高(最終想要的圖片尺寸)
                height:582
            }).toDataURL('image/png');
            $target.attr('src', base64); //裁剪後將圖片放到指定標籤
            $("#coupon").show();
            $("#cropperBox").hide();
            $(".selectImg").removeClass("hide");
        };
    </script>
</body>
</html>