前言:图片裁剪一般都是用户选择头像时用到,现在很多插件都可以满足这个功能,但是我们不仅要会用插件,还要自己懂的裁剪原理。
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>