Search code examples
htmlimage-processingkineticjs

Free form selection using kinetic js and/or html5 canvas


I am looking for some library that can allow my user to do free form selection from uploaded image and get its co-ordinates . Each free form selection will be my one object. For example Image example

This will be my image, I will select complete mat area free-form way and then copy its co-ordinates.

If any other api is available,please tell.

NOTE : Here I am talking about free form selection NOT RECTANGULAR selection . If you are not sure , you can look here here and here


Solution

  • [ Added to answer based on questioner's comment ]

    What you want is edge detection--get ready for some seriously intense coding.

    Here's what Wiki says about a common edge detection algorithm called "marching squares":

    http://en.wikipedia.org/wiki/Marching_squares.

    A nice implimention of marching squares is in d3 (d3js.org).

    http://code.google.com/p/testprogramming/source/browse/trunk/javascript/svg/d3/src/geom/contour.js?r=383

    This implementation is nice because it lets you define what's included & what's excluded in determining your target selection.

    You will need this ability because your selections are not as simple as isolating transparent vs non-transparent pixels.

    For example, to isolate your cat you will first have to limit the search area to pixels near the cat. You can do this using my original answer which makes a new image from a rectangular selection.

    Then you must create an algorithm that includes the range of darker pixels as the cat and excludes the lighter pixels in the chair/floor/wall.

    You will have to become an expert at isolation techniques.

    [ Original Answer ]

    Here's an html5 canvas demo: http://jsfiddle.net/m1erickson/Bc3uK/

    enter image description here

    And here's some annotated code for you to start learning from:

    <!doctype html>
    <html>
    <head>
    <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <style>
        body{ background-color: ivory; }
        #canvas{border:1px solid red;}
    </style>
    <script>
    $(function(){
    
        // canvas related variables
        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");
        var $canvas=$("#canvas");
        var canvasOffset=$canvas.offset();
        var offsetX=canvasOffset.left;
        var offsetY=canvasOffset.top;
        var scrollX=$canvas.scrollLeft();
        var scrollY=$canvas.scrollTop();
    
        // create a temporary canvas
        // used to clip the selected area from the whole image
        var tempCanvas=document.createElement("canvas");
        var tempCtx=tempCanvas.getContext("2d");
    
        var isDown=false;
    
        var $stats=$("#stats");
    
        var cw,ch,startX,startY,mouseX,mouseY
    
        // load and draw the main image on the canvas
        var img=new Image();
        img.crossOrigin="anonymous";
        img.onload=start;
        img.src="https://dl.dropboxusercontent.com/u/139992952/multple/selection.png";
        function start(){
    
            // size the canvas to the image size
            // and draw the image on the canvas
            cw=canvas.width=img.width;
            ch=canvas.height=img.height;
            ctx.drawImage(img,0,0);
    
            // listen for mouse events
            $("#canvas").mousedown(function(e){handleMouseDown(e);});
            $("#canvas").mousemove(function(e){handleMouseMove(e);});
            $("#canvas").mouseup(function(e){handleMouseUp(e);});
            $("#canvas").mouseout(function(e){handleMouseOut(e);});
    
        }
    
    
        function handleMouseDown(e){
    
          // tell the browser we're handling this event
          e.preventDefault();
          e.stopPropagation();
    
          // calculate the current mouse position
          // this is the start position of the drag
          startX=parseInt(e.clientX-offsetX);
          startY=parseInt(e.clientY-offsetY);
    
          // set a flag indicating we've started dragging
          isDown=true;
        }
    
        function handleMouseUp(e){
    
          // tell the browser we're handling this event
          e.preventDefault();
          e.stopPropagation();
    
          // get the current mouse position
          mouseX=parseInt(e.clientX-offsetX);
          mouseY=parseInt(e.clientY-offsetY);
    
          // turn off the drag flag
          isDown=false;
    
          // calc the width/height of the selection
          var w=mouseX-startX;
          var h=mouseY-startY;
    
          // clip the selection and draw it to the temporary canvas
          // then create a new image from the selection
          // and add it to the page
          tempCanvas.width=w;
          tempCanvas.height=h;
          tempCtx.drawImage(canvas,startX,startY,w,h,0,0,w,h);
          var newImage=new Image();
          newImage.onload=function(){
              document.body.appendChild(newImage);
          }
          newImage.src=tempCanvas.toDataURL();
    
        }
    
        function handleMouseOut(e){
    
          // tell the browser we're handling this event
          e.preventDefault();
          e.stopPropagation();
    
          // unset the drag flag
          isDown=false;
        }
    
        function handleMouseMove(e){
    
          // if we're not dragging, just exit
          if(!isDown){return;}
    
          // tell the browser we're handling this event
          e.preventDefault();
          e.stopPropagation();
    
          // calc the current mouse position
          mouseX=parseInt(e.clientX-offsetX);
          mouseY=parseInt(e.clientY-offsetY);
    
          // calc current width/height
          var w=mouseX-startX;
          var h=mouseY-startY;
    
          // display starting/ending drag points and current width/height
          $stats.text("x1/y1: "+startX+"/"+startY+", x2/y2: "+mouseX+"/"+mouseY+", width/height: "+w+"/"+h);
    
          // clear and redraw the canvas showing the current drag rectangle
          ctx.clearRect(0,0,cw,ch);
          ctx.drawImage(img,0,0);
          ctx.strokeRect(startX,startY,w,h);
    
        }
    
    }); // end $(function(){});
    </script>
    </head>
    <body>
        <h4 id=stats>Drag mouse to make selection</h4>
        <canvas id="canvas" width=300 height=300></canvas><br>
    </body>
    </html>