vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理
一、前言
三年.net开发转前端已经四个月了,前端主要用webpack+vue,由于后端转过来的,前端不够系统,希望分享下开发心得与园友一起学习。
图片的上传之前都是用的插件(ajaxupload),或者传统上传图片的方式,各有利弊:插件的问题是依赖jq并且会使系统比较臃肿,还有传统的web开发模式 前后端偶尔在一起及对用户体验要求低,现在公司采用webpack+vue+restfullApi开发模式 前后端完全分离,遵从高内聚,低偶尔的原则,开发人员各司其职,一则提升开发效率(从长期来看,短期对于很多开发人员需要有个适应的过程,特别是初中级的前端处理业务逻辑方面的能力比较欠缺),二则提升用户体验。今天分享下在项目开发中写的的图片上传 vue组件。
二、处理问题
这里用h5做图片上传考虑到浏览器支持的问题,这里考虑的场景是在做webapp的时候
1.移动web图片上传还包括拍摄上传,但是在移动端会出现拍摄的照片会旋转,处理这个问题需要得到图片旋转的情况,可以用exif.js来获取,具体可以参看文档
2.图片压缩
3.旋转
三、代码
1组件代码
<template>
<div>
<input type="file" style="display: none;" id="img-upload" multiple accept="image/*" @change="uploadImg($event)"/>
</div>
</template>
<script>
import EXIF from '../../../Resource/Global/Js/exif'
export default{
name:"image-html5-upload",
props:{
imgArr:{
type:Array,
twoWay: true,
default:Array
},
imgNumLimit:{//一次最多可以上传多少张照片
type:Number,
default:4
}
},
methods:{
"uploadImg": function(e){
let tag = e.target;
let fileList = tag.files;
let imgNum = fileList.length;
let _this = this;
_this.imgArr = [];//图片数据清零
if(this.imgArr.length + imgNum > this.imgNumLimit){
alert('一次最多上传'+this.imgNumLimit+'张图片!');
return;
}
var Orientation;
for(let i=0;i<imgNum;i++){
EXIF.getData(fileList[i], function(){
Orientation = EXIF.getTag(fileList[i], 'Orientation');
});
let reader = new FileReader();
reader.readAsDataURL(fileList[i]);
reader.onload = function(){
var oReader = new FileReader();
oReader.onload = function(e) {
var image = new Image();
image.src = e.target.result;
image.onload = function() {
var expectWidth = this.naturalWidth;
var expectHeight = this.naturalHeight;
if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
expectWidth = 800;
expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
} else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
expectHeight = 1200;
expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
}
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = expectWidth;
canvas.height = expectHeight;
ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
var base64 = null;
//修复ios上传图片的时候 被旋转的问题
if(Orientation != "" && Orientation != 1){
switch(Orientation){
case 6://需要顺时针(向左)90度旋转
_this.rotateImg(this,'left',canvas);
break;
case 8://需要逆时针(向右)90度旋转
_this.rotateImg(this,'right',canvas);
break;
case 3://需要180度旋转
_this.rotateImg(this,'right',canvas);//转两次
_this.rotateImg(this,'right',canvas);
break;
}
}
base64 = canvas.toDataURL("image/jpeg", 0.8);
if(fileList[i].size / 1024000 > 1){
_this.imgScale(base64, 4)
}else{
_this.imgArr.push({"src": base64});
}
console.log(JSON.stringify(_this.imgArr));
};
};
oReader.readAsDataURL(fileList[i]);
}
}
},
"imgScale": function(imgUrl,quality){
let img = new Image();
let _this = this;
let canvas = document.createElement('canvas');
let cxt = canvas.getContext('2d');
img.src = imgUrl;
img.onload = function(){
//缩放后图片的宽高
let width = img.naturalWidth/quality;
let height = img.naturalHeight/quality;
canvas.width = width;
canvas.height = height;
cxt.drawImage(this, 0, 0, width, height);
_this.imgArr.push({"src": canvas.toDataURL('image/jpeg')});
}
},
"rotateImg":function (img, direction,canvas) {//图片旋转
var min_step = 0;
var max_step = 3;
if (img == null)return;
var height = img.height;
var width = img.width;
var 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);
}
var degree = step * 90 * Math.PI / 180;
var 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;
}
}
}
}
</script>
2.使用方法
<template>
<div>
<div class="album-img-list">
<ul>
<li v-for="img in imgList"><div class="album-bg-img"><img :src='img.src'> </div></li> </ul>
</div>
<div class="album">
<label for="img-upload">上传照片</label>
<image-html5-upload :img-arr.sync="imgList"></image-html5-upload>
</div>
</div>
</template>
本文版权归作者(谢俊)和博客园所有,欢迎转载,转载请标明出处。
原文地址:http://www.cnblogs.com/net-xiejun/
微信开发群
完整源码下载:https://github.com/xiejun-net/weixin
公众账号:
vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理的更多相关文章
- 分享一个react 图片上传组件 支持OSS 七牛云
react-uplod-img 是一个基于 React antd组件的图片上传组件 支持oss qiniu等服务端自定义获取签名,批量上传, 预览, 删除, 排序等功能 需要 react 版本大于 v ...
- H5 图片上传
1.h5 图片异步上传 (1) 异步上传input触发onchange事件的时候,就把图片上传至服务器.后台可能会返回图片的链接等信息,前台可以把图片信息展示给用户看. (2) 另一种情况可能需要前台 ...
- 浅析H5图片上传
概述 最近需求上需要实现图片上传的功能,简单记录下实现过程.目前实现的功能比较简单,主要有以下几点: 图片预览 图片删除 拖拽上传 压缩上传 移动端实现方案:使用File API 主要使用到 File ...
- h5图片上传预览与拖拽上传
图片上传: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...
- vue移动端图片上传压缩
上传压缩方法 import {api} from '../../api/api.js'; import axios from 'axios'; export function imgPreview ( ...
- HTML5 开发APP(打开相册以及图片上传)
我们开发app,常常会遇到让用户上传文件的功能.比如让用户上传头像.我公司的业务要求是让用户上传支付宝收款二维码,来实现用户提现的功能.想要调用相册要靠HTML Plus来实现.先上效果图 基本功能是 ...
- H5图片上传插件
基于zepto,支持多文件上传,进度和图片预览,用于手机端. (function ($) { $.extend($, { fileUpload: function (options) { var pa ...
- h5图片上传预览
项目中常用到文件上传预览功能,整理一下:如果不想使用 type="file" 的默认样式,可以让其覆盖在一个按钮样式上边,设其透明度为0,或者使用Label关联 html < ...
- h5图片上传简易版(FileReader+FormData+ajax)
一.选择图片(input的file类型) <input type="file" id="inputImg"> 1. input的file类型会渲染为 ...
随机推荐
- sql中文日期格式转换(xxxx年x月x日)
) set @dd='2014年10月1日' select replace(replace( replace(@dd,'日',''),'月','-'),'年','-') 别人的方法 )='2012年1 ...
- 【RabbitMQ】CentOS安装RabbitMQ,及简单的Java客户端连接
在CentOS安装 因Rabbit MQ使用Erlang,所以需要先安装Erlang,安装过程中可能会遇到种种问题,可参考CentOS 6.5安装Erlang/OTP 17.0.然后就可以安装MQ了. ...
- Oracle建表
1.oracle数据库中的多种数据结构: 1.表结构 存储数据 2.视图 一张表或多张表中数据的字节 3.sequence 主要用来生成主键值 4.index 提高检索性能 我们 ...
- react native改变app的图标和名称
beauty\android\app\src\main\res
- 微信小程序-页面链接
navigator 页面链接. 注:navigator-hover默认为{background-color: rgba(0, 0, 0, 0.1); opacity: 0.7;}, <navig ...
- 链表栈的C语言实现
#ifndef _CONST_H_#define _CONST_H_ #include <stdio.h>#include <stdlib.h> typedef enum { ...
- Redis3.20阅读-SDS实现
声明:这是本人参考黄建宏的<redis设计与实现>(源码版本是redis3.0)来学习redis3.20源码的笔记,如果有什么不对的地方,欢迎大家指正,大家一起学习.一起进步,QQ:499 ...
- TFS二次开发系列:六、TFS的版本控制
在TFS中对于版本控制是在WorkSpace工作区来控制的. 首先我们先整理WorkSpace的一些基本使用方法. CheckIn:迁入挂起的操作 CreateMapping:创建一个本地映射地址 D ...
- Latex引用插图格式制定问题(1)
自定义新命令\reffig如下:\newcommand{\reffig}[1]{Figure \ref{#1}}在需要引用图片的时候,用\reffig代替\ref,就可以自动在图号前面输出" ...
- C++备忘录
参考资料: 1. <C++编程思想(第一卷)> 知识点: ● register变量:它是一种局部变量类型.它告诉编译器尽快访问该变量.一般会把变量放在寄存器中,但不保证一定会.不能得到或计 ...