h5 input type=file ios拍照相片旋转90度修正 前端图片利用canvas处理压缩 vue图片上传优化处理
直接进入正题input type=file 是前端处理图片上传的必要途径 这里说一下第一个需求 如果用户点击type=file的按钮 只想完成调用照相功能 而不用选取照片功能其实 input type=file标签上还是有很多 特殊好玩的属性的 我们列举一下<input type="file" accept="image/*" capture="camera"...
直接进入正题
input type=file 是前端处理图片上传的必要途径 这里说一下
第一个需求 如果用户点击type=file的按钮 只想完成调用照相功能 而不用选取照片功能
其实 input type=file标签上还是有很多 特殊好玩的属性的 我们列举一下
<input type="file" accept="image/*" capture="camera">
<input type="file" accept="video/*" capture="camcorder">
<input type="file" accept="audio/*" capture="microphone">
/*
accept规定可通过文件上传控件提交的文件类型;
capture表示的是系统所捕获的默认设备,camera:照相机;camcorder:摄像机;microphone:录音。
*/
<input type="file" accept="image/*" >
<input type="file" accept="video/*" >
<input type="file" accept="audio/*" >
/*
如果不加上capture,则只会显示相应的,例如上述三种依次是:拍照或图库,录像或图库,
录像或拍照或图库,加上capture之后不会调用图库。
其中还有一个属性multiple,支持多选,当支持多选时,multiple优先级高于capture,
所以只用写成:<input type="file" accept="image/*" multiple>就可以
*/
当我们修改默认的capture的时候 就是默认调起什么方式了
不过我们单位的需求 是 只想选择相册 想关闭掉拍照的唤起 这里百度很多 其中 回复最多的是添加multiple属性
原理是 这个属性是要可以多张选择的 而你开启了多张选择 就会关闭掉照相了
不过我这里测试后 发现只有安卓生效 ios 微信内置无效 还是可以调用拍照功能
2 正题 如何进行压缩 和 旋转 这里我将方法进行了抽离 下面贴出代码
a. 利用EXIF 来进行是否需要旋转的确认
b. npm install exif-js -S 进行下载 (注意 不要下载成 exif了 很容易弄混 不过2个模块并不是一个功能)
c. 返回的内容是我写的 即result.flag是true 则需要通过Orientation去修正; false则无需处理
const EXIF = require('exif-js') // 引入
// vue method里的方法
isNeedFixPhoto(file){
return new Promise(function (resolve,reject) {
EXIF.getData(file, function() {
var Orientation = EXIF.getTag(this, 'Orientation');
if(Orientation && Orientation != 1){
//图片角度不正确
resolve({flag:true,Orientation:Orientation})
}else{
//不需处理直接上传
resolve({flag:false,Orientation:Orientation})
}
});
})
},
// 调用
const result=await this.isNeedFixPhoto(file);
d.利用 方法 将file文件 读成base64码
// 定义方法
file2Base64(file) {
return new Promise(function (resolve, reject) {
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (ev) {
resolve(ev.target.result);
}
})
},
// 方法调用
const resultBase64=await this.file2Base64(file);
e. 结合上面2步 有了是否需要修正的判断 也有了文件的base64码 下面处理判断
// 整体修正方法
async repairPhoto(file,num,w){
const result=await this.isNeedFixPhoto(file);
const resultBase64=await this.file2Base64(file);
const Orientation = result.Orientation;
const numb = num || 1;
if(result.flag){ // 处理旋转
return await this.best4Photo(resultBase64,Orientation,numb,w)
}else{ // 不处理旋转
return await this.best4Photo(resultBase64,1,numb,w)
}
},
// 压缩处理选中的方法
best4Photo(resultBase64,Orientation,num,w){
return new Promise(function (resolve, reject) {
let image = new Image();
image.src = resultBase64;
image.onload = function () {
// var imgWidth = this.width,
// imgHeight = this.height; //获取图片宽高
var imgWidth = w,
imgHeight = w*this.height/this.width; //获取图片宽高
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
canvas.width = imgWidth;
canvas.height = imgHeight;
if(Orientation && Orientation != 1){
switch(Orientation){
case 6: // 旋转90度
canvas.width = imgHeight;
canvas.height = imgWidth;
ctx.rotate(Math.PI / 2);
ctx.drawImage(this, 0, -imgHeight, imgWidth, imgHeight);
break;
case 3:// 旋转180度
ctx.rotate(Math.PI);
ctx.drawImage(this, -imgWidth, -imgHeight, imgWidth, imgHeight);
break;
case 8: // 旋转-90度
canvas.width = imgHeight;
canvas.height = imgWidth;
ctx.rotate(3 * Math.PI / 2);
ctx.drawImage(this, -imgWidth, 0, imgWidth, imgHeight);
break;
}
}else{
ctx.drawImage(this, 0, 0, imgWidth, imgHeight);
}
const result = canvas.toDataURL("image/jpeg",num);
resolve(result)
}
})
},
best4photo里 image.onload 是为了 当时想对图片不进行 尺寸的更改 只进行质量度的处理 但是后来总和考虑 还是利用外部参数去设定压缩后的图片尺寸 这里这个方法其实可以省略的
主要 switch 判断了要旋转的角度 然后利用canvas 重新旋转后绘制图片
canvas.toDataUrl 这个方法的第二个参数是用来处理 压缩质量的 可以从 0 到 1 的区间内选择图片的质量
。如果超出取值范围,将会使用默认值 0.92
。其他参数会被忽略
这样我们就完成了图片的旋转和压缩的处理 虽然看似方法很多 但最后的目的 是为了 剥离代码 方便重复利用 其实代码上还有一些可以优化的地方 这里暂不做处理了
如果你觉得我帮到你了,买个肥宅快乐水,怎么样?哈哈哈哈哈哈
更多推荐
所有评论(0)