小猿圈web前端之移动端Vue+Vant实现上传压缩旋转图片功能
小猿圈web前端讲师为了大家更好的学习前端知识决定每天分享一个web前端案例,希望对你与学习前端的你有所帮助,今天分享的是移动端Vue+Vant的Uploader实现上传、压缩、旋转图片等功能的详细介绍。
面向百度开发
html
<van-uploader :after-read="onRead" accept="image/*">
<img src="./icon_input_add.png" />
</van-uploader>
js
data() {
return {
files: {
name: "",
type: ""
},
headerImage: null,
picValue: null,
upImgUrl,
}
},
// 组件方法 获取 流
async onRead(file) {
// console.log(file);
// console.log(file.file);
this.files.name = file.file.name; // 获取文件名
this.files.type = file.file.type; // 获取类型
this.picValue = file.file; // 文件流
this.imgPreview(this.picValue);
},
// 处理图片
imgPreview(file) {
let self = this;
let Orientation;
//去获取拍照时的信息,解决拍出来的照片旋转问题
Exif.getData(file, function () {
Orientation = Exif.getTag(this, "Orientation");
});
// 看支持不支持FileReader
if (!file || !window.FileReader) return;
if (/^image/.test(file.type)) {
// 创建一个reader
let reader = new FileReader();
// 将图片2将转成 base64 格式
reader.readAsDataURL(file);
// 读取成功后的回调
reader.onloadend = function () {
// console.log(this.result);
let result = this.result;
let img = new Image();
img.src = result;
//判断图片是否大于500K,是就直接上传,反之压缩图片
if (this.result.length <= 500 * 1024) {
self.headerImage = this.result;
self.postImg();
} else {
img.onload = function () {
let data = self.compress(img, Orientation);
self.headerImage = data;
self.postImg();
};
}
};
}
},
// 压缩图片
compress(img, Orientation) {
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
//瓦片canvas
let tCanvas = document.createElement("canvas");
let tctx = tCanvas.getContext("2d");
// let initSize = img.src.length;
let width = img.width;
let height = img.height;
//如果图片大于四百万像素,计算压缩比并将大小压至400万以下
let ratio;
if ((ratio = (width * height) / 4000000) > 1) {
// console.log("大于400万像素");
ratio = Math.sqrt(ratio);
width /= ratio;
height /= ratio;
} else {
ratio = 1;
}
canvas.width = width;
canvas.height = height;
// 铺底色
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
//如果图片像素大于100万则使用瓦片绘制
let count;
if ((count = (width * height) / 1000000) > 1) {
// console.log("超过100W像素");
count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片
// 计算每块瓦片的宽和高
let nw = ~~(width / count);
let nh = ~~(height / count);
tCanvas.width = nw;
tCanvas.height = nh;
for (let i = 0; i < count; i++) {
for (let j = 0; j < count; j++) {
tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
}
}
} else {
ctx.drawImage(img, 0, 0, width, height);
}
//修复ios上传图片的时候 被旋转的问题
if (Orientation != "" && Orientation != 1) {
switch (Orientation) {
case 6: //需要顺时针(向左)90度旋转
this.rotateImg(img, "left", canvas);
break;
case 8: //需要逆时针(向右)90度旋转
this.rotateImg(img, "right", canvas);
break;
case 3: //需要180度旋转
this.rotateImg(img, "right", canvas); //转两次
this.rotateImg(img, "right", canvas);
break;
}
}
//进行最小压缩
let ndata = canvas.toDataURL("image/jpeg", 0.1);
tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
return ndata;
},
// 旋转图片
rotateImg(img, direction, canvas) {
//最小与最大旋转方向,图片旋转4次后回到原方向
const min_step = 0;
const max_step = 3;
if (img == null) return;
//img的高度和宽度不能在img元素隐藏后获取,否则会出错
let height = img.height;
let width = img.width;
let step = 2;
if (step == null) {
step = min_step;
}
if (direction == "right") {
step++;
//旋转到原位置,即超过最大值
step > max_step && (step = min_step);
} else {
step--;
step < min_step && (step = max_step);
}
//旋转角度以弧度值为参数
let degree = (step * 90 * Math.PI) / 180;
let ctx = canvas.getContext("2d");
switch (step) {
case 0:
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0);
break;
case 1:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, 0, -height);
break;
case 2:
canvas.width = width;
canvas.height = height;
ctx.rotate(degree);
ctx.drawImage(img, -width, -height);
break;
case 3:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, -width, 0);
break;
}
},
//将base64转换为文件
dataURLtoFile(dataurl) {
var arr = dataurl.split(","),
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], this.files.name, {
type: this.files.type
});
},
//这里写接口
async postImg() {
let file = this.dataURLtoFile(this.headerImage);
let formData = new window.FormData();
formData.append("file", file);
toast_loding(this, "图片上传中···");
try {
let res = await util.ajax.post(this.upImgUrl, formData, {
headers: {
"Content-Type": "multipart/form-data"
}
});
} catch (e) {
console.log(e);
}
}
以上就是小猿圈web前端讲师给大家分享的移动端Vue+Vant的Uploader实现上传、压缩、旋转图片等功能的详细介绍,希望对你有所帮助web前端自学②群:738735873,想要了解更多内容的小伙伴可以到小猿圈官网进行学习,里面有最新最全面的课程内容等你来学习,而且小猿圈上所有的视频都是免费的学习的。
转载于:https://juejin.im/post/5cfe24cce51d4556bb4cd35f
小猿圈web前端之移动端Vue+Vant实现上传压缩旋转图片功能相关推荐
- 小猿圈Web前端开发学习路线
很多人已经下定决心学习前端开发,但是学习很盲目,没有一个明确的目标,导致学了很长时间效果也没有很明显,最终放弃了,这个结果是我们最不想看到的结果,那么学习路线就十分重要了,好的学习路线对学习会引向成功 ...
- web前端三大主流框架_小猿圈web前端之前端的主流框架都有哪些?
社会在不断发展,互联网更新换代也是飞速,web框架也是经历一代又一代的革新,那么当今时代什么框架是前端的主流框架呢?小猿圈web前端讲师查了一些资料,整理出当今时代比较流行的三种框架,下面说一下这三种 ...
- 前端 input怎么显示null_小猿圈WEB前端之HTML5+CSS3面试题(一)
学习是一件非常充实的过程,特别是把自己的乐趣变成工作的时候,很多朋友就喜欢学习web前端,所以学习前端,也希望从事前端的工作,但是因为缺少实战经验,所以很多都是卡在面试这关上,下面小猿圈总结了web前 ...
- ajax中async_小猿圈web前端之ajax的同步和异步有怎样的区别?
对于ajax我们应该知道ajax是主要用来在前端页面中向服务器后端请求数据,ajax中根据async的值不同分为同步(async = false)和异步(async = true)两种执行方式,那么, ...
- 小猿圈WEB前端之HTML5+CSS3面试题(一)
越来越多人喜欢前端岗位,毕业季已经悄然来临,很多毕业生面临找工作,那你们在狂欢快乐最后恋恋不舍之际,是否想着过几天招工作的危机.如果想要毕业之后,走向前端的岗位,那看到小编的文章后好好做一下这套题,今 ...
- vue 传参 微信_小猿圈web前端之微信小程序页面间跳转传参方式总结
原标题:小猿圈web前端之微信小程序页面间跳转传参方式总结 最近小程序发展的越来越快,很多大公司也在打造自己的小程序平台以及购物小程序等等,今天小猿圈web前端讲师就总结了关于微信小程序的知识点,首先 ...
- 小猿圈web前端之jQuery抽奖系统
你有没有想过有一天可以成为千万富翁呢?你是通过自己的努力和奋斗还是其他手段获得的呢?前端程序员是通过jQuery获得的,他自己写了一个抽奖系统,下面就小猿圈前端讲师分享给大家. 效果图: <!D ...
- 小猿圈web前端简述canvas如何实现二维码和图片合成
你经常看到活动海报什么的,上都是有各种宣传文案以及二维码形成的,你知道怎么用canvas实现二维码和图片合成,下面小猿圈Linux讲师为你详细介绍一下canvas如何实现二维码和图片合成的. 使用ur ...
- th:text为null报错_小猿圈web前端之vue-cli项目打包完成后运行文件路径报错问题
学习前端的小伙伴越来越多,问题也就越多,前面基础部分还好一些,特别是一到框架的时候,难住了一大部分人,今天小猿圈web前端讲师就为大家总结了vue-cli项目打包完成后运行文件路径报错问题,有兴趣的小 ...
最新文章
- 腾讯 Web UI 解决方案 QMUI Web —— 探索与沉淀
- boost::depth_first_search用法的测试程序
- 使用 pyenv 管理 Python 版本
- 使用纯css做的按钮
- jquery实现多级下拉菜单
- vue 子组件 调用、触发父组件中的方法
- python 屏幕输入 读取两行_一节课带你掌握Python的输入输出
- php背景色如何填充满,php - 按一定百分比覆盖背景颜色
- UIActivityIndicatorView创建的菊花隐藏不掉问题
- 有什么软件测试固态硬盘,多个专业软件评测中端固态硬盘
- git php框架,如何用Git安装TP框架
- 快速批量执行redis命令
- 74HC595使用方法
- 使用LIME解释CNN
- 推荐14个可以展示你代码的网站
- 如何将多个excel表格合并成一个_怎么将多个pdf文件合并成一个?
- python矩阵点乘和叉乘_NumPy点积:取向量积的乘积(而不是求和)
- matlab升幂降幂排列,升幂排列与降幂排列
- c语言switch怎么画流程图,请各位大神帮个忙,画个NS流程图,,急!!!
- 不使用循环,求二进制中1的个数
热门文章
- 又见yx — 说说IT公司的团队头儿
- c语言程序改错类型,C语言程序改错总结
- linux分区合并不损坏系统,一次Linux磁盘损坏导致系统不可用恢复实例
- vuepdf转换html,Vue网页html转换PDF(最低兼容ie10)的思路详解
- linux审计原理,Linux安全审计机制模块实现分析(1)
- html图片加波浪滤镜,CSS滤镜wave属性(波形滤镜)
- 第十六届全国大学智能车竞赛华南赛区成绩汇总
- Arduino处理STM32中的多个串口通讯问题
- 配置腾讯云服务器-2021-3-27
- 看到这儿,你就不会再轻易相信自己的眼睛