html5+canvas进行移动端手机照片上传时,发现ios手机上传竖拍照片会逆时针旋转90度,横拍照片无此问题;Android手机没这个问题。
因此解决这个问题的思路是:获取到照片拍摄的方向角,对非横拍的ios照片进行角度旋转修正。
注:在开发时发现 三星手机提交时会向右旋转90度 所以对仅对安卓系统中三星手机进行特别处理
这里主要用到Orientation属性。说明如下:
旋转角度 | 参数 |
---|---|
0° | 1 |
顺时针90° | 6 |
逆时针90° | 8 |
180° | 3 |
一、html文件
- <a href="javascript:document.getElementById('fileobj').click()">
- <button type="button" class="upload-image-btn" >
- <span class="upload-btn-text" v-if="!show_upload_next_button" v-text="Camera / Photo"></span>
- <span class="upload-btn-text" v-text="Please add the images" v-else></span>
- </button>
- </a>
- <input type="file" id="fileobj" accept="image/*" style="display:none" @change="fileobj_change">
二、js文件
- fileobj_change: function(e) {
- var vue_this = this;
- var file = e.target.files[0];
- vue_this.show_loading = true;
- var orientation = 0;
- EXIF.getData(file,
- function() {
- EXIF.getAllTags(this);
- orientation = EXIF.getTag(this, 'Orientation');
- });
- // console.log(orientation)
- var reader = new FileReader();
- reader.onload = function(readerEvent) {
- var face_image = new Image();
- face_image.onload = function(imageEvent) {
- var canvas = document.getElementById('sketchpad');
- drawPhotoImage(this, canvas, face_image, orientation);
- vue_this.image_url = canvas.toDataURL('image/jpeg');
- vue_this.show_upload_next_button = true;
- vue_this.show_loading = false;
- };
- face_image.src = readerEvent.target.result;
- };
- reader.readAsDataURL(file);
- }
- function drawPhotoImage(image, canvas, face_image, orientation) {
- var max_size = 544,
- width = face_image.width,
- height = face_image.height;
- if (width > height) {
- if (width > max_size) {
- height *= max_size / width;
- width = max_size;
- }
- } else {
- if (height > max_size) {
- width *= max_size / height;
- height = max_size;
- }
- }
- canvas.width = width;
- canvas.height = height;
- if (navigator.userAgent.match(/iphone/i)) {
- if (orientation != "" && orientation != 1) {
- switch (orientation) {
- case 6:
- rotateImg(image, 'left', canvas, width, height);
- break;
- case 8:
- rotateImg(image, 'right', canvas, width, height);
- break;
- case 3:
- /*
- //原资料中旋转180度方法为调用两遍90度 但是我这边不起作用 所以增加一种新的方式 => right2
- rotateImg(image, 'right', canvas, width, height);
- rotateImg(image, 'right', canvas, width, height);*/
- rotateImg(image, 'right2', canvas, width, height);
- break;
- default:
- canvas.getContext('2d').drawImage(face_image, 0, 0, width, height);
- break;
- }
- } else {
- canvas.getContext('2d').drawImage(face_image, 0, 0, width, height);
- }
- } else if (get_ua_info()) {
- rotateImg(image, 'left', canvas, width, height);
- } else {
- canvas.getContext('2d').drawImage(face_image, 0, 0, width, height);
- }
- }
- function rotateImg(img, direction, canvas, width, height) {
- var min_step = 0;
- var max_step = 3;
- if (img == null) {
- return;
- }
- var step = 2;
- if (step == null) {
- step = min_step;
- }
- if (direction == 'right') {
- step++;
- step > max_step && (step = min_step);
- } else if (direction == 'right2') {
- step = 2;
- } else {
- step--;
- step < min_step && (step = max_step);
- }
- var degree = step * 90 * Math.PI / 180;
- var ctx = canvas.getContext('2d');
- switch (step) {
- case 0:
- canvas.width = width;
- canvas.height = height;
- ctx.drawImage(img, 0, 0, width, height);
- break;
- case 1:
- canvas.width = height;
- canvas.height = width;
- ctx.rotate(degree);
- ctx.drawImage(img, 0, -height, width, height);
- break;
- case 2:
- canvas.width = width;
- canvas.height = height;
- ctx.rotate(degree);
- ctx.drawImage(img, -width, -height, width, height);
- break;
- case 3:
- canvas.width = height;
- canvas.height = width;
- ctx.rotate(degree);
- ctx.drawImage(img, -width, 0, width, height);
- break;
- }
- }
- //判断是否为三星手机
- //注:此方法准确率欠佳 若有需求可参考https://github.com/fex-team/ua-device
- function get_ua_info() {
- if (navigator.userAgent.indexOf(" SM-") != -1) return true;
- else return false;
- }
来源: https://www.2cto.com/kf/201710/692924.html