IOS中的拍照时,相机有4种不同的放置方法,不管你的相机如何放置,拍出来的照片从数据上来说都是一个方向的(横向)。把你的手机逆时针旋转90度(横向拿),这个方向就是相机的原始视角。你从任何其他3个视角拍出的照片的数据其实都是和原始视角一样的,只是在文件中做了个关于视角的标记。在程序需要展示照片时,需要根据这个标志来翻转图像。
假如你是竖向拍的照片,对相机来说,就是等于把头向右侧歪成水平,再拍照。它眼里看到的世界是逆时针转了90度的。要把相机里的图像转成人看到的视角,就要顺时针旋转90度。
一、实现图像转换的步骤:
1. 在js中,可以通过EXIF图像库获取image的旋转角度,
EXIF.getData(image, function () {
var orient = EXIF.getTag(this, ‘Orientation’);
…
});
2. 把image 顺时针旋转一定度数画到 canvas上
iphone拍照分辨率太大,一般需要缩小图片,在canvas上画image的时候可以按比例缩小画。
iphone新出的手机长宽比太大,长长的图片有时不好看,需要把上方和下方剪去一部分。
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
var cutHt = (ht - keepHt) / 2;//计算上下切去高度
canvas.height = keepHt;
ctx.rotate(degree);//顺时针旋转一定角度
//注意: ctx.rotate(degree);必须在canvas的大小设定好之后再旋转,否则会形成黑屏图片*
ctx.translate(-cutHt, 0);
//translate 将整个画面移向左动cutHt
ctx.drawImage(image, cutHt / bl, 0, keepHt / bl, height, cutHt, 0, keepHt, -wd);
//-wd 是绘制的高度,这里为负数不太好理解。高度为正的情况下,是画在横坐标轴下方的,高度为负时画在上方。宽度为正画在纵坐标轴右侧,为负数时在左侧。
3.然后再把canvas生成图像,这样就完成了格式的转换。
canvas.toBlob(callback, “image/jpeg”, resolution); // get the data from canvas as 70% JPG
二、完整代码
function resizeImage(blob, max_width, max_height, resolution, callback) {
window.URL = window.URL || window.webkitURL;
var blobURL = window.URL.createObjectURL(blob); // and get it's URL
// helper Image object
var image = new Image();
image.src = blobURL;
image.onload = function () {
// have to wait till it's loaded
// var resized = resizeMe(image); // send it to canvas
EXIF.getData(image, function () {
//EXIF.getAllTags(this);
var orient = EXIF.getTag(this, 'Orientation');
var canvas = document.createElement('canvas');
// resize the canvas and draw the image data into it
var ctx = canvas.getContext("2d");
var width = image.width;
var height = image.height;
var wd = width, ht = height;
var degree = 0;
var step = 0;
if (navigator.userAgent.match(/iphone/i)) {
if (orient !== "" && orient !== 1) {
switch (orient) {
case 6://需要顺时针(向左)90度旋转
//rotateImg(this, 'left', canvas);
step = 1;
ht = width;
wd = height;
break;
case 8://需要逆时针(向右)90度旋转
step = 3;
ht = width;
wd = height;
break;
case 3://需要180度旋转
// rotateImg(this, 'right', canvas);//左转两次
// rotateImg(this, 'right', canvas);
step = 2;
break;
}
}
}
degree = step * 90 * Math.PI / 180;
var wl = max_width / wd, hl = max_height / ht;
var bl = wl < hl ? wl : hl;
ht = Math.round(ht * bl); wd = Math.round(wd * bl);
canvas.width = wd; canvas.height = ht;
//ctx.rotate(degree);//anti clock
var maxHtBl = 1.1;
if (step === 1) {
if (ht / wd > maxHtBl) {
var keepHt = wd * maxHtBl;
var cutHt = (ht - keepHt) / 2;
canvas.height = keepHt;
ctx.rotate(degree);//this should be always after setting the height
ctx.translate(-cutHt, 0);
ctx.drawImage(image, cutHt / bl, 0, keepHt / bl, height, cutHt, 0, keepHt, -wd);
}
else {
ctx.rotate(degree);
ctx.drawImage(image, 0, 0, ht, -wd);
}
}
else if (step === 2) {
ctx.rotate(degree);
ctx.drawImage(image, 0, 0, -wd, -ht);
}
else if (step === 3) {
ctx.rotate(degree);
ctx.drawImage(image, 0, 0, -ht, wd);
}
else if (step === 0) {
if (ht / wd > maxHtBl) {
var keepHt = wd * maxHtBl;
var cutHt = (ht - keepHt) / 2;
canvas.height = keepHt;
//ctx.translate(0,-cutHt);
ctx.drawImage(image, 0, cutHt / bl, width, keepHt / bl, 0, 0,wd, keepHt);
}
else ctx.drawImage(image, 0, 0, wd, ht);
}
canvas.toBlob(callback, "image/jpeg", resolution); // get the data from canvas as 70% JPG
});
}
}