前言
很多公司业务中,会存在上传资料图片,以供审核的需求。那我们用H5
如何实现,并达到好的效果呢
涉及技术点:
html media capture
FileReader
||ULR.createObjectURL()
canvas
EXIF
&orientation
调用相机
<input type='file' accept='image/*' capture="camera"/>
获取图片信息
以下两种方式皆可:
- new FileReader().readAsDataURL(file) 异步/data:base64
- ULR.createObjectURL(file) 同步/内存url
压缩
- 限制最大宽度,对宽高做处理
- 等比例压缩
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = Math.min(image.naturalWidth, option.maxWidth)
// 高度通过宽度压缩比处理,保证等比例压缩
const ratio = canvas.width / image.naturalWidth
canvas.height = image.naturalHeight * ratio
...
// 二次压缩(比如90%)
canvas.toDataURL(fileType, 0.9); // fileType: image/jpeg
旋转处理
手机相机(基本上都是Iphone)拍照,你会发现有时候照片会自动旋转,有时候并不是我们期望的显示效果。
不过手机拍照获取的图片,有EXIF(Exchangeable image file format),会默认设置一个orientation tag(jpeg格式才有)。orientation标示了图片旋转信息。
首先,我们可以用Exifjs获取orientation。Exif.js提供了js读取图像的原始数据的功能扩展(拍照方向、相机设备型号、拍摄时间、ISO感光度、GPS地理位置等数据).
import EXIF from 'exif-js';
...
EXIF.getData(file, function () {
const orientation = EXIF.getTag(this, 'Orientation');
console.log(`orientation: ${orientation}`);
});
然后,我们用canvas对图片做一些旋转处理即可( 亲测只存在1,3,6,8四种情况):
// 判断图片方向,重置 canvas 大小,确定旋转角度,iphone 默认的是 home 键在右方的横屏拍摄方式
switch (orientation) {
// 1 不需要旋转
case 1: {
ctx.drawImage(img, 0, 0, width, height);
ctx.clearRect(0, 0, width, height);
ctx.drawImage(img, 0, 0, width, height);
break;
}
// iphone 横屏拍摄,此时 home 键在左侧 旋转180度
case 3: {
ctx.clearRect(0, 0, width, height);
ctx.translate(0, 0);
ctx.rotate(Math.PI);
ctx.drawImage(img, -width, -height, width, height);
break;
}
// iphone 竖屏拍摄,此时 home 键在下方(正常拿手机的方向) 旋转90度
case 6: {
ctx.clearRect(0, 0, width, height);
ctx.translate(0, 0);
ctx.rotate(90 * Math.PI / 180);
ctx.drawImage(img, 0, -height, width, height);
break;
}
// iphone 竖屏拍摄,此时 home 键在上方 旋转270度
case 8: {
ctx.clearRect(0, 0, width, height);
ctx.translate(0, 0);
ctx.rotate(-90 * Math.PI / 180);
ctx.drawImage(img, -width, 0, width, height);
break;
}
default: {
ctx.clearRect(0, 0, width, height);
ctx.drawImage(img, 0, 0, width, height);
break;
}
}
最后,我们上传处理完的图片。