前言:图片裁剪一般都是用户选择头像时用到,现在很多插件都可以满足这个功能,但是我们不仅要会用插件,还要自己懂的裁剪原理。
1. 流程
流程分为:1. 预览本地图片 2. 选择裁剪区域 3. 上传裁剪图像
2. 如何预览图片
通过 FileReader 构造函数,将本地的图片,转换成 base64 的地址,不通过网络请求,直接预览。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="initial-scale=1.0, user-scalable=no, width=device-width"
/>
<title>document</title>
<style>
.preview {
width: 500px;
height: 500px;
margin: 0 auto;
object-fit: cover;
}
</style>
</head>
<body>
<input type="file" />
<img class="preview" />
<script>
const inp = document.querySelector("input");
const img = document.querySelector("img");
inp.onchange = (e) => {
const file = e.target.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
img.src = reader.result;
};
};
</script>
</body>
</html>
3. 上传裁剪后图片
实现思路:上传图片本质是上传文件,我们需要得到一个文件 file 对象,怎么拿到 file 对象呢,通过 canvas 画出裁剪图然后导出为 blob 对象,然后将 blob 对象转为 file 对象我们就可以进行上传了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="initial-scale=1.0, user-scalable=no, width=device-width"
/>
<title>document</title>
<style>
.preview {
width: 500px;
height: 500px;
margin: 0 auto;
object-fit: cover;
}
</style>
</head>
<body>
<input type="file" />
<img class="preview" />
<button>点击上传裁剪图</button>
<script>
const inp = document.querySelector("input");
const img = document.querySelector("img");
const btn = document.querySelector("button");
inp.onchange = (e) => {
const file = e.target.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
img.src = reader.result;
};
};
function uploadResult({ cutWidth, cutHeight, cutX, cutY }) {
const cvs = document.createElement("canvas");
const ctx = cvs.getContext("2d");
cvs.width = 200;
cvs.height = 200;
ctx.drawImage(
img,
cutX,
cutY,
cutWidth,
cutHeight,
0,
0,
cvs.width,
cvs.height
);
document.body.appendChild(cvs);
cvs.toBlob((blob) => {
const file = new File([blob], "cut.png", { type: "image/png" });
// 上传 file 对象
console.log(file);
});
}
btn.onclick = () => {
uploadResult({
cutWidth: 100,
cutHeight: 100,
cutX: 250,
cutY: 250,
});
};
</script>
</body>
</html>