之前寫過一篇「前端如何使用 JS 先壓縮圖片尺寸大小再進行上傳」,其實也能處理前述大部分需求,但稍有不足之處:
- 只能對上傳的圖片等比例縮小
- 不能防止使用者上傳錯誤比例的圖片,例如需要橫躺長方形的比例,卻上傳了直立長方形,這會導致將來圖片顯示時版面效果不佳
- 所以最好能對上傳的圖片進行裁切,可確保圖片比例是正確的
- 如果裁切時有預覽畫面就更好了,讓使用者自行拖曳、縮放來調整裁切範圍,操作介面看起來會更專業
本篇要介紹的 jQuery 外掛 Croppie,完全符合以上的描述,效果也相當有水準,以下會提供 DEMO 效果及範例程式碼。
一、Croppie 介紹
1. Github 官網
以下是官網提供的相關連結:
- Github 官網:Croppie
- CDN 連結:CDNJS
- 說明文件:Documentation
雖然此外掛功能很強,可惜沒有一個很好的教學說明,只能想辦法從官方提供的幾個範例程式碼,來猜測參數要如何使用。
2. 範例效果
首先進入官方範例網址:
進入網頁後會立即看到上圖的範例效果,可直接在頁面上操作此區塊:
- 上方箭頭的區塊,可用滑鼠拖曳,讓圖片出現在適當的位置
- 中間箭頭的置中圓框,為設定好的裁切區域,可選擇圓形或方形,也可設定裁切尺寸
- 下方箭頭的調整軸,可對圖片進行縮放
這個範例效果即為此外掛的核心概念,往下捲還可看到各種 DEMO 範例,說明對應的程式碼要如何寫。
由於本篇為客製需求,因此後面只說明上傳圖片的裁切操作。
二、圖片裁切壓縮範例程式碼
需先載入 jQuery、Bootstrap,如網頁已安裝過,請移除綠字部分的程式碼:
<link href='//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css' rel='stylesheet'></link>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"></link>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/croppie/2.6.5/croppie.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/croppie/2.6.5/croppie.css" rel="stylesheet"></link>
<label class="btn btn-info"><input id="upload_img" style="display:none;" type="file" accept="image/*"><i class="fa fa-photo"></i> 上傳圖片</label>
<div id="oldImg" style="display:none;"></div>
<button id="crop_img" class="btn btn-info"><i class="fa fa-scissors"></i> 裁剪圖片</button>
<div id="newImgInfo"></div>
<div id="newImg"></div>
<script>
(function($) {
var width_crop = 300, // 圖片裁切寬度 px 值
height_crop = 200, // 圖片裁切高度 px 值
type_crop = "square", // 裁切形狀: square 為方形, circle 為圓形
width_preview = 350, // 預覽區塊寬度 px 值
height_preview = 350, // 預覽區塊高度 px 值
compress_ratio = 0.85, // 圖片壓縮比例 0~1
type_img = "jpeg", // 圖檔格式 jpeg png webp
oldImg = new Image(),
myCrop, file, oldImgDataUrl;
// 裁切初始參數設定
myCrop = $("#oldImg").croppie({
viewport: { // 裁切區塊
width: width_crop,
height: height_crop,
type: type_crop
},
boundary: { // 預覽區塊
width: width_preview,
height: height_preview
}
});
function readFile(input) {
if (input.files && input.files[0]){
file = input.files[0];
} else {
alert("瀏覽器不支援此功能!建議使用最新版本 Chrome");
return;
}
if (file.type.indexOf("image") == 0) {
var reader = new FileReader();
reader.onload = function(e) {
oldImgDataUrl = e.target.result;
oldImg.src = oldImgDataUrl; // 載入 oldImg 取得圖片資訊
myCrop.croppie("bind", {
url: oldImgDataUrl
});
};
reader.readAsDataURL(file);
} else {
alert("您上傳的不是圖檔!");
}
}
function displayCropImg(src) {
var html = "<img src='" + src + "' />";
$("#newImg").html(html);
}
$("#upload_img").on("change", function() {
$("#oldImg").show();
readFile(this);
});
oldImg.onload = function() {
var width = this.width,
height = this.height,
fileSize = Math.round(file.size / 1000),
html = "";
html += "<p>原始圖片尺寸 " + width + "x" + height + "</p>";
html += "<p>檔案大小約 " + fileSize + "k</p>";
$("#oldImg").before(html);
};
function displayNewImgInfo(src) {
var html = "",
filesize = src.length * 0.75;
html += "<p>裁切圖片尺寸 " + width_crop + "x" + height_crop + "</p>";
html += "<p>檔案大小約 " + Math.round(filesize / 1000) + "k</p>";
$("#newImgInfo").html(html);
}
$("#crop_img").on("click", function() {
myCrop.croppie("result", {
type: "canvas",
format: type_img,
quality: compress_ratio
}).then(function(src) {
displayCropImg(src);
displayNewImgInfo(src);
});
});
})(jQuery);
</script>
紅、藍字參數可自行調整參數,可參照註解說明:
- width_crop、height_crop 可改為自訂裁切尺寸
- type_crop 可調整裁切形狀
- width_preview、height_preview 可改為自訂預覽區塊尺寸
- compress_ratio 可調整圖片壓縮比例,0 ~ 1 之間的數值
- type_img 為圖檔格式
此範例程式碼的效果大致如上圖,後面有展示用的「上傳圖片」、「裁切圖片」按鈕可自行玩玩看效果。
三、圖片裁切壓縮效果展示
點擊下方的「上傳圖片」,並用滑鼠拖曳、縮放、選擇裁切區域後,點擊「裁切圖片」,會將圖片裁切為 300x200 px,並壓縮為 85%,有效縮減檔案大小,又不降低圖片品質。
更多網頁開發工具:
拜讀網誌大作已久,請教一個問題,暫無頭緒。
回覆刪除要做一個檔案清單,讓使用者可依喜好勾選,
然後伺服器打包成ZIP檔,給客戶下載。
請問該往哪個方向去找比較好,謝謝您。
一個網頁會列出目前的照片清單:
回覆刪除[勾選欄] [照片名稱]
--------------------
[ ]IMG1000.jpg
[ ]IMG1001.jpg
[ ]IMG1002.jpg
[ ]IMG1003.jpg
(下載按鈕)
這些照片都是在伺服端(server side),使用者可以勾選想要的編號後,
按「下載」由 server 打包成 image.zip 然後 push 給使用者。
有點像照片打包功能。謝謝