从画布图像中删除背景

Posted

技术标签:

【中文标题】从画布图像中删除背景【英文标题】:Remove background from Canvas image 【发布时间】:2021-04-30 07:41:29 【问题描述】:

当我将任何图像上传到画布标签时,我希望我可以移除徽标周围的背景。 这是我的代码:

使用 jQuery 1.12.4 和 jQuery UI 1.9.2

<canvas id="canvas" class="resize" style="width:200px;height:200px;"></canvas>
<input type="file" id="file-input">

<button id="removeBKG" onclick="removeBKG();">
RIMUOVI SFONDO
</button>

<script>
$(function() 
            
            $('#file-input').change(function(e) 
                var file = e.target.files[0],
                    imageType = /image.*/;

                if (!file.type.match(imageType))
                    return;

                var reader = new FileReader();
                reader.onload = fileOnload;
                reader.readAsDataURL(file);
            );

            function fileOnload(e) 
                var $img = $('<img>',  src: e.target.result );
                $img.load(function() 
                    var canvas = $('#canvas')[0];
                    var context = canvas.getContext('2d');

                    canvas.width = this.naturalWidth;
                    canvas.height = this.naturalHeight;
                    context.drawImage(this, 0, 0);
                );
            
            
            $(document).mouseup(function(e) 
            
                var container = $(".ui-wrapper");

                // if the target of the click isn't the container nor a descendant of the container
                if (!container.is(e.target) && container.has(e.target).length === 0) 
                
                    $("#canvas").css("border-style","hidden");
                    $(".ui-resizable-handle").attr("style","visibility: hidden");
                 else 
                        $("#canvas").css("border-style","solid");
                        $(".ui-resizable-handle").attr("style","visibility: visible");
                
            );
            
            
                window.zindex = 30;

                $(".resize").resizable(handles: 'ne, se, sw, nw');
                $(".resize").parent().draggable(
                    stack: "div"
                );
            
        );
    
    
    function removeBKG()
    var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    image = document.getElementById("canvas");

canvas.height = canvas.width = 135;
ctx.drawImage(image,0,0);
    
var imgd = ctx.getImageData(0, 0, 135, 135),
    pix = imgd.data,
    newColor = r:0,g:0,b:0, a:0;

for (var i = 0, n = pix.length; i <n; i += 4) 
    var r = pix[i],
            g = pix[i+1],
            b = pix[i+2];

            pix[i] = newColor.r;
            pix[i+1] = newColor.g;
            pix[i+2] = newColor.b;
            pix[i+3] = newColor.a;


ctx.putImageData(imgd, 0, 0);

</script>

点击功能后的预期结果: 图片的背景被移除,只有徽标仍然可见。

当前结果: 当我点击该功能时,整个图像被删除

问题出在哪里?

这是我想做的一个小例子:

http://jsfiddle.net/loktar/BtbSM/

另一个例子:

图片加载背景

点击时,图片必须没有背景

【问题讨论】:

你是对的!我编辑了我的问题 您的示例使用了 base64 编码的图像,在这里您尝试使用图像文件可能是问题所在? 在该示例中,画布将每个白色像素 (if(r == 255&amp;&amp; g == 255 &amp;&amp; b == 255) ) 更改为黑色像素。在您的示例中,您将所有像素覆盖为黑色像素。所以无论你在画布上放置什么,一切都会变成黑色 这个例子只是为了展示我想要获得的效果。在我的代码中,我将图像加载到画布标签中,然后尝试删除背景。 @FabrizioCalderan 我想从图像中动态删除背景,而不仅仅是背景是白色的 【参考方案1】:

对于给定的图像,您需要保留蓝色部分并删除灰色部分

蓝色部分的红色通道值偏低( 灰色部分的红色通道值为~100

你可以放心的移除所有红色通道大于10的像素,所以这部分代码就变成了

for (var i = 0, n = pix.length; i <n; i += 4) 
    var r = pix[i];


    if(r > 10)  
        // overwrite gray pixel with white pixel
        pix[i] = pix[i+1] = pix[i+2] = 255;
        // alpha channel
        pix[i+3] = 255;
    

当然,这个脚本不能处理其他颜色不同的图像,因为它的信息是硬编码的。

【讨论】:

我试过你的代码,但是当我点击 removeBKG() 时,整个图像都会消失...... jsfiddle.net/fzgtc0e3 它有效。 (alpha 通道为 255) 好的,但是如果没有 base64 编码的图像,可能会有这种效果吗?因为在我的最终代码中,我想在将图像加载到画布标签时应用背景去除效果...

以上是关于从画布图像中删除背景的主要内容,如果未能解决你的问题,请参考以下文章

在画布上绘制背景图像并保存图像

无法在画布中设置背景图像

如何在织物画布中使用背景图像获取绘图路径中的图像?

柔化javascript画布图像中的边缘

如何将图像设置为画布背景而不是让它在 Android Studio/JavaScript 中填充颜色

所选图像未显示在画布上