JS前端圖片壓縮上傳重點知識
最近在做一個手機端的圖片上傳,寫了一個比較符合自己要求的方法,可供參考
在做這個功能模塊時,我遇到了以下問題,都花費了大量時間:
1. 不知道怎么壓縮圖片,(代碼和方法)
2. 得到圖片壓縮后的base64值,也可以預覽,但卻傳不到后端去
3. 怎么確保我想要壓縮的所有圖片,大小都相近,圖片還盡可能的清晰(如我參考了網上的代碼,基本都是按照比例壓縮如1/2或1/4,那一個10m的圖片壓縮完后還有5m或者2.5m,意義不大,那你說比例調大些,按照1/10比例壓縮,這樣萬一我上傳的檔案只有200k,這樣一壓縮圖片就嚴重失真了)
4. 將檔案發送到后端時攜帶引數問題
代碼沒有捷徑可走啊!!····
=-目前博主參考的是jQuery和layui框架,如不用layui框架注釋掉相應的樣式即可,影響的只有界面,可能要稍稍修改HTML
實體代碼如下:
<%--
Created by IntelliJ IDEA.
User: ASUS
Date: 2021/2/22
author: xumz
To change this template use File | Settings | File Templates.
搬運請備注
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- meta使用viewport以確保頁面可自由縮放 -->
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
<title>身份驗證</title>
<%--參考jQuery和layui框架,如不用layui框架注釋掉相應的樣式即可,影響的只有界面--%>
<script src=" ../js/jquery-1.9.1.min.js"></script>
<script src="../js/layui/layui.js"></script>
<link rel="stylesheet" href="../js/layui/css/layui.css" media="all">
<style type="text/css">
[id^="layui-layer"] {
border-radius: 9px !important;
}
.up_img_showborder {
border: 1px rgba(143, 143, 143, 0.43) dashed;
width: 85%;
height: 165px;
margin: 25px;
}
#img_one {
border: 1px #F2F2F2 solid;
max-width: 96%;
max-height: 160px;
/*padding: 4px;*/
}
.icon_style {
font-size: 50px;
color: #efefef;
line-height: 100px;
}
</style>
</head>
<body>
<div style="width: 90%;height: 100%;margin: auto;" align="center">
<div id="upload_img01" class="up_img_showborder">
<div id="hiden_one">
<i class="layui-icon layui-icon-addition icon_style"></i>
<p style="color: gray">點擊上傳圖片</p>
</div>
<div class="layui-hide" id="uploadDemoView">
<img class="layui-upload-img" id="img_one">
</div>
</div>
<div>
<input type="button" class="layui-btn layui-btn-normal layui-btn-lg" onclick="next_btn(this)" value="確認">
</div>
<div>
<input type="file" style="visibility: hidden" accept="image/*" id="btn1">
</div>
</div>
<script type="text/javascript">
//參考layui不可少
layui.use(['form', 'layer', 'upload'], function () {
var form = layui.form
, layer = layui.layer
, upload = layui.upload;
});
/*點擊上傳正面圖片*/
$(document).on('click', '#upload_img01', function () {
document.getElementById("btn1").click();
});
var BlobDealImg = null;
/*input資料改變時,獲取檔案資料,上傳正面*/
$("#btn1").change(function () {
console.log(this.files[0].size);
let up_ImgBase64 = this.files[0]; //獲取檔案物件
if (null != up_ImgBase64 && up_ImgBase64 != "") {
layer.msg("影像采集成功!");
var reader = new FileReader();
reader.readAsDataURL(up_ImgBase64); //將讀取的檔案轉換成base64格式
reader.onload = function (e) {
var dataBase64 = e.target.result; //result是你讀取到的檔案內容,此屬性讀取完成才能使用
// console.log('dataBase64==='+dataBase64);
dealImage(dataBase64);
setTimeout(function () {
console.log(BlobDealImg);
}, 50);
}
} else {
layer.open({
title: ['提示', 'border-radius: 6px;']
, shadeClose: true
, resize: false
, content: '影像采集失敗,請重新采集!'
});
}
});
function dealImage(base) {
let image = new Image(); //新建一個img標簽(不嵌入DOM節點,僅做canvas操作)
image.src = base; //讓該標簽加載base64格式的原圖
image.onload = function () { //圖片加載完畢后再通過canvas壓縮圖片,否則圖片還沒加載完就壓縮,結果圖片是全黑的
let canvas = document.createElement('canvas'), //創建一個canvas元素
context = canvas.getContext('2d'), //context相當于畫筆,里面有各種可以進行繪圖的API
originWidth = image.width,/* 圖片的寬度 */
originHeight = image.height, /* 圖片的高度 */
data = ''; //存盤壓縮后的圖片
// 設定最大尺寸限制,將所有圖片都壓縮到小于1m
const maxWidth = 1024, maxHeight = 1024;
// 需要壓縮的目標尺寸
let targetWidth = originWidth, targetHeight = originHeight;
// 等比例計算超過最大限制時縮放后的圖片尺寸
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > 1) {
// 寬圖片
targetWidth = maxWidth;
targetHeight = Math.round(maxWidth * (originHeight / originWidth));
} else {
// 高圖片
targetHeight = maxHeight;
targetWidth = Math.round(maxHeight * (originWidth / originHeight));
}
}
canvas.width = targetWidth; //設定繪圖的寬度
canvas.height = targetHeight; //設定繪圖的高度
//使用drawImage重新設定img標簽中的圖片大小,實作壓縮,drawImage方法的引數可以自行查閱W3C
context.drawImage(image, 0, 0, targetWidth, targetHeight);
//使用toDataURL將canvas上的圖片轉換為base64格式
data = canvas.toDataURL('image/jpg');
$('#hiden_one').addClass('layui-hide');//隱藏區域中的icon和文字
$('#uploadDemoView').removeClass('layui-hide'); //打開隱藏的image標簽
document.getElementById('img_one').src = data;//將壓縮后的圖片顯示到頁面上的img標簽
//將base64轉為blob檔案物件
BlobDealImg = convertBase64UrlToBlob(data);
// console.log(BlobDealImg);
//上傳檔案攜帶引數問題解決
var formData = new FormData();//這里需要實體化一個FormData來進行檔案上傳
formData.append("file", BlobDealImg, "file_" + Date.parse(new Date()) + ".jpg");//檔案
formData.append("data2", "12345");//引數1
formData.append("data1", "023");
//做到這一步前端的所有代碼就已經寫完了,接下來只需要后端接收即可
/* $.ajax({
url: '', //改成您自己的上傳介面
data: formData,
type: "post",
processData: false,//不需要將傳輸的資料序列化,必須這么寫
contentType: false,
// dataType: "json",
success: function (res) {
},
});*/
}
};
/*將base64轉為blob檔案物件,再上傳*/
function convertBase64UrlToBlob(urlData) {
var arr = urlData.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>
</body>
</html>
運行界面如下:


轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/262935.html
標籤:其他
上一篇:window.location.reload(); 不重繪當前頁面問題
下一篇:方塊和圓形跳動正在加載中
