前端选择本地图片并压缩
项目中需要本地选择文件并压缩,这里在Vue项目下面做了一个简单实现,记录一下
Step1:布局文件
<template>
<div class="box">
<input type="file" id="file" @change="selectFile" accept="image/png,image/jpg,image/jpeg,image/gif" multiple/>
<div class="img-grid">
<div class="img-item" v-for="item in imgList">
<img :src="item.base64">
<span>{{item.name}}</span>
</div>
</div>
</div>
</template>
html
-
input
接受类型为image/png,image/jpg,image/jpeg,image/gif
-
multiple
设置数量不限,监听回调函数为selectFile
-
回显布局为
img-grid
,遍历回显数组imgList
数据显示即可 -
imgList
数组基本字段为base64
和name
,分别存放图片数据和名称
Step2:selectFile实现
- 首先设置压缩尺寸
//压缩后的最大尺寸
var MAX_SIZE = 1024
js
- 获取选择的文件数据
//获取文件列表
var fileInputList = document.getElementById("file").files
js
- 初始化imgList
var that = this
//初始化数据
that.imgList = []
js
- 编写写入数据函数
采用递归形式,保证顺序处理
//递归顺序写入数据
function setImgData(input) {
var index = that.imgList.length
if (input.length > index) {
console.log(fileInputList[index].name, "压缩前:", (fileInputList[index].size / 1024).toFixed(0) + "KB")
var name = fileInputList[index].name
compress(fileInputList[index]).then(res => {
blobToDataUrl(res, base64 => {
console.log(name, "压缩后:", (res.size / 1024).toFixed(0) + "KB")
that.imgList.push({
name,
base64
})
if (input.length > index) {
//递归
setImgData(input)
}
})
})
}
}
js
其中compress:
//压缩
function compress(target) {
return new Promise(resolve => {
if (target.size / 1024 < MAX_SIZE) {
resolve(target);
}
// 压缩到MAX_SIZE KB,这里的MAX_SIZE就是要压缩的大小,可自定义
imageConversion
.compressAccurately(target, MAX_SIZE)
.then(res => {
resolve(res);
});
});
}
js
且blobToDataUrl:
//blob转为base64
function blobToDataUrl(blob, output) {
let reader = new FileReader()
reader.onload = function (evt) {
let base64 = evt.target.result
output(base64)
}
reader.readAsDataURL(blob)
}
js
- 调用写入数据函数
setImgData(fileInputList)
js
- 完整selectFile:
selectFile() {
//压缩后的最大尺寸
var MAX_SIZE = 1024
//获取文件列表
var fileInputList = document.getElementById("file").files
var that = this
//初始化数据
that.imgList = []
//开始写入数据
setImgData(fileInputList)
//递归顺序写入数据
function setImgData(input) {
var index = that.imgList.length
if (input.length > index) {
console.log(fileInputList[index].name, "压缩前:", (fileInputList[index].size / 1024).toFixed(0) + "KB")
var name = fileInputList[index].name
compress(fileInputList[index]).then(res => {
blobToDataUrl(res, base64 => {
console.log(name, "压缩后:", (res.size / 1024).toFixed(0) + "KB")
that.imgList.push({
name,
base64
})
if (input.length > index) {
//递归
setImgData(input)
}
})
})
}
}
//压缩
function compress(target) {
return new Promise(resolve => {
if (target.size / 1024 < MAX_SIZE) {
resolve(target);
}
// 压缩到MAX_SIZE KB,这里的MAX_SIZE就是要压缩的大小,可自定义
imageConversion
.compressAccurately(target, MAX_SIZE)
.then(res => {
resolve(res);
});
});
}
//blob转为base64
function blobToDataUrl(blob, output) {
let reader = new FileReader()
reader.onload = function (evt) {
let base64 = evt.target.result
output(base64)
}
reader.readAsDataURL(blob)
}
}
js
Step3:Style样式
<style scoped>
body {
margin: 0;
padding: 0;
overflow: auto !important;
}
.box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.box input {
margin: 20px;
}
.box .img-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
}
.box .img-grid .img-item {
margin: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.box img {
width: 200px;
height: 120px;
}
.box span {
margin: 5px;
}
</style>
css
完整实现
<template>
<div class="box">
<input type="file" id="file" @change="selectFile" accept="image/png,image/jpg,image/jpeg,image/gif" multiple/>
<div class="img-grid">
<div class="img-item" v-for="item in imgList">
<img :src="item.base64">
<span>{{item.name}}</span>
</div>
</div>
</div>
</template>
<script>
import * as imageConversion from "image-conversion";
export default {
data() {
return {
imgList: []
}
},
methods: {
selectFile() {
//压缩后的最大尺寸
var MAX_SIZE = 1024
//获取文件列表
var fileInputList = document.getElementById("file").files
var that = this
//初始化数据
that.imgList = []
//开始写入数据
setImgData(fileInputList)
//递归顺序写入数据
function setImgData(input) {
var index = that.imgList.length
if (input.length > index) {
console.log(fileInputList[index].name, "压缩前:", (fileInputList[index].size / 1024).toFixed(0) + "KB")
var name = fileInputList[index].name
compress(fileInputList[index]).then(res => {
blobToDataUrl(res, base64 => {
console.log(name, "压缩后:", (res.size / 1024).toFixed(0) + "KB")
that.imgList.push({
name,
base64
})
if (input.length > index) {
//递归
setImgData(input)
}
})
})
}
}
//压缩
function compress(target) {
return new Promise(resolve => {
if (target.size / 1024 < MAX_SIZE) {
resolve(target);
}
// 压缩到MAX_SIZE KB,这里的MAX_SIZE就是要压缩的大小,可自定义
imageConversion
.compressAccurately(target, MAX_SIZE)
.then(res => {
resolve(res);
});
});
}
//blob转为base64
function blobToDataUrl(blob, output) {
let reader = new FileReader()
reader.onload = function (evt) {
let base64 = evt.target.result
output(base64)
}
reader.readAsDataURL(blob)
}
}
}
}
</script>
<style scoped>
body {
margin: 0;
padding: 0;
overflow: auto !important;
}
.box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.box input {
margin: 20px;
}
.box .img-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
}
.box .img-grid .img-item {
margin: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.box img {
width: 200px;
height: 120px;
}
.box span {
margin: 5px;
}
</style>
html