canvas去除图片空白部分,图片裁剪

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">
                        <path
                            d="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>

 

 

posted @ 2025-02-06 14:13  瞎BB的是2B  阅读(98)  评论(0)    收藏  举报