Reputation: 341
I have overlay image with rectangle transparent hole. Beneath is scalable and draggable image. How to cut only visible part of image ?
How to determine size and position of transparent rectangle ? Is it possible to do pixel by pixel alpha channel search only on overlay image ?
Any other ideas ?
EDIT:
Solution to another quoted problem is usefull, although it works only on whole canvas not on individual items like background, overlay or added images or shapes. Is it possible to read pixel values on individual fabric elements ?
I use overlay image as external png files.
Upvotes: 6
Views: 2835
Reputation: 105035
The FabricJS API does not include a method to fetch the pixel values of an image.
You will have to draw your overlay image onto an html5 canvas and use getImageData
to fetch the pixel data from that canvas.
getImageData().data
contains the red, green, blue & alpha information for each pixel on the canvas.
You can test each pixel's alpha value and determine the minimum & maximum boundary of the transparent rectangle.
Here's example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image();
img.crossOrigin='anonymous';
img.onload=start;
img.src="http://masterblocks.co.in/static/img/logo.png";
function start(){
cw=canvas.width=img.width;
ch=canvas.height=img.height
ctx.drawImage(img,0,0);
// clear a test rectangle
ctx.clearRect(100,100,100,75);
// get clear rect bounds
var bounds=findCutoutBounds();
// test: stroke the bounds
ctx.lineWidth=2;
ctx.strokeStyle='red';
ctx.strokeRect(bounds.x,bounds.y,bounds.width,bounds.height);
}
// Get the imageData of that canvas
function findCutoutBounds(){
var minX=1000000;
var minY=1000000;
var maxX=-1;
var maxY=-1;
var data=ctx.getImageData(0,0,canvas.width,canvas.height).data;
for(var y=0;y<ch;y++){
for(var x=0;x<cw;x++){
var n=(y*cw+x)*4;
if(data[n+3]<5){
if(y<minY){minY=y;}
if(y>maxY){maxY=y;}
if(x<minX){minX=x;}
if(x>maxX){maxX=x;}
}
}}
return({x:minX,y:minY,width:maxX-minX,height:maxY-minY});
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<h4>The bounding box of the transparent rectangle is stroked in red</h4>
<canvas id="canvas" width=300 height=300></canvas>
Upvotes: 5