需求:图片在客户端上传图片,当图片过大的时候就对图片进行缩小,然后上传到服务器。
配置: windows10 , node.js,multiparty
安装插件multiparty
在node.js下执行命令npm i multiparty(node.js 安装以及环境变量的配置,jdk的安装这里就不一一详述了,请自行百度安装。)
1、普通的上传图片
以表单的形式,提交图片到服务器,这里考虑到android可能无法同时选择多张图片,这里写了个自定义表单,用js代码动态添加input 空间,然后最后submit提交
<form enctype='multipart/form-data' action="/upload2" method="POST">
<button type="button" class="btn btn-success btn_upImg" onClick="addinputFile2()">选择图片</button>
<br>
<div class="inputFiles" align="center" width="50%"></div>
<div id="images" align="center"></div>
<br>
<span class="btn btn-success fileinput-button">
<span>确定</span>
<input type="submit" >
</span>
</form >
点击选择图片,会动态添加input标签,代码如下:
function addinputFile(){
//检查最后一个type="file"有没有选择图片,没有则去使用,不再建新的
var lastObj=$("input[type='file']:last");
if(lastObj.prop('files')){
if(lastObj.prop('files').length==0){
lastObj.click();
}else{
$(".inputFiles").append("<input type='file' name='fileAttach' multiple='multiple' accept='image/*' onChange='xmTanUploadImg(this);' />");
$("input[type='file']:last").click();
}
}else{
//第一个
$(".inputFiles").append("<input type='file' name='fileAttach' multiple='multiple' accept='image/*' onChange='xmTanUploadImg(this);' />");
$("input[type='file']:last").click();
}
}
然后会执行οnchange=xmTanUploadImg,来显示我们所选图片,也是动态的向images 模块添加<img>,然后显示:
function xmTanUploadImg(obj) {
var fl=obj.files.length;
for(var i=0;i<fl;i++){
var file=obj.files[i];
var reader = new FileReader();
//读取文件过程方法
reader.onload = function (e) {
var imgstr='<img src="'+e.target.result+'"/>';
var oimgbox=$("#images");
oimgbox.append(imgstr);
}
reader.readAsDataURL(file);
}
}
点击 确定按钮,就会提交表单 action="/upload2",服务器端的方法:
// 提交表单上传接口
var multiparty = require('multiparty')
var router = express.Router();
var fs = require('fs');
web.post('/upload2',function(req,res){
console.log("开始上传");
//创建处理form表单的对象
var form = new multiparty.Form({
uploadDir: './public/uploadimages'
})//文件上传的路径
//通过form.parse生成服务器文件,注意这里生成的文件名字不是原来的名字,而是编码后的名字,里面的回调包含错误信息,字段信息,文件信息
form.parse(req,function (err,fields,files) {
if(err) {
console.log("上传失败");
throw err ;
console.log(err)}
else{
console.log("上传成功");
// res.send('上传图片成功')
var html = fs.readFileSync('./public/successUpload.html')
//res.write(html);
res.send(html);
// res.send(JSON.stringify(files.pic[0]))
}
})
})
2、压缩所选图片 并上传压缩后base64格式图片,显示base64格式图片
html相对于不是表单的形式,而是选择了一张或者多张后,读取为base64的格式,然后对图像进行判断是否要压缩,压缩完成后上交到服务器。
html端代码
<button type="button" class="btn btn-success btn_upImg" onClick="addinputFile2()">选择图片</button>
<br>
<div class="inputFiles" align="center" width="50%"></div>
<div id="images" align="center"></div>
<button type="button" class="btn btn-success btn_upImg" onClick="myClick()">确定</button>
点击选择图片,读取图片,然后判断是否压缩,若压缩则先压缩,压缩完成后再将压缩的base64数据,动态添加<img>显示出来(缩小base64<img>的src显示),addinputFile2的代码与上面的addinputFile相似,只是οnchange=xmTanUploadImg2的方法修改如下面:
function xmTanUploadImg2(obj) {
var fl=obj.files.length;
for(var i=0;i<fl;i++){
var oFile = obj.files[i],
imgSize = oFile.size;
if(imgSize < 1920){
var reader = new FileReader();
// console.log("小图,不用压缩哦");
reader.onload = function(e) {
var base64Img= e.target.result;
$.ajax({
type: 'POST',
url: '/uploadbase64',
dataType: "json",
data: {
"base64":base64Img
},
success: function(data) {
console.log(data);
},
error: function(error) {
alert(JSON.stringify(error));
}
});
// 显示压缩的图片
//var imgstr = '<img src=""+resizeImgBase64 />'
//var base64Data = resizeImgBase64.replace(/^data:image\/\w+;base64,/, "");
//var imgstr = '<img src="https://img-blog.csdnimg.cn/2022010700234445491.png"+base64Data/>'
var img = new Image();//创建img容器
img.src=base64Img.toString();//给img容器引入base64的图片
var oimgbox=$("#images");
oimgbox.append(img);
}
reader.readAsDataURL(oFile);
} else { // 图片压缩处理
var reader = new FileReader(),
maxWidth = 1920,
maxHeight= 1920,
suffix = oFile.name.substring(oFile.name.lastIndexOf('.') + 1);
if(imgSize > 2 * 1024 * 1024){
maxWidth = 1920;
maxHeight= 1920;
}
console.log("maxWidth",maxWidth);
console.log("maxHeight",maxHeight);
//alert("hello,开始压缩"+imgSize);
reader.onload = function(e) {
var base64Img= e.target.result;
//console.log("-----",base64Img);
//--执行resize。
var _ir=ImageResizer({
resizeMode:"auto",
dataSource:base64Img,
dataSourceType:"base64",
maxWidth:maxWidth, //允许的最大宽度
maxHeight:maxHeight, //允许的最大高度。
onTmpImgGenerate:function(img){
},
success:function(resizeImgBase64,canvas){
console.log("base64",resizeImgBase64);
$.ajax({
type: 'POST',
url: '/uploadbase64',
dataType: "json",
data: {
"base64":resizeImgBase64
},
success: function(data) {
console.log(data);
},
error: function(error) {
//alert(JSON.stringify(error));
}
});
// 显示压缩的图片
//var imgstr = '<img src=""+resizeImgBase64 />'
//var base64Data = resizeImgBase64.replace(/^data:image\/\w+;base64,/, "");
//var imgstr = '<img src="https://img-blog.csdnimg.cn/2022010700234445491.png"+base64Data/>'
var img = new Image();//创建img容器
img.src=resizeImgBase64.toString();//给img容器引入base64的图片
var oimgbox=$("#images");
oimgbox.append(img);
}
});
};
reader.readAsDataURL(oFile);
// alert("hello,压缩成功");
}
}
}
ImageResizer是参考的网上的提供的一个工具类,利用canvas来绘制得到小的base64的图,不过该工具类有个bug,在读取图片宽高的时候经常为0,因为读取宽高是异步的,经常图片没有加载完成,就去读取图片宽高,导致宽高经常读取都为0,这里本人经过修改,在加载完成后读取。
这里点击选择了图片就会自动上传到服务器,在压缩后利用ajax发送post请求,服务器端的接受接口方法为:
// 上传base64 方法接口
var a = 0;
web.use(express.json({limit: '50mb'}));
web.post('/uploadbase64', function(req, res){
a = a + 1;
//console.log("服务端接收到了数据啦");
//接收前台POST过来的base64
var imgData = req.body.base64;
//console.log("服务端接收到了数据啦",imgData);
//过滤data:URL
var base64Data = imgData.replace(/^data:image\/\w+;base64,/, "");
var timestamp = Date.parse(new Date());
var dataBuffer = Buffer.from(base64Data, 'base64');
var name = timestamp.toString()+a+".jpg"
console.log(name);
// 写入的地址
fs.writeFile("./public/uploadimages/"+name, dataBuffer, function(err) {
if(err){
res.send(err);
}else{
// res.send("保存成功!");
//console.log("服务端接收到了数据啦");
}
});
});
至此,当我们在服务器上执行有上端接口的js文件服务,就可以通过网页上传图片了。(初学网站,利用浏览器打开网页 F12来调试)
这里给出完整的demo,欢迎各位老铁下载。
github 的下载地址:https://github.com/hurtnotbad/lammtUploadImage 希望各位老铁不吝给星,小弟拜谢
说明:
将下载的解压出来,执行node lammtUploadImage.js
浏览器输入:http://10.5.11.136:8080/lammyUploadImage.html(第一种提交方式)
http://10.5.11.136:8080/lammyUploadbase64Image.html(第二种有压缩的提交方式)
压缩工具是compress.js,toUpload.js是动态添加<input>、<img>代码和调用压缩算法的方法文件