canvas去除图片空白部分实现图片的缩小,可用于vue-signature-pad 签名实现签名裁剪,图片裁剪
电子签名连接 https://blog.csdn.net/Shids_/article/details/135695601
<!DOCTYPE html> <html><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1"><title></title></head><body><button onclick="handleClear()">去除</button><div class="view-box"><div class="view-content"><img class="img" src="https://cdn.shopifycdn.net/s/files/1/0343/0275/4948/files/png_7261d2f1-9f99-4972-8e2f-7a00535a9f34.png?v=1634027745" alt=""><div class="arrow"><svg t="1640838036592" class="icon" viewBox="0 0 1024 1024" version="1.1"xmlns="http://www.w3.org/2000/svg" p-id="4100" width="128" height="128"><pathd="M916.70478 440.270049L531.68078 217.987122c-21.079415-12.188098-47.953171-13.08722-70.631024 0s-35.365463 36.764098-35.365463 61.140293v97.304975H127.37561c-34.766049 0-62.938537 28.172488-62.938537 62.938537v145.258146c0 34.766049 28.172488 62.938537 62.938537 62.938537h298.308683v90.411707c0 26.673951 13.886439 52.748488 38.662244 67.034537 24.775805 14.385951 54.247024 13.386927 77.524292 0l374.833951-216.388683c25.674927-14.685659 42.858146-42.458537 42.858147-74.227512 0-31.469268-17.18322-59.242146-42.858147-74.12761z"p-id="4101" fill="#ffffff"></path></svg></div><img class="img" id="img" src="" alt=""></div></div><script type="text/javascript">async function handleClear() {// const url = "https://cdn.shopifycdn.net/s/files/1/0343/0275/4948/files/png_7261d2f1-9f99-4972-8e2f-7a00535a9f34.png?v=1634027745"; const bigURL = 'https://cdn.shopifycdn.net/s/files/1/0343/0275/4948/files/png_7261d2f1-9f99-4972-8e2f-7a00535a9f34.png?v=1634027745'const base64 = await clearImageEdgeBlank(bigURL, 4);console.log(base64)document.getElementById("img").setAttribute("src", base64);}handleClear();/*** 清楚图片周围空白区域* @param {string} url - 图片地址或base64* @param {number} [padding=0] - 内边距* @return {string} base64 - 裁剪后的图片字符串*/function clearImageEdgeBlank(url, padding = 0) {console.log(url)console.log(padding)return new Promise((resolve, reject) => {// create canvas const canvas = document.createElement("canvas");const ctx = canvas.getContext("2d");// create image const image = new Image();image.onload = draw;image.src = url;image.crossOrigin = "Anonymous";function draw() {canvas.width = image.width;canvas.height = image.height;ctx.drawImage(image, 0, 0, canvas.width, canvas.height);const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);const {data,width,height} = imageData;// 裁剪需要的起点和终点,初始值为画布左上和右下点互换设置成极限值。 let startX = width,startY = height,endX = 0,endY = 0;/*col为列,row为行,两层循环构造每一个网格,便利所有网格的像素,如果有色彩则设置裁剪的起点和终点*/console.log('开始')const startTime = Date.now();for (let col = 0; col < width; col++) {for (let row = 0; row < height; row++) {// 网格索引 const pxStartIndex = (row * width + col) * 4;// 网格的实际像素RGBA const pxData = {r: data[pxStartIndex],g: data[pxStartIndex + 1],b: data[pxStartIndex + 2],a: data[pxStartIndex + 3]};// 存在色彩:不透明 const colorExist = pxData.a !== 0;/*如果当前像素点有色彩startX坐标取当前col和startX的最小值endX坐标取当前col和endX的最大值startY坐标取当前row和startY的最小值endY坐标取当前row和endY的最大值*/if (colorExist) {startX = Math.min(col, startX);endX = Math.max(col, startX);startY = Math.min(row, startY);endY = Math.max(row, endY);}}}const interval = Date.now() - startTime;console.log('总共耗时', interval);// 右下坐标需要扩展1px,才能完整的截取到图像 endX += 1;endY += 1;// 加上padding startX -= padding;startY -= padding;endX += padding;endY += padding;// 根据计算的起点终点进行裁剪 const cropCanvas = document.createElement("canvas");const cropCtx = cropCanvas.getContext("2d");cropCanvas.width = endX - startX;cropCanvas.height = endY - startY;cropCtx.drawImage(image,startX,startY,cropCanvas.width,cropCanvas.height,0,0,cropCanvas.width,cropCanvas.height);// rosolve裁剪后的图像字符串 resolve(cropCanvas.toDataURL());}});}</script></body> </html>