https://github.com/exif-js/exif-js

http://code.ciaoca.com/javascript/exif-js/demo/

因为最近遇到个移动端上传头像的需求,上传到后台的数据是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>

vue2移动端上传,预览,压缩图片,解决拍照旋转问题相关推荐

  1. java 图片上传 预览 demo_图片上传预览

    [实例简介] 实现图片上传预览,可以增加新的空数组,并上传和替换.还有删除功能:提交的时候,还可以判断是否有空的img [实例截图] [核心代码] 613ddc50-96b8-4197-ba2e-1e ...

  2. Angular6自定义指令实现多图片上传预览

    在做移动端开发多时候经常会遇到用户图片上传的需求,有单图片上传预览的需求,也有多图片上传预览的需求.自己刚遇到这个需求的时候有踩到各种个样到坑.经过多番尝试,下面将本人成功的一个案例分享出来(公司对外 ...

  3. 模拟QQ心情图片上传预览

    出于安全性能的考虑,目前js端不支持获取本地图片进行预览,正好在做一款类似于QQ心情的发布框,找了不少jquery插件,没几个能满足需求,因此自己使用SWFuplad来实现这个图片上传预览. 先粘上以 ...

  4. html 手机qq图片预览,模拟QQ心情图片上传预览示例

    出于安全性能的考虑,目前js端不支持获取本地图片进行预览,正好在做一款类似于QQ心情的发布框,找了不少jquery插件,没几个能满足需求,因此自己使用SWFuplad来实现这个图片上传预览. 先粘上以 ...

  5. vue实战--vue+elementUI实现多文件上传+预览(word/PDF/图片/docx/doc/xlxs/txt)

    需求 最近在做vue2.0+element UI的项目中遇到了一个需求:需求是多个文件上传的同时实现文件的在线预览功能.需求图如下: 看到这个需求的时候,小栗脑袋一炸.并不知道该如何下手,之前的实践项 ...

  6. 图片上传预览的几种方式,了解下?

    图片上传预览场景基本处处可见,朋友圈发动态配图,身份验证及头像更新,莫过如斯. 原由 最近在研究twitter PC网站的时候,在个人中心的主页,设置个人的背景图的时候,发现twitter有个非常好的 ...

  7. php 图片上传预览(转)

    网上找的图片上传预览: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ ...

  8. js实现图片上传预览及进度条

    js实现图片上传预览及进度条 原文js实现图片上传预览及进度条 最近在做图片上传的时候,由于产品设计的比较fashion,上网找了比较久还没有现成的,因此自己做了一个,实现的功能如下: 1:去除浏览器 ...

  9. JAVA实现一个图片上传预览功能

    这个小项目主要使用java实现了一个简单的图片上传预览功能,废话不多说,先上实现成果 ^ _ ^

最新文章

  1. Xilinx基于模型的设计工具—Model Composer
  2. 2021高考成绩一分段查询陕西省,2021年陕西高考一分一段表查询排名方法 成绩排名位次什么时候公布...
  3. 几种常见的CSS布局
  4. JavaScript 渐变效果
  5. centos7 kickstart 使用小结
  6. EMLO模板GeMedia媒体范儿[小梦修改尊享版]
  7. python文本进度条代码解释_python动态文本进度条的实例代码
  8. 【kibana】kibana 7.* 设置中文 汉化
  9. 对listView的理解
  10. java base64字符 转图片_JAVA实现图片与base64字符串之间的转换详解
  11. create session 参数介绍
  12. UI界面视觉设计之字体要素--安卓-ios-网页常用字体
  13. WPF界面样式学习及优化
  14. h5分享到新浪微博 php,h5分享图文链接到微博如何实现
  15. G6 3.1 线条的属性
  16. 亚马逊云科技帮助德比软件轻松应对爆发的增长
  17. vue 给圆遮盖物添加文字 高德地图_【高德地图开发4】---增加覆盖物setMapTextZIndex...
  18. 英语单词记忆的词根总结
  19. IMX6ULL鼠标光标显示到oled
  20. 高中毕业证计算机系,高中毕业证书,急

热门文章

  1. 中国网络安全法对德国公司的影响
  2. 2021-11-16 以太网
  3. 头条竞价php下单系统源码_PHP在线订单系统V8.0竞价单页网站源码 短信提醒+网银支付+支付宝...
  4. html布局(两列布局的常见方式)
  5. 示波器显示读取串口数据
  6. 怎么永久彻底关闭windows 10自动更新
  7. 等参元八节点matlab,平面四边形八节点等参元matlab程序.docx
  8. 深度神经网络(DNN)模型
  9. 树的存储结构一 (一些简单概念)
  10. X004---alteryx for Excel用户