minio用来上传图片:
需求:公司需要标注一些大量的图片,压缩包大小在5gb,图片数量在百万级别来说,前端这部分与后端配合选用了minio这一技术,官方API文档链接在这里:https://min.io/
这是对象object的名字
上传流程:
用的技术栈是vue,首先要进行minio的安装
npm install --save minio
然后在你使用的页面中要引入minio,此处的endpoint容易出错,如果使用的时候刚开始报错的话要注意是不是这里出现了问题
let Minio = require('minio')
let stream = require('stream')
//连接minio文件服务器
var minioClient = new Minio.Client({
endPoint: '', //对象存储服务的URL
port: ,//端口号
useSSL: false, //true代表使用HTTPS
accessKey: '', //登陆minio的账户id
secretKey: '', //登陆minio的密码
// partSize: '50M'
});
(1)首先通过input按钮拿到你需要上传的文件
<el-button type="primary" class="btn">上传文件</el-button>
上传的文件类型是压缩包zip,大小在5gb以内
onFileChange () {
const file = this.$refs.file.files[0]
const filePath = window.URL.createObjectURL(file)
// console.log(file)
// 文件的类型与大小应该进行一次判断,如果不满足条件应该弹出信息提示
if (file.type !== "application/x-zip-compressed" && file.size > 5*2^30) {
this.$message.error('上传失败,文件格式或者大小不符合要求')
return
}
this.uploadMinIo(file)
this.$message({
message: '上传文件成功',
type: 'success'
})
},
上述只是对上传的压缩包有个判断筛选过程,接下来要做的是将选中的压缩包给上传给minio,uploadMinIo是封装好的上传函数
//上传文件
uploadMinIo (fileObj) {
let vm = this
// const files = fileObj;
if (fileObj) {
let file = fileObj
//判断是否选择了文件
if (file == undefined) {
//未选择
} else {
//选择
//获取文件类型及大小
const fileName = file.name
// const mineType = file.type
const fileSize = file.size
const a = '/'
//参数
// let metadata = {
// "content-type": image/png,
// "content-length": fileSize
// }
//判断储存桶是否存在
minioClient.bucketExists('annotation', function(err) {
if (err) {
if (err.code == 'NoSuchBucket') return console.log("bucket does not exist.")
return console.log(err)
}
//准备上传
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = function (e) {//读取完成触发,无论成功或失败
const dataurl = e.target.result
//base64转blob
const blob = vm.toBlob(dataurl)
//blob转arrayBuffer
let reader2 = new FileReader()
reader2.readAsArrayBuffer(blob)
reader2.onload = function(ex) {
//定义流
let bufferStream = new stream.PassThrough();
//将buffer写入
bufferStream.end(new Buffer(ex.target.result));
//上传
minioClient.putObject('annotation', `archive${a}${fileName}`, bufferStream, fileSize, function(err, etag) {
if (err == null) {
minioClient.presignedGetObject('annotation', `archive${a}${fileName}`, 24*60*60, function(err) {
if (err) return console.log(err)
})
}
})
}
}
})
}
}
},
//base64转blob
toBlob (base64Data) {
let byteString = base64Data
if (base64Data.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(base64Data.split(',')[1]) // base64 解码
} else {
byteString = unescape(base64Data.split(',')[1])
}
// 获取文件类型
let mimeString = base64Data.split(';')[0].split(":")[1] // mime类型
// ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区
// let arrayBuffer = new ArrayBuffer(byteString.length) // 创建缓冲数组
// let uintArr = new Uint8Array(arrayBuffer) // 创建视图
let uintArr = new Uint8Array(byteString.length) // 创建视图
for (let i = 0; i < byteString.length; i++) {
uintArr[i] = byteString.charCodeAt(i)
}
// 生成blob
const blob = new Blob([uintArr], {
type: mimeString
})
// 使用 Blob 创建一个指向类型化数组的URL, URL.createObjectURL是new Blob文件的方法,可以生成一个普通的url,可以直接使用,比如用在img.src上
return blob
},
前端上传压缩包,由后端负责解压,上传之后,很快就可以在bucket中找到上传之后的结果。
(2)解压过后,前端还需要将上传过后的图片给拽下来,渲染到页面中,因为我要进行渲染,minio获取存储在minio的图片由两个api,刚开始用的是get object,但是这样生成的链接在浏览器中打不开图片,又重新找到另一个API–presignedGetObject,这个API生成的链接是可以渲染在页面中的。
后端这块在解压的时候会将图片的信息进行记录,需要使用的时候可以通过接口拿到图片的详细信息,然后根据这些信息经图片渲染回来
annotationStart(this.task_id).then((res)=> {
this.message = res.data
this.work_id = res.data.id
let key = res.data.data.Key
minioClient.presignedGetObject('annotation', `${key}`, 24*60*60, (err, presignedUrl) => {
this.imageUrl= presignedUrl
this.publish(this.imageUrl)
})
})
annotation是bucket的名字,key是对应object的名字,这个生成的链接文档部分说是有效期是七天。
minio技术我觉得重点是知道bucketname,还有object是什么,对这两点的知识如果很清晰的话,API在使用的时候就游刃有余了。@TOC
版权声明:本文为m0_52518047原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。