因为最近遇到个移动端上传头像的需求,上传到后台的数据是base64位,其中为了提高用户体验,把比较大的图片用canvas进行压缩之后再进行上传。在移动端调用拍照功能时,会发生图片旋转,为了解决这个问题引入了exif去判断拍照时的信息再去处理图片,这是个很好的插件。关于exif.js可以去他的GitHub上了解,这边直接npm install exif-js --save   安装,然后import一下就可以使用了。以下就是源码,可以直接使用。

[html] view plaincopy
  1. <template>
  2. <div>
  3. <div style="padding:20px;">
  4. <div class="show">
  5. <div class="picture" :style="'backgroundImage:url('+headerImage+')'"></div>
  6. </div>
  7. <div style="margin-top:20px;">
  8. <input type="file" id="upload" accept="image" @change="upload">
  9. <label for="upload"></label>
  10. </div>
  11. </div>
  12. </div>
  13. </template>
  14. <script>
  15. import Exif from 'exif-js'
  16. export default {
  17. data () {
  18. return {
  19. headerImage:'',picValue:''
  20. }
  21. },
  22. mounted () {
  23. },
  24. methods: {
  25. upload (e) {
  26. let files = e.target.files || e.dataTransfer.files;
  27. if (!files.length) return;
  28. this.picValue = files[0];
  29. this.imgPreview(this.picValue);
  30. },
  31. imgPreview (file) {
  32. let self = this;
  33. let Orientation;
  34. //去获取拍照时的信息,解决拍出来的照片旋转问题
  35. Exif.getData(file, function(){
  36. Orientation = Exif.getTag(this, 'Orientation');
  37. });
  38. // 看支持不支持FileReader
  39. if (!file || !window.FileReader) return;
  40. if (/^image/.test(file.type)) {
  41. // 创建一个reader
  42. let reader = new FileReader();
  43. // 将图片2将转成 base64 格式
  44. reader.readAsDataURL(file);
  45. // 读取成功后的回调
  46. reader.onloadend = function () {
  47. let result = this.result;
  48. let img = new Image();
  49. img.src = result;
  50. //判断图片是否大于100K,是就直接上传,反之压缩图片
  51. if (this.result.length <= (100 * 1024)) {
  52. self.headerImage = this.result;
  53. self.postImg();
  54. }else {
  55. img.onload = function () {
  56. let data = self.compress(img,Orientation);
  57. self.headerImage = data;
  58. self.postImg();
  59. }
  60. }
  61. }
  62. }
  63. },
  64. postImg () {
  65. //这里写接口
  66. },
  67. rotateImg (img, direction,canvas) {
  68. //最小与最大旋转方向,图片旋转4次后回到原方向
  69. const min_step = 0;
  70. const max_step = 3;
  71. if (img == null)return;
  72. //img的高度和宽度不能在img元素隐藏后获取,否则会出错
  73. let height = img.height;
  74. let width = img.width;
  75. let step = 2;
  76. if (step == null) {
  77. step = min_step;
  78. }
  79. if (direction == 'right') {
  80. step++;
  81. //旋转到原位置,即超过最大值
  82. step > max_step && (step = min_step);
  83. } else {
  84. step--;
  85. step < min_step && (step = max_step);
  86. }
  87. //旋转角度以弧度值为参数
  88. let degree = step * 90 * Math.PI / 180;
  89. let ctx = canvas.getContext('2d');
  90. switch (step) {
  91. case 0:
  92. canvas.width = width;
  93. canvas.height = height;
  94. ctx.drawImage(img, 0, 0);
  95. break;
  96. case 1:
  97. canvas.width = height;
  98. canvas.height = width;
  99. ctx.rotate(degree);
  100. ctx.drawImage(img, 0, -height);
  101. break;
  102. case 2:
  103. canvas.width = width;
  104. canvas.height = height;
  105. ctx.rotate(degree);
  106. ctx.drawImage(img, -width, -height);
  107. break;
  108. case 3:
  109. canvas.width = height;
  110. canvas.height = width;
  111. ctx.rotate(degree);
  112. ctx.drawImage(img, -width, 0);
  113. break;
  114. }
  115. },
  116. compress(img,Orientation) {
  117. let canvas = document.createElement("canvas");
  118. let ctx = canvas.getContext('2d');
  119. //瓦片canvas
  120. let tCanvas = document.createElement("canvas");
  121. let tctx = tCanvas.getContext("2d");
  122. let initSize = img.src.length;
  123. let width = img.width;
  124. let height = img.height;
  125. //如果图片大于四百万像素,计算压缩比并将大小压至400万以下
  126. let ratio;
  127. if ((ratio = width * height / 4000000) > 1) {
  128. console.log("大于400万像素")
  129. ratio = Math.sqrt(ratio);
  130. width /= ratio;
  131. height /= ratio;
  132. } else {
  133. ratio = 1;
  134. }
  135. canvas.width = width;
  136. canvas.height = height;
  137. //        铺底色
  138. ctx.fillStyle = "#fff";
  139. ctx.fillRect(0, 0, canvas.width, canvas.height);
  140. //如果图片像素大于100万则使用瓦片绘制
  141. let count;
  142. if ((count = width * height / 1000000) > 1) {
  143. console.log("超过100W像素");
  144. count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片
  145. //            计算每块瓦片的宽和高
  146. let nw = ~~(width / count);
  147. let nh = ~~(height / count);
  148. tCanvas.width = nw;
  149. tCanvas.height = nh;
  150. for (let i = 0; i < count; i++) {
  151. for (let j = 0; j < count; j++) {
  152. tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
  153. ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
  154. }
  155. }
  156. } else {
  157. ctx.drawImage(img, 0, 0, width, height);
  158. }
  159. //修复ios上传图片的时候 被旋转的问题
  160. if(Orientation != "" && Orientation != 1){
  161. switch(Orientation){
  162. case 6://需要顺时针(向左)90度旋转
  163. this.rotateImg(img,'left',canvas);
  164. break;
  165. case 8://需要逆时针(向右)90度旋转
  166. this.rotateImg(img,'right',canvas);
  167. break;
  168. case 3://需要180度旋转
  169. this.rotateImg(img,'right',canvas);//转两次
  170. this.rotateImg(img,'right',canvas);
  171. break;
  172. }
  173. }
  174. //进行最小压缩
  175. let ndata = canvas.toDataURL('image/jpeg', 0.1);
  176. console.log('压缩前:' + initSize);
  177. console.log('压缩后:' + ndata.length);
  178. console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%");
  179. tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
  180. return ndata;
  181. },
  182. }
  183. }
  184. </script>
  185. <style>
  186. *{
  187. margin: 0;
  188. padding: 0;
  189. }
  190. .show {
  191. width: 100px;
  192. height: 100px;
  193. overflow: hidden;
  194. position: relative;
  195. border-radius: 50%;
  196. border: 1px solid #d5d5d5;
  197. }
  198. .picture {
  199. width: 100%;
  200. height: 100%;
  201. overflow: hidden;
  202. background-position: center center;
  203. background-repeat: no-repeat;
  204. background-size: cover;
  205. }
  206. </style>

vue开发:移动端图片上传相关推荐

  1. vue移动端图片上传

    一.服务端环境准备 本文服务端主要为nodejs,利用multer中间件完成图片上传功能.服务端安装express框架和multer. npm install express --save npm i ...

  2. 详细阐述Web开发中的图片上传问题

    Web开发中,图片上传是一种极其常见的功能.但是呢,每次做上传,都花费了不少时间. 一个"小功能"花费我这么多时间,真心不愉快. So,要得认真分析下原因. 1.在最初学习Java ...

  3. 移动端图片上传裁切(版权归秒为所有,仅为搬运)

    <!DOCTYPE html> <html lang="en"> <head> <meta name="viewport&quo ...

  4. 移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传

    现在科技太发达,移动设备像素越来越高,随便一张照片2M+,但是要做移动端图片上传和pc上略有不同,移动端你不能去限制图片大小,让用户先处理图片再上传,这样不现实.所以理解的解决方案就是在上传先进行图片 ...

  5. element显示服务器的图片,Vue+ElementUI+SpringMVC实现图片上传和回显

    Vue+ElementUI+SpringMVC实现图片上传和table回显 而我们也常遇到表单中包含图片上传的需求,并且需要在table中显示图片,所以这里我就讲一下结合后端的SpringMVC框架如 ...

  6. Vue+ElementUI+SpringMVC实现图片上传和回显

    Vue+ElementUI+SpringMVC实现图片上传和table回显 在之前我们已经讲过了 Vue+ElementUI+SpringMVC实现分页 . 而我们也常遇到表单中包含图片上传的需求,并 ...

  7. 移动端图片上传后进行压缩功能

    移动端图片上传后进行压缩功能 在进行讲解上传图片压缩之前,我们先来了解下HTML5中的文件上传的基本知识点. 一: FileList对象与file对象. FileList对象表示用户选择的文件列表.在 ...

  8. php 图片压缩旋转,移动端图片上传旋转、压缩问题的解决方案

    本篇文章就给大家带来移动端图片上传旋转.压缩问题的解决方案.有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助. 前言 在手机上通过网页 input 标签拍照上传图片,有一些手机会出现图片 ...

  9. JavaScript移动端图片上传方法

    移动端图片上传方法 实现效果 文件下载 http://files.cnblogs.com/files/sntetwt/%E7%A7%BB%E5%8A%A8%E7%AB%AF%E5%9B%BE%E7%8 ...

  10. 使用vue+elementUi+springBoot实现图片上传,图片删除,图片展示

    使用vue+elementUi+springBoot实现图片上传,图片删除,图片展示 环境配置 准备环境 使用软件 图片上传 图片删除 图片显示 所有代码均为参考,每个人的方法不一样,效果不一样,该代 ...

最新文章

  1. java性能调优03
  2. Celt Codec简单使用方法
  3. 经典C语言程序100例之七
  4. “做好大数据测试,我是认真的!”
  5. Moss 2007 入门(1) - 功能概述【转】
  6. 深入理解 switch....case 中的case
  7. 优先队列的优先级设置法
  8. web项目导出excel表格
  9. [RK3399][Android7.1] 移植笔记 --- 音频Codec RT5640添加
  10. P问题、NP问题、NPC问题、NPC-hard问题
  11. excel2007不显示文件名
  12. Object.defineProperty是Es5中无法shim的特性 shim是什么?
  13. 如何优雅的整合定时批量任务(荣耀典藏版)
  14. bandgap中简并点理解与仿真
  15. Effie:沉浸写作,创造价值
  16. java tooltip_案例-Swing使用ToolTip
  17. NOI2017银色记
  18. 海南考研二战心得体会
  19. 女孩上中专学财经类号还是计算机好,女生学财经类专业好吗
  20. Typora编辑器(蓝奏)

热门文章

  1. 顺序表插入删除查找操作
  2. 技术剖析中国菜刀原理
  3. 戴维宁定理等效电压源
  4. MTBF检测方法及标准
  5. (二)MATLAB数学建模——规划问题
  6. HTML:给自己设计一个简单的专属网页音乐播放器
  7. 2020前端面试题72道总结
  8. 618观察,拼购成新势力,一线城市和下沉市场并重成趋势
  9. 分享五款智能配音软件,声音堪比真人,制作视频更方便
  10. 全球及中国咳嗽和感冒药行业竞争趋势及需求规模预测报告(2022-2027)