简体   繁体   中英

How to crop color portion from image canvas?

I am working on ionic based application.

I want to functionality like user has Filled the red color on image(canvas) with finger. So I have done the filled functionality but I want to crop the Filled portion from canvas. I have attached one image for reference.

在此处输入图片说明

I want to crop red portion from above image. I has googling but not found any solution.

Creating a image mask.

If you are rendering the selection area (red) then the solution is simple.

Create a second canvas the same size as the drawing, and don't add it to the DOM. Draw the red marking content onto that canvas

The on the display canvas render the image first and then render that marking canvas over the image with composite mode like "overlay" so that the original image can be seen and the marked areas are red.

Now you have two layers, one is the image and the other the mask you can use to get a copy of the marked content.

To do that create a 3rd canvas, draw the original image onto it, then set the composite mode to "destination-in". Then draw the mask over it. Only the marked pixels will remain.

See the example for more details

 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(); mx = e.pageX - bounds.left - scrollX; my = 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(lx){c=r;r=y;y=ly;l=lx}c.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> 

Already masked.

If the red mask is already applied to the image then there is not much you can do apart from do a threshold filter depending on how red the image is. But even then you are going to have problems with darker areas, and areas that already contain red.

Unless you have the original image you will have poor results.

If you have the original image then you will have to access the image data and create a new image as a mask by comparing each pixel and selecting only pixels that are different. That will force you to same domain images only (or with CORS cross origin headers)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM