在显示上传完毕的图片的时候遇到了一个问题, 图片莫名其妙被逆时针旋转了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. Jmeter系列(32)- 详解 CSV 数据文件设置

    如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 了解一哈什么是 CSV 文件 为了实现 ...

  2. CentOS 7 Nacos 集群搭建

    环境 CentOS 7.4 MySQL 5.7 nacos-server-1.1.2 本次安装的软件全部在 /home/javateam 目录下. MySQL 安装 首先下载 rpm 安装包,地址:h ...

  3. 暑假集训day1 水题 乘法最大

    题目大意:有一个长度为N的字符串,要求用K个乘号将其分成K+1个部分,求各个部分相乘的最大值 输入:第一行输入N和K,第二行输入一个长度为N的字符串 算法分析 1. 这个题只是一个简单的dp(甚至连区 ...

  4. python文件处理-根据txt列表将文件从其他文件夹 拷贝到指定目录

    内容涉及:路径拼接,文件拷贝,内容追加(append) # !/usr/bin/python # -*- coding: UTF-8 -*- import pandas as pd import os ...

  5. Package Control:There are no packages available for installation

    百度推荐的sublime3,里面好多全家桶,注意安装. 我的问题报错是:Package Control:There are no packages available for installation ...

  6. 学习Java的Day05

    知识点 关键字,常用类(super,static,final): super 子类对父类的引用,只能在非静态方法中使用 引用父类的成员变量的格式为 super.成员变量名称 引用父类的非静态方法的格式 ...

  7. 七.数据分页原理,paginator与page对象

    1.分页: Paginator对象 Page对象 2.Paginator: class Paginator(object_list, per_page, orphans=0, allow_empty_ ...

  8. Write a program that prints its input one word per line.

    #include <stdio.h> #define State '\n' void main() { int Juge=;/*only one space*/ int c=; while ...

  9. Yolo训练自定义目标检测

    Yolo训练自定义目标检测 参考darknet:https://pjreddie.com/darknet/yolo/ 1. 下载darknet 在 https://github.com/pjreddi ...

  10. No mapping found for HTTP request with URI [/***] in DispatcherServlet with name 'dispatcherServlet'

    相信不少Springboot初学者和我一样,都遇到上边这个提示,明明路径都是对的,但就是找不到对于的页面而404了,这也困扰我很长一段时间,我也是不得其解,百度上也鲜有合理回答,因为以前使用的时候,明 ...