實作圖片的壓縮,上傳功能
簡言:在前端開發中,我們經常會遇見圖片上傳等功能,
很多前端作業者 都知道利用input的 file功能實作圖片上傳的樣式

常用的可能是 用一個a標簽包裹著input 實作按鈕狀的上傳樣式

但是在深層次的上傳和壓縮功能 卻知知甚少
下邊我將以個人案例幫助大家了解 上傳 壓縮等功能
首先 圖片壓縮的原理是 獲取當前圖片檔案轉化成base64格式, 創建image物件把圖片的base64賦值上去
獲取改圖片的實際大小,定義需要壓縮后呈現的尺寸 除以當前的圖片尺寸 得出 壓縮比.
利用壓縮比計算出 實際壓縮后的圖片
(有人會問 我可以直接定義圖片的大小啊 比如800*800 還計算干嘛)
答:會變形 失貞 我們希望壓縮后的圖片比例和之前一樣.
最后把計算后的尺寸 利用canvas 繪制出來 并使用canvas.toDataURL 匯出 完成壓縮
最后再計算出 壓縮后的base64地址 生成一個回呼完成上傳;
不多BB 上代碼
按鈕樣式:給新手看的 大佬跳過
.import_btn {
display: block;
margin: 100px;
width: 50px;
text-align: center;
color: #fff;
border-radius: 5px;
position: relative;
text-decoration: none;
padding: 10px 20px;
background: #e56233;
}
#upload {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0;
}
<a href="javascript:;" class="import_btn"> 上傳
<input type="file" id="upload">
</a>
上邏輯:
const ACCEPT = ["image/png", "image/jpg","image/jpeg"]
const MAXSIZE = 1920 * 1080;
const MAXSIZE_STR = '1MB';
function convertImageToBase64(file, callback) {
// 實體化reader物件
let reader = new FileReader(); //FileReader 物件允許Web應用程式異步讀取存盤在用戶計算機上的檔案
reader.addEventListener("load", function (e) {
const base64Image = e.target.result;
callback && callback(base64Image); //執行回呼 把得到base64傳遞出去
// 使用完成重置reader 釋放記憶體
reader = null;
});
reader.readAsDataURL(file);
};
function compress(base64Image,callback) {
// 創建一個image 物件
const image = new Image();
// 設定最大寬高
let maxW = 1024;
let maxH = 1024;
// load 指圖片加載完成 自動執行
image.addEventListener('load', function (e) {
let ratio; //圖片的壓縮比
let needCompress = false;//是否需要進行壓縮
if (maxW < image.naturalWidth) { //naturalWidth 圖片的實際寬度
needCompress = true; //需要壓縮
ratio = image.naturalWidth / maxW;//獲得壓縮比
maxH = image.naturalHeight / ratio //高度根據獲取的壓縮比 同比進行壓縮
};
// 進行寬高倆次判斷 防止寬度符合后直接跳過
if (maxH < image.naturalHeight) {
needCompress = true;
ratio = image.naturalHeight / maxH;
maxW = image.naturalWidth / ratio;
};
// 如果圖片過小 就取實際尺寸
if (!needCompress) {
maxW = image.naturalWidth;
maxh = image.naturalHeight;
}
// 把壓縮后的圖片繪制出來
const canvas = document.createElement("canvas"); //創建Dom
canvas.setAttribute("id", "_compress_");//添加一個id
canvas.width = maxW;
canvas.height = maxH;
canvas.style.visibility = "hidden";//壓縮程序 bu可見
document.body.appendChild(canvas);
// 繪制
const ctx=canvas.getContext("2d");//創建2d繪制
ctx.clearRect(0,0,maxW,maxH);//清理畫布上原有的像素 防止圖片疊加 坐標
ctx.drawImage(image,0,0,maxW,maxH);//繪制圖片 起始坐標 圖片大小
// 獲取壓縮后圖片的 base64
const compressImage=canvas.toDataURL("image/jpeg",0.9);
callback&&callback(compressImage);//執行回呼函式 傳出壓縮后的照片
//展示圖片(壓縮后) 后期可剔除
const _image=new Image();
_image.src=compressImage;
document.body.appendChild(_image);
canvas.remove();
});
//展示 把傳遞過來的base64(未壓縮)路徑賦值到新創建的image上
image.src = base64Image;
document.body.appendChild(image);
};
// 回呼函式 把壓縮后的base64傳給后端 實作上傳
function uploadToServer(compressImage){
// console.log("aka",compressImage);
}
// 給 input系結監聽事件 獲取到上傳的圖片資訊
const upload = document.getElementById('upload');
upload.addEventListener("change", function (e) {
// console.log(e.target.files); 當前檔案的資訊
// 結構賦值
const [file] = e.target.files;
const { type: fileType, size: fileSize } = file;
/*
* 非空判斷
*/
if (!file) {
return
}
/*
*
ES6寫法 ACCEPT [上邊定義的圖片型別] includes:判斷有無 .前的資料型別
*/
if (!ACCEPT.includes(fileType)) {
alert('不支持[' + fileType + ']檔案型別');
upload.value = '';
return;
}
/*
* 尺寸判斷
*/
if (fileSize > MAXSIZE) {
alert(`檔案超出${MAXSIZE_STR}!`);
upload.value = '';
return;
}
/*
* 壓縮圖片
1.圖片轉為base64
回呼+回呼+回呼
*/
convertImageToBase64(file,(base64Image)=> compress(base64Image,uploadToServer));
})
如果你仍然覺得 看起來有些困難:我在最后 補一段注釋:
前言 圖片壓縮上傳是一個相對復雜的功能
* 1.需要一個上傳按鈕 input的file 格式
2.監聽input框的 change事件 上傳成功后 通過files 拿到圖片的各種資訊
3.通過對檔案的前置判斷,型別 可上傳大小 寬高等..
4.圖片壓縮:
一.首先將獲取到的圖片轉化成base64格式
通過FileReader物件(webAPI 可獲取儲存在計算機上的檔案)
呼叫他的API readAsDataURL(file)
readAsDataURL() 方法會讀取指定的 Blob 或 File 物件,
讀取操作完成的時候,readyState 會變成已完成DONE,
并觸發 loadend 事件,同時result 屬性將包含一個data:URL格式的字串(base64編碼)以表示所讀取檔案的內容,
獲取成功后,執行 compress() 回呼事件 屬于壓縮核心;
二.compress屬于壓縮的核心代碼
創建一個圖片的Dom new Image
把我們獲取到的base64地址 賦值給這個圖片 然后加載到頁面上
在 監聽image .load (圖片加載完成的回呼);
此時已獲取到 當前base64圖片的實際大小 尺寸
然后我們對 需要展示的圖片占比和實際的圖片占比
當圖片超出我們需要壓縮后的尺寸時 得出壓縮比例 radio(實際尺寸/需要壓縮的尺寸);
利用壓縮比計算出 圖片壓縮后的尺寸 并使得圖片不會變形
三.創建一個canvas 把計算后的尺寸賦值給canvas 并設定該canvas不可見(理解為 壓縮程序隱藏)
拿到canvas物件,呼叫canvas.drawImage繪制出來;并轉換成需要呈現的圖片格式
const compressImage=canvas.toDataURL("image/jpeg",0.9); (格式,圖片質量);
此時已經拿到壓縮后的 圖片base64
通過callback傳遞給后端 即可完成上傳
四.為了更好的演示 我在案例中分別展示了2張圖片(壓縮前 壓縮后);實際開發中,可將這部分邏輯洗掉
你get 了啵 T_T
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/235504.html
標籤:其他
上一篇:計算屬性與監聽屬性
