最近在做一个手机端的图片上传,写了一个比较符合自己要求的方法,可供参考
在做这个功能模块时,我遇到了以下问题,都花费了大量时间:
1. 不知道怎么压缩图片,(代码和方法)
2. 得到图片压缩后的base64值,也可以预览,但却传不到后端去
3. 怎么确保我想要压缩的所有图片,大小都相近,图片还尽可能的清晰(如我参考了网上的代码,基本都是按照比例压缩如1/2或1/4,那一个10m的图片压缩完后还有5m或者2.5m,意义不大,那你说比例调大些,按照1/10比例压缩,这样万一我上传的文件只有200k,这样一压缩图片就严重失真了)
4. 将文件发送到后端时携带参数问题
实例代码如下:
<%--
Created by IntelliJ IDEA.
User: ASUS
Date: 2021/2/24
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.11.0.js"></script>
<style type="text/css">
.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;*/
}
</style>
</head>
<body>
<div style="width: 90%;height: 100%;margin: auto;" align="center">
<span>建议传送1M以上的图片进行测试,会有明显的效果,所有的图片都会被压缩在1M以内</span>
<div id="upload_img01" class="up_img_showborder">
<div id="hiden_one">
<svg t="1614166231165" class="icon" viewBox="0 0 1027 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1748" width="60" height="60"><path d="M853.95951925 475.5066105h-310.08967642v-300.83326917c0-13.88461268-13.88461268-32.39742862-32.39742936-32.39742862-18.51281666 0-32.39742862 18.51281666-32.39742861 37.02563333v300.83326844H178.2417157c-18.51281666-4.62820399-37.02563333 13.88461268-37.02563262 32.39742934s18.51281666 32.39742862 32.39742863 32.39742861h300.83326916v300.83326845c4.62820399 18.51281666 18.51281666 37.02563333 37.02563261 37.02563334s32.39742862-18.51281666 32.39742935-32.39742862v-305.46147317h305.46147243c18.51281666 0 32.39742862-18.51281666 32.39742934-32.39742861s-9.25640796-37.02563333-27.76922535-37.02563333z" fill="#bfbfbf" p-id="1749"></path></svg>
<p style="color: gray">点击上传图片</p>
</div>
<div id="uploadDemoView">
<img id="img_one">
</div>
</div>
<div>
<input type="button" onclick="next_btn(this)" value="确认">
</div>
<div>
<input type="file" style="visibility: hidden" accept="image/*" id="btn1">
</div>
</div>
<script type="text/javascript">
$(function () {
$("#uploadDemoView").hide(); //
});
/*点击上传正面图片*/
$(document).on('click', '#upload_img01', function () {
document.getElementById("btn1").click();
});
var BlobDealImg = null;
/*input数据改变时,获取文件数据,上传正面*/
$("#btn1").change(function () {
console.log("压缩前的数据大小(1M=1024*1024):"+this.files[0].size);
let up_ImgBase64 = this.files[0]; //获取文件对象
if (null != up_ImgBase64 && up_ImgBase64 != "") {
alert("图像采集成功!");
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("压缩后的数据大小(1M=1024*1024)="+BlobDealImg.size);
// console.log("转成blob文件后:"+BlobDealImg);
console.log(BlobDealImg);
}, 50);
}
} else {
alert('图像采集失败,请重新采集!');
}
});
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').hide();//隐藏区域中的icon和文字
$('#uploadDemoView').show(); //打开隐藏的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");
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>
创作不易,如果这篇文章能够帮助到你,希望能关注或收藏一下博主,如果文章内容有问题也可留言讨论,我们一起学习,一起进步!!