Image

Adding timestamps to photos

While working on an Ionic project, the client asked for a timestamp to be added at the bottom of a taken photo.

After some head scratching, I ended up with the solution below.

onTakePhoto(): void {
  const options: CameraOptions = {
    quality: 30,
    destinationType: this.camera.DestinationType.DATA_URL,
    encodingType: this.camera.EncodingType.JPEG,
    mediaType: this.camera.MediaType.PICTURE,
    targetWidth: 2304,
    targetHeight: 1728
  };

  this.camera.getPicture(options).then(
    (imageData) => {
      this.generateImageWithTimestamp("data:image/jpeg;base64," + imageData);
    },
    (error) => {
      // not important now
    }
  );
}

generateImageWithTimestamp(dataUrl: string): void {
  let image = new Image();
  image.onload = () => {
    let canvas = document.createElement("canvas");
    let context = canvas.getContext("2d");

    canvas.height = image.height;
    canvas.width = image.width;

    context.drawImage(image, 0, 0);

    //adding some styling
    context.font = "80px Arial bold";
    context.textAlign = "center";
    context.fillStyle = "orange";
    context.fillText(
      this.getTimeStamp(),
      image.width / 2, //center
      image.height * 0.97 //close to the bottom
    );

    const finalImage = canvas.toDataURL("image/jpeg", 1);
  };
  image.src = dataUrl;
}

getTimeStamp(): string {
  const date = new Date();

  return `${date.getDate()}. ${date.getMonth() +1}. ${date.getFullYear()}, ${date.getHours()}:${date.getMinutes()}`;
}

We simply take a photo, redraw it on a canvas where we also add the timestamp.

One thing to keep in mind here is that order is important.

In my first attempt I first added the text and then the image which, of course, has overwritten the text. It looks obvious now but it took me a little to figure it out.

Hope this will help you out.

Until next time,
Happy coding.

Showing image only when fully loaded (Angular 1)

While working for a client, a requirement came up requesting for images only to be visible when fully downloaded.

The reason for this is that currently the images would load line by line which doesn't look quite nice. 

I started playing around a little but nothing worked as I would have liked, so I had to go deeper.

inceptius-meme-generator-we-have-to-go-deeper-014848.jpg

Directives to the rescue!

I ended up creating a new directive and hooked it up in my markup.

//.js
angular.module('app', [])
.directive("dynamicImage", function () {
  return {
    restrict: 'E', //restrict only to elements
      scope: {
        imageSource: '=src' //hook up to the outside scope
      },
      template: '<img ng-show="showImage" src="{{ imageSource }}">',
      //get the element and bind to the load event
      link: function ($scope, iElm, iAttrs, controller) {
        $scope.showImage = false;
        iElm.find('img').bind('load', function (e) {
        //when loaded show the image            
        $scope.$apply('showImage = true');
       });
    }
  }
});

//.html
//keep in mind that you don't need interpolation here
//so pass only the property without the '{{}}'
<dynamic-image src="propertyHoldingTheImageSource"></dynamic-image>

If you try it out now you won't see the image until fully loaded. 

To enhance the user experience a little more you can add a background image to the parent <div> which can serve as a placeholder but this is a topic for another time :)

Until then, happy coding!