最近做的vue项目中好多涉及到图片上传的,为了方便开发就进行了相关总结。因为公司有好多项目,并且使用的是不同后台语言,有的需要通过base64字符串传递,有的需要转换成二进制数据流传递,有的可以直接使用from表单进行提交。后来有涉及到ios上拍照图片会旋转的问题,也一并进行了封装。好了废话不多说直接上代码。
DOCTYPE html
>
<
html
>
<
head
>
<
meta
charset=
"utf-8"
/>
<
title
>图片上传
title
>
head
>
<
body
>
<
form
id=
"upImg"
>
<
input
type=
'file'
accept=
"image/*"
name=
"avatar"
placeholder=
""
id=
"img"
/>
form
>
<
img
src=
""
alt=
""
id=
'preImg'
>
<
script
src=
'./exif.js'
>
<
/
script
>
<
script
>
var
domImg =
document.
querySelector(
'#img')
//添加DOM事件
domImg.
onchange =
function
upLoadImg(
e,
type) {
let
files =
e.
target.
files ||
e.
dataTransfer.
files;
if (!
files.
length)
return;
if (
files[
0].
type.
indexOf(
"image") <
0) {
alert(
"上传了非图片");
return;
}
if (
files[
0].
size >
5 *
1000000) {
alert(
"上传文件过大");
return;
}
// 图片压缩成base64
compress(
e.
target, (
base64,
imgFile)
=> {
var
upImage =
new
FormData();
upImage.
append(
"fileName",
imgFile.
name);
var
blob =
convertImgDataToBlob(
base64);
upImage.
append(
"file",
blob);
//上传图片接口
this.
$http({
method:
"POST",
url:
interfaced.
aliYun,
body:
upImage
}).
then(
res
=> {
console.
log(
res);
},
err
=> {
console.
log(
err);
}
);
});
//将base64转换成二进制函数
function
convertImgDataToBlob(
base64Data) {
var
format =
"image/jpeg";
var
base64 =
base64Data;
var
code =
window.
atob(
base64.
split(
",")[
1]);
var
aBuffer =
new
window.
ArrayBuffer(
code.
length);
var
uBuffer =
new
window.
Uint8Array(
aBuffer);
for (
var
i =
0;
i <
code.
length;
i++) {
uBuffer[
i] =
code.
charCodeAt(
i) &
0xff;
}
var
blob =
null;
try {
blob =
new
Blob([
uBuffer], {
type:
format
});
}
catch (
e) {
window.
BlobBuilder =
window.
BlobBuilder ||
window.
WebKitBlobBuilder ||
window.
MozBlobBuilder ||
window.
MSBlobBuilder;
if (
e.
name ==
"TypeError" &&
window.
BlobBuilder) {
var
bb =
new
window.
BlobBuilder();
bb.
append(
uBuffer.
buffer);
blob =
bb.
getBlob(
"image/jpeg");
}
else
if (
e.
name ==
"InvalidStateError") {
blob =
new
Blob([
aBuffer], {
type:
format
});
}
else {}
}
return
blob;
}
//将图片压缩成base64函数
function
compress(
event,
callback) {
//图片方向角
var
Orientation =
null;
var
file =
event.
files[
0];
var
reader =
new
FileReader();
//获取照片方向角属性,用户旋转控制
EXIF.
getData(
file,
function() {
EXIF.
getAllTags(
this);
Orientation =
EXIF.
getTag(
this,
'Orientation');
});
reader.
onload =
function (
e) {
var
image =
document.
createElement(
"img");
image.
onload =
function () {
//使用canvas重绘图片
var
canvas =
document.
createElement(
"canvas");
var
x =
this.
width;
var
y =
this.
height;
this.
width =
375 *
2;
this.
height =
this.
width /
x *
y;
var
width =
this.
width;
var
height =
this.
height;
canvas.
width =
this.
width;
canvas.
height =
this.
height;
var
context =
canvas.
getContext(
"2d");
context.
clearRect(
0,
0,
width,
height);
//对图片进行旋转
switch (
Orientation) {
case
3:
context.
rotate(
180 *
Math.PI /
180);
context.
drawImage(
this, -
this.
width, -
this.
height,
this.
width,
this.
height);
break;
case
6:
context.
rotate(
90 *
Math.PI /
180);
context.
drawImage(
this,
0, -
this.
width,
this.
height,
this.
width);
break;
case
8:
context.
rotate(
270 *
Math.PI /
180);
context.
drawImage(
this, -
this.
height,
0,
this.
height,
this.
width);
break;
case
2:
context.
translate(
this.
width,
0);
context.
scale(-
1,
1);
context.
drawImage(
this,
0,
0,
this.
width,
this.
height);
break;
case
4:
context.
translate(
this.
width,
0);
context.
scale(-
1,
1);
context.
rotate(
180 *
Math.PI /
180);
context.
drawImage(
this, -
this.
width, -
this.
height,
this.
width,
this.
height);
break;
case
5:
context.
translate(
this.
width,
0);
context.
scale(-
1,
1);
context.
rotate(
90 *
Math.PI /
180);
context.
drawImage(
this,
0, -
this.
width,
this.
height,
this.
width);
break;
case
7:
context.
translate(
this.
width,
0);
context.
scale(-
1,
1);
context.
rotate(
270 *
Math.PI /
180);
context.
drawImage(
this, -
this.
height,
0,
this.
height,
this.
width);
break;
default:
context.
drawImage(
this,
0,
0,
this.
width,
this.
height);
}
var
quality =
0.9;
//压缩程度
var
data;
var
result;
var
length;
//控制图片上传的大小,注意若图片过大 ajax上传的时候会出现参数为null的错误
//这里如果图片过大会将图片压缩程度放大
do {
data =
canvas.
toDataURL(
"image/jpeg",
quality);
length =
data.
length;
result = (
length /
4 *
3 +
1023) /
1024;
//计算压缩后图片的大小
quality -=
0.05;
}
while (
result >
450);
//data:base64
document.
querySelector(
'#preImg').
src =
data
callback(
data,
event.
files[
0]);
};
image.
src =
e.
target.
result;
};
reader.
readAsDataURL(
file);
}
}
<
/
script
>
body
>
html
>