weui上传多图片,前端压缩,base64编码
记录一下在做一个报修功能的心路历程,需求功能很简单,一个表单提交,表单包含简单的文字字段以及图片
因为使用的是weui框架,前面的话去找weui的表单和图片上传组件,说实话,weui的组件写的还不错,作为一个不太懂前端的渣渣可以拿来开箱即用
主要是不用调那么多的样式问题,直接上代码:
<div class="weui-cell">
<div class="weui-cell__bd">
<div class="weui-uploader">
<div class="weui-uploader__hd">
<p class="weui-uploader__title">图片上传</p>
<!-- <div class="weui-uploader__info">0/2</div>-->
</div>
<div class="weui-uploader__bd">
<ul class="weui-uploader__files" id="uploaderFiles">
<!--<li class="weui-uploader__file" style="background-image:url(/img/upload-btn.png)"></li>
<li class="weui-uploader__file weui-uploader__file_status" style="background-image:url(/img/upload-btn.png)">
<div class="weui-uploader__file-content">
<i class="weui-icon-warn"></i>
</div>
</li>
<li class="weui-uploader__file weui-uploader__file_status" style="background-image:url(/img/upload-btn.png)">
<div class="weui-uploader__file-content">50%</div>
</li>-->
</ul>
<div class="weui-uploader__input-box">
<input id="uploaderInput" class="weui-uploader__input zjxfjs_file" type="file" accept="image/*" multiple="">
</div>
</div>
</div>
</div>
</div>
//文件上传js
var tmpl = '<li class="weui-uploader__file" style="background-image:url(#url#)"></li>',
$gallery = $("#gallery"),
$galleryImg = $("#galleryImg"),
$uploaderInput = $("#uploaderInput"),
$uploaderFiles = $("#uploaderFiles");
$uploaderInput.on("change", function(e) {
var src, url = window.URL || window.webkitURL || window.mozURL,
files = e.target.files;
//这里获取到批量的file
var fileNum =fileArr.length;
for(var i = 0, len = files.length; i < len; ++i) {
var file = files[i];
if(fileNum + i + 1 > 5) {
break;
}
// fileArr.push(file);
if(url) {
src = url.createObjectURL(file);
} else {
src = e.target.result;
}
var reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = function(e) {
var image = new Image() //新建一个img标签(还没嵌入DOM节点)
image.src = e.target.result
image.onload = function () {
var canvas = document.createElement('canvas'),
context = canvas.getContext('2d'),
imageWidth = image.width / 5.5, //压缩后图片的大小
imageHeight = image.height / 5.5;
canvas.width = imageWidth;
canvas.height = imageHeight;
context.drawImage(image, 0, 0, imageWidth, imageHeight); var data = {
base64: canvas.toDataURL('image/jpeg')
}
mui.ajax({
url: "/file/uploadBase64",
type: "POST",
async: false,
cache: false,
processData: false,// 不处理发送的数据
headers: {
'Content-Type': 'application/json'
},
data: JSON.stringify(data),
success: function(res){
console.log(res)
if (res.code==100){
fileArr.push(res.data);
//上传完成,前端页面显示
$uploaderFiles.append($(tmpl.replace('#url#', canvas.toDataURL('image/jpeg'))));
}else {
weui.toast("出错了,请稍后再试", "forbidden");
}
},
error:function () {
weui.toast("出错了,请稍后再试", "forbidden");
}
});
}
}
}
checkPhotoSize();
});
//控制显示5张以内照片
function checkPhotoSize(){
if(fileArr.length>4){
$(".weui-uploader__input-box").hide();
}else{
$(".weui-uploader__input-box").show();
}
}
var index; //第几张图片
$uploaderFiles.on("click", "li", function() {
index = $(this).index();
$galleryImg.attr("style", this.getAttribute("style"));
$gallery.fadeIn(100);
});
$gallery.on("click", function() {
$gallery.fadeOut(100);
});
//删除图片 删除图片的代码也贴出来。
$(".weui-gallery__del").click(function() {
console.log('删除'+index);
$uploaderFiles.find("li").eq(index).remove();
fileArr.splice(index,1);
checkPhotoSize();
});
这里有几个要注意的点
1、要实现多图片上传,对比了几个UI框架,感觉还是weui的样式做的最好看
2、考虑到图片大小问题,一开始我使用的是直接将图片文件以数组的形式post给后台,然后后台使用 MultipartFile 数组接收,但是这导致有个问题,现在的手机拍照的图片都比较大,随便都有个3-5M一张图片,如果直接post给后台,用户体验不好(速度太慢了),同时也占用了服务器太多资源(主要是带宽和存储空间),所以必须前端先压缩后再上传
3、前端压缩目前能想到的是使用第三方工具接口(阿里或者七牛云端接口);前端页面利用canvas,进行base64编码,然后发送给后端,显然用后者会比较合适
最后利用canvas将图片进行base64编码压缩,可以实现到将3-5M的图片图片压缩为100k内,目前实现的是每次上传图片都会保存在服务器上,删除图片的话没法同步删除服务器上的图片,但是这个问题不大,需要修改的话将这个上传服务器的请求搞到点击提交表单的时候再上传图片就好了
最后贴一下后端接收代码:
/**
* 上传图片信息,base64字符串格式
* @param map
* @param model
* @return
*/
@PostMapping(value = "uploadBase64")
@ResponseBody
public Map<String, Object> uploadBase64Image(@RequestBody Map<String, Object> map) throws ParseException, IOException {
Map<String, Object> imageMap = new HashMap<>();
String base64 = map.get("base64").toString();
MultipartFile file = BASE64DecodedMultipartFile.base64ToMultipart(base64);
//获取文件保存路径
String fileSavePath = globalConfService.getByKey(StaticConfigUtil.FILE_SAVE_PATH).getConfValue();
String fileServerPath = globalConfService.getByKey(StaticConfigUtil.FILE_SERVER_PATH).getConfValue();
fileSavePath = fileSavePath + DateUtil.formatDatetime("yyyy-MM-dd");
fileServerPath = fileServerPath + DateUtil.formatDatetime("yyyy-MM-dd");
if (!file.isEmpty()) { String fileName = file.getOriginalFilename();
String ext=fileName.substring(fileName.lastIndexOf(".")+1); String imgName = "/"+UUID.randomUUID()+ "." +ext; InputStream in = null;
OutputStream out = null;
try {
File serverFile = new File(fileSavePath+imgName);
//判断文件父目录是否存在
if(!serverFile.getParentFile().exists()){
serverFile.getParentFile().mkdir();
}
if (!serverFile.exists()) {
serverFile.createNewFile();
}
in = file.getInputStream();
out = new FileOutputStream(serverFile);
byte[] b = new byte[1024];
int len = 0;
while ((len = in.read(b))!=-1) {
out.write(b, 0, len);
}
out.close();
in.close();
String serverPath = fileServerPath + imgName;
return ResultUtil.successJson(serverPath);
} catch (Exception e) {
e.printStackTrace();
return ResultUtil.errorJson(ErrorEnum.E_40001,e.getMessage());
} finally {
if (out != null) {
out.close();
out = null;
}
if (in != null) {
in.close();
in = null;
}
}
} else {
return ResultUtil.errorJson(ErrorEnum.E_90007);
}
}
/**
* base64转MultipartFile文件
*
* @param base64
* @return
*/
public static MultipartFile base64ToMultipart(String base64) {
try {
String[] baseStrs = base64.split(","); BASE64Decoder decoder = new BASE64Decoder();
byte[] b = new byte[0];
b = decoder.decodeBuffer(baseStrs[1]); for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {
b[i] += 256;
}
} return new BASE64DecodedMultipartFile(b, baseStrs[0]);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
weui上传多图片,前端压缩,base64编码的更多相关文章
- js实现图片上传预览功能,使用base64编码来实现
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- uniapp小程序图片前端压缩上传
目录 1,前言 2,实现代码 1,前言 这次项目中做了一个图片上传,要求是大于2MB的就压缩成2MB一下的再上传,我这边利用了uniapp的文件接口,使用canvas做了一个压缩上传的功能,目前已上线 ...
- 移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传
现在科技太发达,移动设备像素越来越高,随便一张照片2M+,但是要做移动端图片上传和pc上略有不同,移动端你不能去限制图片大小,让用户先处理图片再上传,这样不现实.所以理解的解决方案就是在上传先进行图片 ...
- js如何展示上传的图片
前言:本文章主要讲的是上传的图片如何展示在页面上. 一般来说,我们会先将本地图片上传到服务器,上传成功后,由后台返回图片的网络地址再在前端显示.但是,我今天讲的是不通过前面说的过程,而是直接使用js将 ...
- TP5+阿里云OSS上传文件第三节,实现淘宝上传商品图片
**TP5+阿里云OSS上传文件第三节,实现淘宝上传商品图片首先我们来看看淘宝的功能和样式:** 之后看看制作完成的演示:(由于全部功能弄成GIF有点大,限制上传大小好像在1M之内,压缩之后也有1.9 ...
- ASP.NET、JAVA跨服务器远程上传文件(图片)的相关解决方案整合
一.图片提交例: A端--提交图片 protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { string u ...
- ASP.NET MVC在服务端把异步上传的图片裁剪成不同尺寸分别保存,并设置上传目录的尺寸限制
我曾经试过使用JSAjaxFileUploader插件来把文件.照片以异步的方式上传,就像"MVC文件图片ajax上传轻量级解决方案,使用客户端JSAjaxFileUploader插件01- ...
- php 上传缩放图片
有时上传图片时因为图片太大了,不仅占用空间,消耗流量,而且影响浏(图片的尺寸大小不一).下面分享一种等比例不失真缩放图片的方法,这样,不管上传的图片尺有多大,都会自动压缩到我们设置尺寸值的范围之内.经 ...
- Django使用cropbox包来上传裁剪图片
1.使用cropbox包来上传裁剪图片,可见介绍:https://www.jianshu.com/p/6c269f0b48c0I ImgCrop包包括:css--style.css,js--cropb ...
随机推荐
- [Firefox附加组件]0001.入门
Firefox 火狐浏览器,拥有最快.最安全的上网体验,并且火狐拥有超过一万个的 扩展(add-ons),提供各种不同的扩展功能,您可以简单的下载.安装这些扩展以增强您的火狐功能,帮助您更好.更个性化 ...
- MVC案例之通过配置切换底层存储源(面向接口)
1.深入理解面向接口编程: 在类中调用接口的方法,而不必关心具体的实现.这将有利于代码的解耦.使程序有更好的可移植性 和可扩展性 动态修改 Customer 的存储方式:通过修改类路径下的 switc ...
- 正则表达式:匹配单个数字重复n次
匹配单个数字重复n次:(\d)\1{n-1}其中,\d表示一位数字,(\d)表示匹配之后捕获该匹配,并分组并对组进行编号\1表示被捕获的第一个分组{n-1}是因为被捕获的第一个分组已经消耗了一位数字, ...
- Javascript函数闭包详解(通俗易懂
许多书上闭包过于复杂讲解难懂,自己理解了一下并总结啦~ 讲闭包之前,需要先明白以下几个概念. 总之,函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域. 1.执行上下文(executi ...
- WEB APPLICATION PENETRATION TESTING NOTES
此文转载 XXE VALID USE CASE This is a nonmalicious example of how external entities are used: <?xml v ...
- Java实现 LeetCode 773 滑动谜题(BFS)
773. 滑动谜题 在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示. 一次移动定义为选择 0 与一个相邻的数字(上下左右)进行交换. 最终 ...
- Java实现蓝桥杯日期问题
历届试题 日期问题 时间限制:1.0s 内存限制:256.0MB 提交此题 问题描述 小明正在整理一批历史文献.这些历史文献中出现了很多日期.小明知道这些日期都在1960年1月1日至2059年12月3 ...
- Java实现 LeetCode 481 神奇字符串
481. 神奇字符串 神奇的字符串 S 只包含 '1' 和 '2',并遵守以下规则: 字符串 S 是神奇的,因为串联字符 '1' 和 '2' 的连续出现次数会生成字符串 S 本身. 字符串 S 的前几 ...
- Java实现 蓝桥杯VIP 算法训练 拦截导弹
1260:[例9.4]拦截导弹(Noip1999) 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 4063 通过数: 1477 [题目描述] 某国为了防御敌国的导弹袭击,发展出一 ...
- 第九届蓝桥杯JavaC组省赛真题
解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.哪天返回 题目描述 小明被不明势力劫持.后被扔到x星站再无问津.小明得知每天都有飞船飞往地球,但需要108元的船票,而他却身无分文. ...