如何从图像画布中裁剪颜色部分?
Posted
技术标签:
【中文标题】如何从图像画布中裁剪颜色部分?【英文标题】:How to crop color portion from image canvas? 【发布时间】:2018-05-04 17:32:33 【问题描述】:我正在研究基于离子的应用程序。
我想要像用户用手指在图像(画布)上填充红色的功能。所以我已经完成了填充功能,但我想从画布上裁剪填充部分。我附上了一张图片供参考。
我想从上面的图像中裁剪红色部分。我用谷歌搜索但没有找到任何解决方案。
【问题讨论】:
你应该详细说明你的问题,以及到目前为止你为完成你想要的事情而采取的代码或步骤,直到你付出了一些努力,没有人会帮助你。 问题已更新 Canvas: mask an image and preserve its alpha channel?的可能重复 @3Dos - 它不是重复的,在标记为重复之前阅读我在问什么?我知道如何在我已经完成的图像上绘制/填充红色。 但我想从原始图像中裁剪出红色部分 @TofaaniKaanudo 这正是我标记的副本中所解释的内容 【参考方案1】:创建图像掩码。
如果您正在渲染选择区域(红色),那么解决方案很简单。
创建与绘图相同大小的第二个画布,不要将其添加到 DOM。将红色标记内容绘制到该画布上
显示画布上的首先渲染图像,然后渲染该标记 使用“叠加”等合成模式在图像上画布,以便可以看到原始图像并且标记区域为红色。
现在您有两层,一层是图像,另一层是蒙版,您可以使用它来获取标记内容的副本。
为此,请创建第三个画布,在其上绘制原始图像,然后将合成模式设置为“destination-in”。然后在它上面画一个面具。只有标记的像素会保留。
查看示例了解更多详情
setTimeout(example,0); // ensures that the run us after parsing
function example()
const ctx = canvas.getContext("2d");
var w = canvas.width;
var h = canvas.height;
var cw = w / 2; // center
var ch = h / 2;
var selectLayer = CImageCtx(w,h); // creates a canvas
var selectedContent = CImageCtx(w,h); // the selected content
document.body.appendChild(selectedContent);
var image = new Image; // the image
image.src = " https://i.stack.imgur.com/QhFct.png";
// updates the masked result
function updateSelected()
var ctx = selectedContent.ctx;
ctx.drawImage(image,0,0);
ctx.globalCompositeOperation = "destination-in";
ctx.drawImage(selectLayer,0,0);
ctx.globalCompositeOperation = "source-over";
function update()
// if mouse down then
if(mouse.but)
// clear the mask if on the right image
if(mouse.oldBut === false && mouse.x > 256)
selectLayer.ctx.clearRect(0,0,w,h);
mouse.but = false;
else
// draw the red
selectLayer.ctx.fillStyle = "red";
fillCircle(mouse.x, mouse.y, 20, selectLayer.ctx);
// update the masked result
updateSelected();
// clear the canvas
ctx.clearRect(0,0,w,h);
// draw the image
ctx.drawImage(image,0,0);
// then draw the marking layer over it with comp overlay
ctx.globalCompositeOperation = "overlay";
ctx.drawImage(selectLayer,0,0);
ctx.globalCompositeOperation = "source-over";
mouse.oldBut = mouse.but;
requestAnimationFrame(update);
requestAnimationFrame(update);
//#############################################################################
// helper functions not part of the answer
//#############################################################################
const mouse =
x : 0, y : 0, but : false,
events(e)
const m = mouse;
const bounds = canvas.getBoundingClientRect();
m.x = e.pageX - bounds.left - scrollX;
m.y = e.pageY - bounds.top - scrollY;
m.but = e.type === "mousedown" ? true : e.type === "mouseup" ? false : m.but;
;
(["down","up","move"]).forEach(name => document.addEventListener("mouse" + name,mouse.events));
const CImage = (w = 128, h = w) => (c = document.createElement("canvas"),c.width = w,c.height = h, c);
const CImageCtx = (w = 128, h = w) => (c = CImage(w,h), c.ctx = c.getContext("2d"), c);
const fillCircle = (l,y=ctx,r=ctx,c=ctx) =>if(l.p1)c=y; r=leng(l);y=l.p1.y;l=l.p1.x else if(l.x)c=r;r=y;y=l.y;l=l.xc.beginPath(); c.arc(l,y,r,0,Math.PI*2); c.fill()
body font-family : arial;
canvas border : 2px solid black;
Draw on image and the selected parts are shown on the right<br>
Click right image to reset selection<br>
<canvas id="canvas" width=256 height=256></canvas>
已经被屏蔽了。
如果红色蒙版已经应用于图像,那么除了根据图像的红色程度进行阈值过滤之外,您无能为力。但即便如此,您仍会遇到较暗区域和已经包含红色的区域的问题。
除非您拥有原始图像,否则效果会很差。
如果您有原始图像,则必须访问图像数据并通过比较每个像素并仅选择不同的像素来创建新图像作为蒙版。这将迫使您仅使用相同的域图像(或使用 CORS 跨源标头)
【讨论】:
真的你救了我的一天 +1 或接受对你来说还不够。感谢您的支持和合作。如果您有任何橡皮擦的来源或链接(如果用户选择了错误的部分。用户可以擦除它)。我正在等待您的积极反馈。 它不能在移动设备上运行。对于移动,我们需要改变什么。?请给我建议。 @TofaaniKaanudo 手机将需要触摸事件监听器。该代码仅作为如何屏蔽图像的示例,界面与问题无关。 @ Blindman67 你能建议那个面具上的橡皮擦功能吗?如果用户选择了错误的部分。比用户可以擦除它。以上是关于如何从图像画布中裁剪颜色部分?的主要内容,如果未能解决你的问题,请参考以下文章
jquery - 用“cropper”裁剪图像 - 在画布中