Javascript: Using Canvas to cut an area of an image

Over the few weeks I’ve been working on a Canvas based side project (more on that soon) that involved cutting a mask out of a source image and placing it on a Canvas. In Photoshop parlance, this would be similar to creating a clipping mask and then using it to extract a path from the image into a new layer. So visually, we’re looking to achieve something similar to:

At face value, it looks like doing this with Canvas is pretty straightforward using the getImageData function. Unfortunately, if you look at the parameters that function accepts it’ll only support slicing out rectangular areas which isn’t what we’re looking to do. Luckily, if you look a bit further in the docs it turns out Canvas supports setting globalCompositeOperation which allows you to control how image data is drawn onto the canvas. The idea is to draw the mask on a canvas, turn on the “source-in” setting, and then draw on the image that you want to generate the slice off. The big thing to note here is that putImageData isn’t effected by the globalCompositeOperation setting so you have to use drawImage to draw the mask and image data.

So concretely how do you do this? Well check it out:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>

    <link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700,800' rel='stylesheet' type='text/css'>
    <link href='http://fonts.googleapis.com/css?family=Lato:400,700,900' rel='stylesheet' type='text/css'>
    
    <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
        
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="bootstrap/js/bootstrap.min.js"></script>
    <script src="underscore-min.js"></script>    
    <script src="fabric.min.js"></script>
    
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->    
  </head>
  <body>
  
  <canvas id="target" width="800px" height="400px" style="margin: auto"></canvas>
  
  <script>
  
  $(document).ready(function(){
      
      var mask = new Image(), bg = new Image();
      var mDf = $.Deferred(), bgDf = $.Deferred();
            
      mask.src = "grass_overlay.png";
      bg.src = "grass_texture.png";
      
      mask.addEventListener("load", function(){ mDf.resolve(this); });
      bg.addEventListener("load", function(){ bgDf.resolve(this); });
      
      var canvas = document.createElement("canvas"), ctx = canvas.getContext('2d');
      var target = document.getElementById("target"), targetCtx = target.getContext('2d');
      
      
      $.when(mDf, bgDf).done(function(){
          var l = (bg.width / 2) - (mask.width / 2), t = (bg.height / 2) - (mask.height / 2);
          
          canvas.width = bg.width;
          canvas.height = bg.height;
          
          ctx.drawImage(mask, l, t);
          ctx.globalCompositeOperation = "source-in";
          ctx.drawImage(bg, 0, 0);
                 
          var imageData = ctx.getImageData(l, t, mask.width, mask.height);                                       
          targetCtx.putImageData(imageData, 50, 50);                         
      });
      
  });
  
  </script>
  
  </body>
</html>

The code is running over at http://symf.setfive.com/canvas_puzzle/grass.html if you want to see it in action.

Anyway, happy canvasing!

Fun: Sending Valentines day cards with lob.com

A couple of months ago I ran across the lob.com API on ProgrammableWeb and was intrigued. One of the features of the Lob API is that it allows you to programmatically send postcards by just providing address details and images. I’d been itching to find a use case for the API since who doesn’t love physical mail? Following a few beers on a snow day an idea struck - why not send Valentines day postcards with lob!

Overall, the idea was straightforward, allow users to compose a message on one of a few available templates, enter some address details, and then send their postcard. Given the short timeline and relatively few features, the main factors behind picking an implementation stack were something “lightweight” that I was already comfortable with. After drawing up some options I decided to use Silex since it’s based on Symfony components, it’s lightweight, and we’ve used it in the past.

The main UI for the cards ended up looking like:

One of the “fun” features I did implement was that instead of using a big header background image, I used a HTML5 Canvas to render frames from Beauty and the Beast as the page’s background.

Anyway, we might bring this back next year so be on the lookout around Valentines day.

Scala: Fun with Parser Combinators

A couple of months ago I decided to use Scala with the Play Framework for a Bitcoin related project. The decision to use Play was motivated primarily by the goal of implementing a “pure” Bitcoin application, leveraging bitcoinj to interact with the Bitcoin network as opposed to a third party service. Overall, everything was pretty straightforward but one thing that stuck out was how the Play framework handles parsing JSON.

Coming from loosely typed PHP I knew that handling serializing and unserializing of JSON data was going to be different but Play’s approach is a completely new paradigm. If you use Play with Scala, you can handle parsing JSON input back into objects using Scala’s Parser Combinators syntax. I’m going to butcher this description so check the wikipedia entry but the idea is that parser combinators let you “build up” increasingly complex parsers by combining functions that recognize smaller inputs. If you’ve taken a compilers or programming language class, Scala’s parser combinators end up looking a lot like Backus–Naur Form for the input you want to recognize.

Anyway in an effort to learn Scala a bit better and take Parser Combinators for a spin I decided to build out a small project. What I ended up building is a really simple implementation of a Turtle Graphics system. You basically feed it a series of “turtle” commands and it’ll move the “turtle” around on a Swing window drawing some graphics.

Here’s an examples of the input and output:

Which was generated by:

setpos 200 200
pendown
up 100 right 100 down 100 left 100 penup
setpos 400 200
pendown
up 100 right 100 down 100 left 100 penup
setpos 340 225
pendown
down 125 right 20 up 125 left 20 penup
setpos 200 375
pendown
repeat 9 [down 10 right 15]
repeat 2 [right 15]
repeat 9 [up 10 right 15]

Overall, parser combinators seem to be a really powerful Scala feature that would make developing domain specific languages relatively straightforward. Compared to messing around with a parser generator, using parser combinators seems to more closely mirror what the formal grammar of a language would be.

The entire project is available on GitHub. If you clone that project, there’s a runnable JAR which you can run with:

java -jar logoparser.jar /home/ashish/workspace_java/logo-parser/samples/face.txt

You’ll need to provide an absolute path for the “filewatcher” to work. Once the app starts, if you modify the file you specify it’ll repaint the canvas with your updates. Note: I’m not sure why but certain text editors don’t seem to register in the Java “filewatcher” interface so if your updates aren’t showing up try using a different editor.

Anyway, as always I’d love any feedback!

Coding: How do you approach an engineering problem?

As a team last week we decided to work through a “Coding Kata” as a learning experiment. For those unfamiliar with the concept, a Kata is a Japaneese word that refers to a choreographed series of movements. In the context of programming, a Kata refers to repeatedly solving a problem with incrementally improving technique. The challenge we decided to look at was a somewhat contrived Bank OCR problem described on codingdojo.org.

We only looked at “User Story 1” which describes a process for translating lines of ASCII text into the decimal numbers which they represent. The task isn’t particularly hard but what we were interested in was how different people approached the problem, what considerations they had, and where they got hung up. As a group, the consensus approach was to decompose the problem into pieces, decide on data structures, and then sketch out some pseudo code.

  • Breaking down the problem is fairly straightforward. We're basically looking to read in the file, separate the lines into the "bank numbers", recognize individual numbers, and then combine the numbers we've recognized. An additional benefit of approaching the Kata like this was that individual team members could craft solutions in different programming styles - imperative, functional, etc.
  • Once we had the "big" pieces of the solution, the next thing we flushed out was which data structures to use. After some discussion it was clear that reading the file and recognizing the numbers were related and the data structures used would need to be related. Interestingly, there was a decent amount of debate around what to use to represent the read lines and then how to match them. The team was split between using a 3x3 array versus using a 9 character string.
  • The final step we took was jotting down some pseudo code on a whiteboard to actually perform all the steps. I've always found it interesting to watch people code on a whiteboard and this time wasn't any different. Our team seemed to struggle with visualizing what the data looked like and also how much detail to convey in the pseudo code.

After we wrapped up on the whiteboard we ended up implementing 3 solutions. A functional solution using a 3x3 array for the numbers, an imperative solution also using a 3x3 array, and an imperative solution using a 9 character string to represent the numbers. The solutions are similar but the style of the original author still definitely comes through.

Anyway, how would you have approached a problem like this? We’d love to hear in the comments!

Friday Links: RDMS, Bitcoin, and Facebook

Congrats! You’ve survived the first full work week of 2015. Hopefully your resolutions are still intact and if they’re not there’s always next year. Shockingly informational links ahead so hold on to your hats.