七牛云 vue 压缩上传 预览图片

本文介绍了一个使用Vue.js实现的图片上传组件,该组件能够处理图片的压缩和上传至七牛云存储。文章详细展示了如何使用FileReader API读取图片文件,并通过Canvas进行压缩,最后将压缩后的图片转换为Base64编码并上传。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<template>
    <div>
        <div class="rz-picter">
          <img :src="producImg" class="img-avatar">
          <input type="file" name="avatar" id="uppic" accept="image/gif,image/jpeg,image/jpg,image/png" @change="changeImage" ref="avatarInput" class="uppic">
        </div>
    </div>
</template>

<script>
import { Toast } from 'mint-ui';
export default {
    data() {
        return {
            uploadToken: '',
            producImg: ''
        }
    },
    methods: {
        photoCompress(file,obj,objDiv){
 
            var ready=new FileReader();
            /*开始读取指定的Blob对象或File对象中的内容. 当读取操作完成时,readyState属性的值会成为DONE,如果设置了onloadend事件处理程序,则调用之.同时,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容.*/
            ready.readAsDataURL(file);
            let that = this
            ready.onload=function(){
                var re=this.result;
                that.canvasDataURL(re,obj,objDiv)
            }
        },
        canvasDataURL(path, obj, callback){
            var img = new Image();
            img.src = path;
            img.onload = function(){
                var that = this;
                // 默认按比例压缩
                var w = that.width,
                    h = that.height,
                    scale = w / h;
                w = obj.width || w;
                h = obj.height || (w / scale);
                var quality = 0.7;  // 默认图片质量为0.7
                //生成canvas
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                // 创建属性节点
                var anw = document.createAttribute("width");
                anw.nodeValue = w;
                var anh = document.createAttribute("height");
                anh.nodeValue = h;
                canvas.setAttributeNode(anw);
                canvas.setAttributeNode(anh);
                ctx.drawImage(that, 0, 0, w, h);
                // 图像质量
                if(obj.quality && obj.quality <= 1 && obj.quality > 0){
                    quality = obj.quality;
                }
                // quality值越小,所绘制出的图像越模糊
                var base64 = canvas.toDataURL('image/jpeg', quality);
                // 回调函数返回base64的值
                callback(base64);
            }
        },
        convertBase64UrlToBlob(urlData){
            var arr = urlData.split(','), mime = arr[0].match(/:(.*?);/)[1],
                bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
            while(n--){
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new Blob([u8arr], {type:mime});
        },
        changeImage(e) {
            var file = e.target.files[0]
            let data = new FormData();
            let that = this;
            if(file.size/1024 > 1025){
                this.photoCompress(file,{
                    quality: 0.5
                }, function(base64Codes){
                    //console.log("压缩后:" + base64Codes.length / 1024 + " " + base64Codes);die;
                    file = that.convertBase64UrlToBlob(base64Codes);
                    data.append('token', that.uploadToken);
                    data.append('file', file)
                    that.axios({
                        method: 'post',
                        url: 'http://upload-z2.qiniup.com',
                        data,
                        headers: {
                            'Content-Type': 'multipart/form-data'
                            // 'X-Requested-With': 'XMLHttpRequest'
                        }
                    })
                    .then(res => {
                        that.producImg = 'http://dingdanimage.ibabybaby.com/' + res.data.key
                    })
                    .catch(err => {
                        Toast(err)
                    })
                }
                )} else {
                    data.append('token', that.uploadToken);
                    data.append('file', file)
                    that.axios({
                        method: 'post',
                        url: 'http://upload-z2.qiniup.com',
                        data,
                        headers: {
                            'Content-Type': 'multipart/form-data'
                            // 'X-Requested-With': 'XMLHttpRequest'
                        }
                    })
                    .then(res => {
                        that.producImg = 'http://dingdanimage.ibabybaby.com/' + res.data.key
                    })
                    .catch(err => {
                        Toast(err)
                    })
                }
                // data.append('token', this.uploadToken);     //七牛需要的token,叫后台给,是七牛账号密码等组成的hash
                // data.append('file', file);
        }
    },
    created() {
        this.axios.get('/api/order/uploadToken')
        .then(res => {
            this.uploadToken = res.data.uploadToken
        })
        
    },
}
</script>

<style lang="scss" scoped>
.rz-picter {
    position:absolute;
    .img-avatar {
        width: 100px;
        height: 100px;
    }
    .uppic {
        height: 90px;
        width: 90px;
        margin: 0 auto;
        opacity: 0;
        z-index: 99999;
    }
    .img-avatar {
    position: absolute;
    }
}
</style>

### Vue3 实现图片上传七牛云 #### 准备工作 为了在Vue3项目中实现图片上传七牛云,需先完成如下准备工作: - 注册并登录七牛云账号,创建存储空间。 - 获取Access Key (AK) 和 Secret Key (SK)[^1]。 #### 安装依赖库 安装`qiniu-js` SDK用于处理与七牛云交互的任务。打开命令行工具,在项目根目录下执行以下npm指令来安装所需包: ```bash npm install qiniu-js --save ``` #### 配置Token获取接口 服务器端应提供一个API用来请求上传凭证token。此部分涉及后端开发,通常采用Spring Boot框架构建服务端应用,并通过HTTP GET方法返回临时授权令牌。 #### 前端代码编写 下面展示了一个简单的例子说明如何利用Element Plus组件库中的`<el-upload>`标签配合`axios`发起POST请求向七牛云提交文件数据。 ##### HTML模板结构 ```html <!-- src/components/ImageUploader.vue --> <template> <div class="upload-demo"> <el-upload :action="uploadUrl" :data="uploadData" list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :before-upload="beforeAvatarUpload" multiple> <i class="el-icon-plus"></i> </el-upload> <el-dialog :visible.sync="dialogVisible"> <img width="100%" :src="dialogImageUrl" alt=""> </el-dialog> </div> </template> <script lang="ts"> import { defineComponent, ref } from 'vue'; // Import axios for making HTTP requests. import axios from 'axios'; export default defineComponent({ name: "ImageUploader", setup() { const uploadUrl = ref('http://up-z2.qiniup.com'); // 替换成自己的区域域名 let token = ''; async function fetchQiniuToken(){ try{ const res = await axios.get('/api/qiniu/token'); token = res.data.token; } catch(error){ console.error("Failed to get Qiniu Token", error); } } return { dialogImageUrl: '', dialogVisible: false, disabled: false, handleRemove(file, fileList) {}, handlePictureCardPreview(file) { this.dialogImageUrl = file.url; this.dialogVisible = true; }, beforeAvatarUpload(file) { const isJPGorPNG = ['image/jpeg', 'image/png'].includes(file.type); const isLt2M = file.size / 1024 / 1024 < 2; if (!isJPGorPNG) { ElMessage.error('仅支持 JPG 或 PNG 文件!'); } if (!isLt2M) { ElMessage.error('图片大小不得超过 2MB!'); } fetchQiniuToken(); return isJPGorPNG && isLt2M; }, uploadData: computed(() => ({ key: `${Date.now()}-${Math.random().toString(36).substr(2,8)}-${file.name}`, token: token })), uploadUrl }; } }); </script> ``` 注意上述代码片段里定义了几个重要属性和函数: - `uploadUrl`: 设置为七牛云提供的上传地址; - `fetchQiniuToken()`异步调用以获得有效的上传凭证; - `beforeAvatarUpload()`钩子函数负责验证待上传资源合法性的同时也触发了token的拉取操作; 此外还设置了两个计算属性`key`作为唯一标识符以及携带认证信息的`token`参数传递给表单域内。 #### 后端控制器样例(Spring Boot) 对于Java开发者来说可以参考这段简化版的服务端逻辑来响应来自客户端关于获取上传凭证的需求: ```java @RestController @RequestMapping("/api/qiniu") public class QiNiuController { @Value("${qiniu.accessKey}") private String accessKey; @Value("${qiniu.secretKey}") private String secretKey; @GetMapping("/token") public ResponseEntity<Map<String,Object>> getToken(){ Auth auth = Auth.create(accessKey,secretKey); String bucketName ="your-bucket-name"; long expireSeconds=3600; //设置过期时间 String upToken =auth.uploadToken(bucketName,null,expireSeconds,new PutPolicy(null)); Map<String,Object> resultMap=new HashMap<>(); resultMap.put("code",200); resultMap.put("msg","success"); resultMap.put("token",upToken); return new ResponseEntity<>(resultMap,HttpStatus.OK); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值