在显示上传完毕的图片的时候遇到了一个问题, 图片莫名其妙被逆时针旋转了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. linux最小化安装命令补全

    bash-completion 需要安装bash-completion才能补全,安装后,重新打开一个窗口就能生效.

  2. #linux vscode 保存总提示“Retry as sudo”

    linux中,对不同路径下的文件,系统默认指定了不同的操作权限(读/写/执行),出现这个问题是由于文件的权限不足造成的.(路径为/opt/lampp/htdocs/LearnPHP_jayce/hel ...

  3. Newtonsoft 六个超简单又实用的特性,值得一试 【下篇】

    一:讲故事 上一篇介绍的 6 个特性从园子里的反馈来看效果不错,那这一篇就再带来 6 个特性同大家一起欣赏. 二:特性分析 1. 像弱类型语言一样解析 json 大家都知道弱类型的语言有很多,如: n ...

  4. 如何修改git commit的author信息

    本地有多个git账号时,容易发生忘记设置项目默认账号,最后以全局账号提交的情况,其实对代码本身并无影响,只是提交记录里显示的是别的名字稍显别扭. 举个例子:  查看提交日志,假设以a(a@email. ...

  5. mysql 出现You can't specify target table for update in FROM clause错误的解决方法

    mysql出现You can’t specify target table for update in FROM clause 这个错误的意思是不能在同一个sql语句中,先select同一个表的某些值 ...

  6. 微信小程序点击保存图片到本地相册——踩坑

    在微信小程序中要保存图片到本地相册,需要获取相册权限. 总之整个功能实现下来需要如下几个小程序的API:wx.getSetting,wx.authorize,wx.openSetting,wx.dow ...

  7. Git安装及配置SSH-Key

    下载Git 打开 https://git-scm.com/downloads 选择windows, 下载并安装. 配置全局用户名及邮箱 配置用户名 git config --global user.n ...

  8. 调用微信内置的方法及wx.config的配置问题

    首先请看网址: https://www.w3cschool.cn/weixinkaifawendang/h8ap1qe5.html 重点说下怎么配置wx.config(为了安全,所有的参数都在服务端获 ...

  9. Centos7 上安装FastDFS

    Centos7 上安装 FastDFS 本文章摘抄于 风止鱼歇  博客地址:https://www.cnblogs.com/yufeng218/p/8111961.html 1.安装gcc(编译时需要 ...

  10. SpringBoot下Druid连接池的使用配置

    Druid是一个JDBC组件,druid 是阿里开源在 github 上面的数据库连接池,它包括三部分: * DruidDriver 代理Driver,能够提供基于Filter-Chain模式的插件体 ...