在显示上传完毕的图片的时候遇到了一个问题, 图片莫名其妙被逆时针旋转了90度就很离谱

如下图

经过一番查询, 原来是 IOS 的相机拍照的时候会把方向角写入到图片里面

因为我用的是 element 的上传组件, 所以先去找了找 issue, 果不其然在 Issues #15162有人和我提出了同样的问题, 官方给的回答是 Sorry, we have no plan to support this. 所以只能尝试自己修复了

基础思路就是

  • 获取图片的方向角
  • 将图片在 canvas 画出
  • 旋转到正常位置
  • 导出为 DataURL
  • DataURL 转换为 File 上传

获取旋转角#

这里我们会用到 exif-js 这个库来获取图片的 orientation (方向角), 如果方向角不为 0 , 就需要吧方向角改回 0

先使用 EXIF.getData 解析图片, 然后 EXIF.getTag 拿到 Orientation返回, 为了调用方便都包装成 Promise

import EXIF from 'exif-js'
 
async get_img_orientation(file) {
return new Promise((resolve, j) => {
EXIF.getData(file, function() {
resolve(EXIF.getTag(this, 'Orientation'))
})
})
}

Orientation 对照表#

Orientation 值 旋转角度
1
6 顺时针90°
8 逆时针90°
3 180°

这时候我们进行判断, 如果 Orientation = 6 那么我们就进行下面的调整

调整图片#

由于我们拿到的是 File 没法直接使用, 需要先变成 Image 对象

async file_to_image(file) {
return new Promise((resolve) => {
const reader = new FileReader()
const img = new Image()
reader.onload = (e) => {
img.src = e.target.result
img.onload = function() {
resolve(img)
}
}
reader.readAsDataURL(file)
})
}

下面的代码参考 VUE uses element UI’s upload component when ios uploads image rotation 90 degrees, 有所修改

去除方向角#

原作者这里是把图片旋转了, 这里只画出来去除了方向角

直接在画布上面画出来, 然后导出

remove_orientation(image, width, height) {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.width = width
canvas.height = height
ctx.drawImage(image, 0, 0)
return canvas.toDataURL('image/jpeg')
}

转换为 file#

从base64的DataURL, 去掉标记信息, 后面的数据用 atob 解码, 直接装到 Uint8Array

dataURL_to_file(dataurl, filename) {
const arr = dataurl.split(',')
const mime = arr[0].match(/:(.*?);/)[1]
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
}

这样就拿到了转换好的图片, 如果你喜欢可以 base64 直接上传

结合 Element UI#

如果结合 Element UI 修改 Upload 的话, before-upload 这个函数是不能返回 一个修改后的file的, 所以我们使用 http-request 拦截上传函数来做

先添加一个 :http-request="upload_file"

async upload_file(req) {
let file = req.file
const orient = await this.get_img_orientation(file)
if (orient && orient === 6) {
const img = await this.file_to_image(file)
const data = this.remove_orientation(img, img.width, img.height)
file = this.dataURL_to_file(data, file.name)
}
const payload = new FormData()
payload.append(file.name, file)
const id = await upload_file(payload) // 发送上传请求
this.item.pictures.push(id[0]) // 添加到自己业务里面
}

后~#

= = IOS 上面权限系统好麻烦, Chrome 也调用不了摄像头, 用了 vue-qrcode-reader 扫描二维码 识别率太低了, 要各种摆姿势, 微信上面基本秒扫, 有点考虑用小程序重做这部分了

参考引用#

[1]: VUE uses element UI’s upload component when ios uploads image rotation 90 degrees http://www.programmersought.com/article/6665266668/

原文地址:https://haozi.moe/2020/03/12/%E4%BF%AE%E5%A4%8DIOS%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87%E6%96%B9%E5%90%91%E9%97%AE%E9%A2%98/

IOS上传图片方向问题的更多相关文章

  1. ios上传图片显示方向错误问题

    IOS 上传图片方向显示错误问题 问题描述 在使用苹果手机上传图片的时候,发现传完的图片显示出来方向是错误的,竖着的图片会变成横着显示(少部分安卓手机也存在这个问题) 产生原因 ios 相机加入了方向 ...

  2. IOS上传图片方法类

    IOS上传图片方法类   iPhone开发中遇到上传图片问题,找到多资料,最终封装了一个类,请大家指点,代码如下 // // RequestPostUploadHelper.h // demodes ...

  3. IOS上传图片

    //原文地址http://www.cnblogs.com/skyblue/archive/2013/05/08/3067108.html,因为以后要用到,搬来存下// // RequestPostUp ...

  4. iOS上传图片详解

    iphone中图像通常存储在4个地方[相册.应用程序包.沙盒.Internet],通过这4个源,我们就可以存取应用图片. 相册 iphone的相册包含摄像头胶卷+用户计算机同步的部分照片.用户可以通过 ...

  5. iOS 屏幕方向

    参考文章:http://www.tuicool.com/articles/e2q6zi 一般的应用,只会支持竖屏正方向一个方向,支持多个屏幕方向的应用还是比较少的. 当时也没搞明白,所以直接就设置了正 ...

  6. iOS上传图片和视频(base64和file)

    前言:iOS开发中经常会使用到图片和视频上传及保存到相册,下面我讲介绍视频图片的两种上传服务器的方法.以阿里云的OSS服务器为例. 友情提示:上传图片方法在APP中使用很广泛,最好单独写一个图片上传的 ...

  7. 微信网页IOS上传图片旋转解决方案

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. 前端手势控制图片插件书写四(图片上传及Ios图片方向问题)

    1.在图片上传中,使用的input的type为File的属性.使用filereader的Api let that = this; var file = document.getElementById( ...

  9. vue iOS上传图片file 出错

    前言 用vue 移动端上传图片在低版本的 ios 手机上 图片转换base64 在转换file 文件类型 会报错 并且报错 “Script Error ” 查阅了github 和一些文档发现 可以吧 ...

随机推荐

  1. MySQL服务器是怎么处理客户端请求的

    不论MySQL客户端进程和服务器进程是采用哪种方式进行通信,最后实现的效果都是:客户端进程向服务器进程发送一段文本(MySQL语句),服务器进程处理后再向客户端进程发送一段文本(处理结果).那服务器进 ...

  2. Spark HA搭建

    正文 下载Spark版本,这版本又要求必须和jdk与hadoop版本对应. http://spark.apache.org/downloads.html tar -zxvf 解压到指定目录,进入con ...

  3. Centos7 GRE Tunnel

    一.关闭防火墙及selinux 二.CentOS7默认不加载gre内核模块,加载gre内核模块 # modprobe ip_gre   临时加载gre模块(重启后失效) # lsmod |grep g ...

  4. cv2 exposureFusion (曝光融合)

    import cv2 import numpy as np import sys filenames = ['./images/memorial0061.jpg', './images/memoria ...

  5. express高效入门教程(3)

    3.路由 路由到底是什么呢?不管官方定义到底是什么,咱通俗的说就是根据不同的url,执行不同的代码,类似于编程语言中的分支结构 3.1.express规划路由 稍微复杂点的应用,通常都是分模块进行的, ...

  6. 【Xamarin.Forms 1】App的创建与运行

    引言 本篇文章将从介绍Xamarin.Forms创建开始. 开发环境 Visual Studio 2019 16.6.2 Xamarin.Forms 4.6.0.726 Android 5.0 (AP ...

  7. 听说你还不知道CompletableFuture?

    java8已经在日常开发编码中非常普遍了,掌握运用好它可以在开发中运用几行精简代码就可以完成所需功能.今天将介绍CompletableFuture的在生产环境如何使用实践.CompletableFut ...

  8. 如何嵌套一个网页html到另一个html中

    在常规网页开发中(单页应用除外哈),经常会遇到把一些通用内容的页面集中到一个页面中,需要使用这些页面只需要包含引入即可,这样有利于维护和修改,当通用页面修改时只需更改一个文件就可以了,不需要每个文件单 ...

  9. github检索小技巧

    GitHub筛选项目 首先打开主页 没有github账户的小伙伴先注册再登录 (其实不登录也可以下载项目) 登录状态的搜索框 未登录状态下的搜索框 点击搜索框输入内容 根据自己需要,输入关键字搜索 明 ...

  10. 奇妙的 CSS MASK

    本文将介绍 CSS 中一个非常有意思的属性 mask . 顾名思义,mask 译为遮罩.在 CSS 中,mask 属性允许使用者通过遮罩或者裁切特定区域的图片的方式来隐藏一个元素的部分或者全部可见区域 ...