记录一下在做一个报修功能的心路历程,需求功能很简单,一个表单提交,表单包含简单的文字字段以及图片

因为使用的是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编码的更多相关文章

  1. js实现图片上传预览功能,使用base64编码来实现

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  2. uniapp小程序图片前端压缩上传

    目录 1,前言 2,实现代码 1,前言 这次项目中做了一个图片上传,要求是大于2MB的就压缩成2MB一下的再上传,我这边利用了uniapp的文件接口,使用canvas做了一个压缩上传的功能,目前已上线 ...

  3. 移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传

    现在科技太发达,移动设备像素越来越高,随便一张照片2M+,但是要做移动端图片上传和pc上略有不同,移动端你不能去限制图片大小,让用户先处理图片再上传,这样不现实.所以理解的解决方案就是在上传先进行图片 ...

  4. js如何展示上传的图片

    前言:本文章主要讲的是上传的图片如何展示在页面上. 一般来说,我们会先将本地图片上传到服务器,上传成功后,由后台返回图片的网络地址再在前端显示.但是,我今天讲的是不通过前面说的过程,而是直接使用js将 ...

  5. TP5+阿里云OSS上传文件第三节,实现淘宝上传商品图片

    **TP5+阿里云OSS上传文件第三节,实现淘宝上传商品图片首先我们来看看淘宝的功能和样式:** 之后看看制作完成的演示:(由于全部功能弄成GIF有点大,限制上传大小好像在1M之内,压缩之后也有1.9 ...

  6. ASP.NET、JAVA跨服务器远程上传文件(图片)的相关解决方案整合

    一.图片提交例: A端--提交图片 protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { string u ...

  7. ASP.NET MVC在服务端把异步上传的图片裁剪成不同尺寸分别保存,并设置上传目录的尺寸限制

    我曾经试过使用JSAjaxFileUploader插件来把文件.照片以异步的方式上传,就像"MVC文件图片ajax上传轻量级解决方案,使用客户端JSAjaxFileUploader插件01- ...

  8. php 上传缩放图片

    有时上传图片时因为图片太大了,不仅占用空间,消耗流量,而且影响浏(图片的尺寸大小不一).下面分享一种等比例不失真缩放图片的方法,这样,不管上传的图片尺有多大,都会自动压缩到我们设置尺寸值的范围之内.经 ...

  9. Django使用cropbox包来上传裁剪图片

    1.使用cropbox包来上传裁剪图片,可见介绍:https://www.jianshu.com/p/6c269f0b48c0I ImgCrop包包括:css--style.css,js--cropb ...

随机推荐

  1. [PHP学习教程 - 网络]002.$_SERVER["SCRIPT_NAME"]、$_SERVER["PHP_SELF"]、$_SERVER["QUERY_STRING"]、$_SERVER["REQUEST_URI"]介绍($_SERVER URL Infomation)

    引言:在使用原生PHP的时候,对于URL路径的切割,如:域名,查询参数等等的提取,通常绝大多数兄弟会忽略$_SERVER中定义的内置常量的关系,这里为大家讲解一下. 常用的URL请求路径$_SERVE ...

  2. Vue拖拽交换数据(非插件)

    HelloWorld.vue 文件 <template> <div class="hello"> <h1>{{ msg }}</h1> ...

  3. C# Winform退出程序的方法介绍

    这篇文章主要介绍了C#中WinForm程序退出方法, 实例总结了技巧退出WinForm程序窗口的各种常用技巧,非常具有实用价值,需要的朋友可以参考下 本文实例总结了C#中WinForm程序退出方法技巧 ...

  4. Java实现 蓝桥杯VIP 算法提高 P0401

    算法提高 P0401 时间限制:1.0s 内存限制:256.0MB 输入一个无符号整数x,输出x的二进制表示中1的个数. 输入: 76584 输出: 7 import java.util.Scanne ...

  5. Java实现 LeetCode 110 平衡二叉树

    110. 平衡二叉树 给定一个二叉树,判断它是否是高度平衡的二叉树. 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1. 示例 1: 给定二叉树 [3,9 ...

  6. Java实现约瑟夫环问题

    约瑟夫环问题起源于一个犹太故事.约瑟夫环问题的大意如下: 罗马人攻占了桥塔帕特,41个人藏在一个山洞中躲过了这场浩劫.这41个人中,包括历史学家Josephus(约瑟夫)和他的一个朋友.剩余的39个人 ...

  7. java实现第六届蓝桥杯居民集会

    居民集会 蓝桥村的居民都生活在一条公路的边上,公路的长度为L,每户家庭的位置都用这户家庭到公路的起点的距离来计算,第i户家庭距起点的距离为di. 每年,蓝桥村都要举行一次集会.今年,由于村里的人口太多 ...

  8. java实现第七届蓝桥杯寒假作业

    题目6.寒假作业 寒假作业 现在小学的数学题目也不是那么好玩的. 看看这个寒假作业: □ + □ = □ □ - □ = □ □ × □ = □ □ ÷ □ = □ (如果显示不出来,可以参见[图1. ...

  9. java实现第四届蓝桥杯有理数类

    有理数类 题目描述 有理数就是可以表示为两个整数的比值的数字.一般情况下,我们用近似的小数表示.但有些时候,不允许出现误差,必须用两个整数来表示一个有理数. 这时,我们可以建立一个"有理数类 ...

  10. mysql基础之-mysql数据控制语言DCL(七)

    0x01 mysql中的权限分布 mysql中的用户信息都存储在系统数据库mysql的user表中 查询语句:select host,user,password from mysql.user; 创建 ...