前端上传图片和下载
-
通过后端接口上传图片
上传 file 对象给接口
<input type="file" ref="fileinput" name="fileContent" @input="getinfo($event)" style="display:none">
<img src="" ref="imagesss" class="showimgs" />
getinfo(el){
if( this.$refs.fileinput.files.length > 0 ){
var file = this.$refs.fileinput.files[0] // 这个就是上传到接口的file对象
var fileReader = new FileReader() // FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
fileReader.readAsDataURL(file) //将file对象读取为一段以 data: 开头的字符串,可以直接赋值给 img的src
fileReader.onload = ()=> {
if (/^image/.test(file.type)) {
// 读取结果在fileReader.result里面
this.$refs.imagesss.src = fileReader.result //将读取的图片展示
}
}
if( (5*1024*1024) >= file.size ) { //判断图片大小
this.icon = file
} else {
this.$Message.warning('上传的图片不能大于 5M')
}
}
},
-
直接上传到对象存储(oss)
通过对接oss,直接上传图片到oss,不过有安全性问题。
<uploadimg :list.sync="list" :uploadpic="uploadpic" :violist.sync="violist" :VPflag="VPflag" :limit="limitpic" :xzflag="xzflag" :num="num" class="upload-img" />
<template>
<div id="uploadimg">
<el-upload
action="''"
list-type="picture-card"
:http-request="uploadpic"
:before-upload="beforeAvatarUpload"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:file-list="showlist"
>
<i class="el-icon-plus"><div style="font-size:12px;margin-top: 3px;">上传图片</div></i>
</el-upload>
<el-image-viewer v-if="showViewer" :on-close="closeViewer" :url-list="picList" />
</div>
</template>
<script>
//element-ui upload修改预览功能,需安装element-ui
//说明:
// uploadpic:父组件传入upload方法
// list:父组件传入图片列表
// limit:父组件传入图片大小限制
import ElImageViewer from 'element-ui/packages/image/src/image-viewer' //查看图片
export default {
name: 'uploadimg',
components: { ElImageViewer },
props: ['list','uploadpic','limit','num','xzflag'],
data() {
return {
showViewer: false,
showlist: [],
picList: [],
}
},
created() {
this.getimgdata()
},
methods: {
//获取图片列表
getimgdata() {
this.showlist = this.list
for(let i in this.showlist) {
this.picList.push(this.showlist[i].url)
}
},
//点击预览图片
handlePictureCardPreview(file) {
this.showViewer = true
let i = 0
for(i=0;i<this.showlist.length;i++) {
if(this.picList[i] == file.url)
break
}
for(let j=0;j<i;j++) {
this.picList.push(this.picList[j])
}
this.picList.splice(0,i)
},
//删除上传图片
handleRemove(file, fileList) {
this.$emit('update:list',fileList)
this.showlist = fileList
this.picList = []
for(let i in this.showlist) {
this.picList.push(this.showlist[i].url)
}
},
//关闭预览图片
closeViewer() {
this.showViewer = false
},
beforeAvatarUpload(file) {
let isLt = file.size / 1024 / 1024 < this.limit
if (!isLt) {
this.$message.error('上传图片大小不能超过'+this.limit+'MB!')
}
return isLt
},
},
watch: {
//监听父组件图片列表的变化
list(val) {
this.showlist = val
this.picList = []
for(let i in this.showlist) {
this.picList.push(this.showlist[i].url)
}
},
num( val,old ){ // 控制图片个数
var el = document.getElementsByClassName('el-upload')[0]
var els = document.getElementsByClassName('el-upload')[1]
var elss = document.getElementsByClassName('el-upload')[2]
var elsss = document.getElementsByClassName('el-upload')[3]
if( val > 8 ){
if( this.xzflag == true){
elss.style.display = 'none'
elsss.style.display = 'none'
} else {
el.style.display = 'none'
els.style.display = 'none'
}
// console.log( el )
} else {
if( this.xzflag == true ){
elss.style.display = 'inline-block'
elsss.style.display = 'inline-block'
} else {
el.style.display = 'inline-block'
els.style.display = 'inline-block'
}
}
}
}
}
</script>
<style scoped>
#uploadimg >>> .el-upload-list--picture-card .el-upload-list__item-status-label {
position: absolute;
right: -17px;
top: -17px;
width: 60px;
height: 60px;
background: none;
background-image: url('../../assets/images/weifabu.png');
background-repeat: no-repeat;
background-size: 60px 60px;
box-shadow: 0 0 1pc 1px rgba(0,0,0,.2);
transform:none;
}
#uploadimg >>> .el-upload-list--picture-card .el-upload-list__item-status-label i{
display: none;
}
</style>
图片上传处理函数
// 处理上传结果并保存到数据库
uploadpic(file) {
// 获取文件后缀
const tmp = file.file.name.split('.');
const extname = tmp.pop();
const imgextList = ['jpg', 'jpeg', 'png', 'gif'];
const vioextList = ['AVI', 'ASF', 'MOV', 'QT','RM','NAVI','DivX','MPEG','DAT','MPG','mp4'];
var isimg = imgextList.includes(extname)
var isvio = vioextList.includes(extname)
// 校验文件类型
if( isimg ) {
this.VPflag = false
}
if( isvio ) {
this.VPflag = true
}
if ( !isimg && !isvio ) {
this.$message.warning(`支持上传 jpg、jpeg、png、gif 格式的图片 或者 AVI、ASF、MOV、QT、RM、NAVI、DivX、MPEG、DAT、MPG、mp4 格式的视频`);
return;
}
var randomName = Array(32)
.fill(null)
.map(() => Math.round(Math.random() * 16).toString(16))
.join('');
// console.log( isimg )
var path
if( isimg ) {
path = `${this.username}/picture/${randomName}-${this.daili.length+1+this.list.length}.${extname}`; //上传图片的地址
}else {
path = `${this.username}/video/${randomName}-${this.daili.length+1+this.list.length}.${extname}`; //上传视频的地址
}
var type
try {
// 使用 multipartUpload 正式上传到 oss
if( isimg ) {
this.listpic.push({"image":path})
type=0
} else {
this.listvio.push({"video":path})
type=1
}
this.dlclient.multipartUpload(path,file.file).then((res)=>{ //使用分片上传
if( res.res.statusCode == 200 ){
let params = {
image_url:path,
type:type,
size:file.file.size
}
shangchuanoss('',SaltEnp(params)).then(res=>{
this.mysqlimg.push(res.data.data)
})
const url = this.dlclient.signatureUrl(path, { //通过 signatureUrl 得到完整的url地址
expires: 3600, // 设置过期时间,默认为1800秒。
method: 'GET' // 设置请求方式为PUT。默认请求方式为GET。
});
if( isimg ) {
this.list.push({url:url})
} else {
this.violist.push({url:url})
}
} else {
this.$Message.error('上传oss失败')
}
});
} catch (error) {
this.$message.error(`${error}`);
}
},
//得到oss 对象
getossinfo(){
var params = {
"source": "web",
"type": "sts",
}
GetstsDevice('',SaltEnp(params)).then(res=>{ //通过后端接口,获取oss所需的参数
if ( res.data.code === 1) {
var info = res.data.data
this.expirationTime = this.formateDate(info.Expiration); //过期时间
//代理的oss
this.dlclient = new OSS({ //获取client对象
accessKeyId:info.AccessKeyId,
accessKeySecret:info.AccessKeySecret,
stsToken:info.SecurityToken,
region: '*******',
bucket: '*******'
});
}
});
}
下载oss对应文件的图片
on: {
click:()=>{
const result = this.client.list({ // 通过client.list,列举想要的文件下的对象,得到promise对象
prefix: `${this.sid}/picture/${params.row.dirname}/`,
delimiter: '/'
});
result.then(res=>{
res.objects.forEach(obj => {
this.downloadFile(obj.name) //调用图片下载函数
// let result = this.client.signatureUrl(`${obj.name}`); //通过 signatureUrl 方法获得完整下载地址
// location.href= result
// console.log( result )
});
})
}
}
// 批量下载oss对象里面的图片,使用 location,只能下载最后一张,原因:图片还未下载完毕,就跳转, 使用onload。
downloadFile(key) {
// console.log(key)
if( key.lastIndexOf('.')!= -1 ){
var imgtype = key.substr(key.lastIndexOf('.')+1,key.length) //判断是什么格式的图片
}
let url = this.client.signatureUrl(key); //获取完整地址
let Img = new Image(), dataURL = '';
// let fileName = key.substring(key.indexOf('_')+1); //文件下载下来的名字
let fileName = key;
Img.src = url;
Img.setAttribute("crossOrigin", 'Anonymous'); // 设置跨域
Img.onload = function () { //要先确保图片完整获取到,这是个异步事件
let canvas = document.createElement("canvas"), //创建canvas元素
width = Img.width, //确保canvas的尺寸和图片一样
height = Img.height;
canvas.width = width;
canvas.height = height;
canvas.getContext("2d").drawImage(Img, 0, 0, width, height); //将图片绘制到canvas中
if( imgtype == 'png' ){
dataURL = canvas.toDataURL('image/png'); //转换图片为对应的dataURL
} else {
dataURL = canvas.toDataURL('image/jpeg'); //转换图片为对应的dataURL
}
let eleLink = document.createElement('a');
eleLink.download = fileName;
eleLink.style.display = 'none';
eleLink.href = dataURL;
document.body.appendChild(eleLink);
eleLink.click();
document.body.removeChild(eleLink);
};
},
- 上传到七牛云
通过对接七牛云,直接上传图片到七牛云,不过也有安全性问题。处理图片函数中,这里控制了图片大小小于4M,如果图片大于4M,使用这个方法会存在问题。 我这里使用了 ‘qiniu-js’ 插件。使用之前需要导入, import * as qiniu from ‘qiniu-js’。 具体参考 七牛云js-sdk文档
<input type="file" ref="fileinputs" name="fileContent" @input="getinfos" style="display:none">
getinfos(){
if( this.$refs.fileinputs.files.length > 0 ){
if( this.detailimgobj.length<5 ){ //控制图片数量
var file = this.$refs.fileinputs.files[0] //这个就是第一种方法中,获取file对象
if( (4*1024*1024) >= file.size ) { //控制图片大小,这里控制了图片大小小于4M,如果图片大于4M,使用这个会有问题
// 图片上传到七牛云上
let config = {
"AK":"M0zHAZqlEfVYZYqanOCaQLvuDYWKgtwtZJpHHiWv",
"SK":"01MUPfns2TtpqqTcz5HVaap-XcYzdtFFGJmBhzJF",
"Bucket":"media"
}
var putExtra = {
fname: "",
params: {},
mimeType:["image/png", "image/jpeg", "image/gif"]
};
var observable = qiniu.upload(file, new Date().getTime() , this.qiniuyuntoken, putExtra, config)
var _this = this
var subscription = observable.subscribe({
next(res){
},
error(err){
this.$Message.error('文件已经存在')
},
complete(res){
var obj = {}
obj.url = '七牛云的基础地址'+res.key //得到图片地址,基础地址拼接上传成功返回的key
_this.detailimgobj.push(obj)
}
})
} else {
this.$Message.warning('上传的图片不能大于 4M')
}
this.$refs.fileinputs.value = '' // 删除图片时,也删除input里面的file对象
} else {
this.$Message.warning('最多选择五张图片')
}
} else {
this.flagshowimg = false
}
}