Monday, 15 August 2016

AWS Lambda - Using Image function in a basic web-page

Following on from the previous posting, we're now going to try to use our basic Lambda function which provides a simple HTTP GET method with no parameters and returns JSON with an image in base64 encoding. We're going to make a simple web-page to call the function and display the image.

I'm going to use AngularJS as it just means we don't need to fight with basic HTML and scripting. If you're not familiar, then this or this should give a quick Hello World intro just for what is needed in this example.

First of all we need to think how to get a Base64 chunk of data to show as an image. Thankfully most browsers now support inline images with data URLs. More details can be found here. The format looks like this:

<img src="data:image/png;base64,iVBORw0KGgoAAAANS..." />


Which all seems quite easy. There are some discussions on stackoverflow of where to go from here to link up to JavaScript.

Taking our basic Angular app it's quite a simple matter to add in a button that pushes the base64 data we had previously into a text box and also into the image data:

<!DOCTYPE html>
<html ng-app="TestApp">
<head>
 <script type="text/javascript"
  src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>

</head>
<body>
 <div ng-controller="TestController">
        
        <h1>base64: {{data}}</h1>
    
        <img height="100" width="100" data-ng-src="data:image/png;base64,{{data}}" data-err-src="empty.png"/>

        <button ng-click="click()">GetImage</button>
 </div>
    
 <script>
        angular.module('TestApp', [])
            .controller('TestController', function($scope) {
            $scope.data = "empty";
            
            $scope.click = function() {
                $scope.data = "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";
            };
        });
     </script>
</body>
</html>

Now to get it calling the Lambda service, the $scope.click function can simply be changed to make an http request and put the data into the image. Hey presto!


$scope.click = function() {
    
    var response = $http.get('https://xxxxxxx.execute-api.eu-west-1.amazonaws.com/prod/getImage2');

    response.success(function(data, status, headers, config) {

        $scope.data = data.img;
    });

    response.error(function(data, status, headers, config) {
        alert("Error.");
    });
};

Now, if this isn't working for you, and almost part of the point of this post in itself it means that you have some API Gateway config to get sorted. I must admit first time I went through this there was a bit of head bashing and using fiddler to check that everything was ok.

If everything worked ok up to the previous post and you're getting the base64 data coming back from a browser call then it's sure to be some fun with JavaScript. This is most likely that you have not got CORS setup for your API Gateway binding. Biggest clue here is that you only have a GET method defined in API Gateway and there is no OPTIONS method. AWS makes this pretty easy, so follow the online instructions to configure for CORS.

If you're still having problems and I was bashing my head at this for a while it seems (for me at least) that the default CORS settings from AWS were not working and I needed to manually add in X-Requested-With to the Access-Control-All-Headers  configuration. Remember you'll need to deploy the API again for the changes to take effect. Thanks to this stackoverflow discussion and this one as well for the help.

The other problem I bumped into on this first time round and you'll not have it on the example posted is that if you use the function context.fail(error); in your Lambda to return an error, this will give an http 403 response, not a 200 response, and this is not handled in the basic API Gateway bindings so looks like an error that the service is unavailable. Very confusing!

Thursday, 11 August 2016

65DOS No Man's Sky


Well finally the wait is over. Returning from holiday I was happy to find a package containing the album of tunes by 65DOS inspired by creating the generative soundtrack to the endless universe game No Man's Sky.



Listening to it on the commute it's living up to expectations and continues the journey on from Wild Light. There's been quite a bit of press before (Guardian) and on release Metro and Digital Trends on the approach and challenges to making music this way.

And here's Debutante, the track that kicked off the collaboration:




Thursday, 28 July 2016

Queues.io

I've been reading quite a bit about queuing technology recently as the concepts of event-based processing, enterprise design patterns and scaling backend cloud and integration technologies seem to be using common patterns to build solutions. Apart from the most well recognised ones such as Amazon SQS and RabbitMQ there are quite a lot of other projects to look at and build upon. I stumbled across the excellent queues.io site on my journey which provides an excellent aggregation of the various options and a great jumping off point to investigate further.

Sunday, 26 July 2015

WOMAD 2015: Hannah Peel

Absolutely loved this set.... beautiful voice and wonderfully acoustic music box:

Tainted Love @ WOMAD



Blue Monday






Monday, 2 March 2015

Leverete @ South Street Reading

Saw the fantastic Leverete at South Street Reading on Friday. It was a wonderful gig on Sam Sweeny's birthday with them all very relaxed and intermingling interesting anecdotes along with the music.

Homework from the night:

a) Explore more English folk tunes
b) Play 'small horse' next motorway journey
c) Practice getting an After Eight mint stuck on forehead into mouth
d) Be able to turn an After Eight mint packet inside out


If you don't know about Leverete, here's their intro on YouTube:


And another example of what you can enjoy from them..... buy the album!


Friday, 6 February 2015

The Sound of Space

Radio4 had a wonderful programme last week called the Sound of Space where Dr Lucie Green was joined by a number of cosmologist and astrophysicists who are using the data from space probes to present and give some feeling to the senses and experiences they are having during their interplanetary journeys.

There were some really fascinating eery sounds that are made that much more interesting and meaningful by understanding how they were collected and what effects they are representing. 

Following links from the programme it seems that there is quite a good community who are developing and presenting these sounds that really merits some more exploration.


Thursday, 15 January 2015

Moolodeon - Arduino Midi Melodeon

And next up... I've also been following this one for a while and is another of my favourite projects out there. Lee O'Donnell aka Bassmaker has this great hack of a cheap Chinese import Melodeon that he's dropped an Arduino into along with buttons and a pressure sensor to make a fun little instrument.

Lee also has some excellent pictures showing off the design and the electronics. It's just a little bit of a shame that the source code isn't also posted. Here's some pictures of the construction:


I'm not going to comment more than this as Lee has done such a good job on his site, but here are the YouTube links of it in action.


Lee also has a cracking project explaining his SD Card Midi sample player that generates the fantastic sounds from this instrument. I'll probably blog on that separately later, but check it out!