Add Outline Text to an Image using Imagemagick

outlined-text-image

Very often you see images with a quote added to it, sometimes funny, sometimes informational. Adding solid font to an image is quite easy but I didn’t know how to add outlined font (font with a border) to an image. Example of outlined font can be seen in the image below – Original image on the left, quoted image on the right.

smriti-irani-outline

Such things are easily done in Photoshop and on Gimp if you’re on Linux. However, being a fan of the command line, I always try to find an alternative solution which doesn’t involve the usage of a GUI based application. After some research, I figured out how to do it with Imagemagick.

It is a two step process – First create the transparent image with the text that you wish to super-impose on the image, and then use the composite command to merge this image created in the first step with the original image.

For the first step:

convert -background transparent -channel RGBA -gaussian 0x1 -fill white -stroke black -strokewidth 1 -font /home/pratik/.fonts/Unkempt/Unkempt-Bold.ttf -size 720x -pointsize 63 -gravity center -interline-spacing 8 label:"Smriti Irani on being told\n that someone got arrested\n for a fake degree." empty.png

To create the outline effect, we set the -fill option to white and then we create a border for the font using the -stroke option which is set to black. -strokewidth controls the width of the border. This lets us create alphabets with a black border and white solid colour within.

Using label as opposed to -annotate option of imagemagick lets you add newline characters within the text as you can see above. The -size option is used to set the width of the textual image that we want to create. It should be typically set to the width of the original image which can be determined using the identify command. The -gaussian option is used to give a slight blurred effect to the text. You can use any font you wish to, I’m using the Unkempt font available on the Google Font Repository.

The resultant image looks like this:
outlined-text-image

The next step is to merge the above image with the original image (below).

smriti-gun

We will use the composite command which also comes as part of the imagemagick suite for this purpose.

composite -gravity center outlined-text-image.png smriti-gun.jpg smriti-outlined.jpg

The desired result can be seen below:

smriti-outlined

man convert is your goto friend to understand what are the various options used in the first command to create the outlined text image.

Do leave a comment if there any questions or suggestions.

Compile and Install OpenCV 3.0.0 on Ubuntu 14.04

OpenCV 3.0 was released yesterday. I have been using OpenCV for a couple of weeks now for a project that involves face recognition. To compile the latest and greatest version of OpenCV on Ubuntu, here’s what you need to do.

Download the latest version of OpenCV => https://codeload.github.com/Itseez/opencv/zip/3.0.0

Install all the dependences:

sudo apt-get install zlib1g-dev libjpeg-dev libwebp-dev libpng-dev libtiff5-dev libjasper-dev libopenexr-dev libgdal-dev  libdc1394-22-dev libavcodec-dev libavformat-dev libswscale-dev libtheora-dev libvorbis-dev libxvidcore-dev libx264-dev yasm libopencore-amrnb-dev libopencore-amrwb-dev libv4l-dev libxine2-dev  libtbb-dev libeigen3-dev python-dev python-tk python-numpy python3-dev python3-tk python3-numpy

Unzip the OpenCV zip file, create a build folder

unzip /opencv-3.0.0.zip
cd opencv-3.0.0
mkdir build
cd build

Run cmake so as to create the Makefile.

cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=$(python3 -c "import sys; print(sys.prefix)") -DWITH_QT=ON -DWITH_OPENGL=ON -DWITH_VTK=ON -DWITH_TBB=ON -DWITH_GDAL=ON -DWITH_XINE=ON -DBUILD_EXAMPLES=ON -D BUILD_opencv_java=OFF BUILD_opencv_test_java=OFF  ..

Since I do not need Java bindings for OpenCV and they were giving some errors, I have disabled them in the above cmake command. For those who need Java, might have to do some digging vis-a-vis getting OpenCV to compile with Java.

Compile OpenCV

make -j4

Choose -j2 or -j4 depending on how many cores your processor has. Skipping the -j and utilizing just a single core for compilation works too.

Install OpenCV. I use checkinstall to create a deb package instead of doing a direct make install. That lets you cleanly uninstall OpenCV whenever required, especially when Ubuntu upgrades its own version to 3.0.0.

sudo apt-get install checkinstall
sudo checkinstall

The installation procedure using checkinstall is shown below

@build$ sudo checkinstall

checkinstall 1.6.2, Copyright 2009 Felipe Eduardo Sanchez Diaz Duran
           This software is released under the GNU GPL.


The package documentation directory ./doc-pak does not exist. 
Should I create a default set of package docs?  [y]: n

*****************************************
**** Debian package creation selected ***
*****************************************

This package will be built according to these values: 

0 -  Maintainer: [ root@sony ]
1 -  Summary: [ opencv ]
2 -  Name:    [ release ]
3 -  Version: [ 20150605 ]
4 -  Release: [ 1 ]
5 -  License: [ GPL ]
6 -  Group:   [ checkinstall ]
7 -  Architecture: [ amd64 ]
8 -  Source location: [ release ]
9 -  Alternate source location: [  ]
10 - Requires: [  ]
11 - Provides: [ release ]
12 - Conflicts: [  ]
13 - Replaces: [  ]

Enter a number to change any of them or press ENTER to continue: 2
Enter new name: 
>> opencv

This package will be built according to these values: 

0 -  Maintainer: [ root@sony ]
1 -  Summary: [ opencv ]
2 -  Name:    [ opencv ]
3 -  Version: [ 20150605 ]
4 -  Release: [ 1 ]
5 -  License: [ GPL ]
6 -  Group:   [ checkinstall ]
7 -  Architecture: [ amd64 ]
8 -  Source location: [ release ]
9 -  Alternate source location: [  ]
10 - Requires: [  ]
11 - Provides: [ release ]
12 - Conflicts: [  ]
13 - Replaces: [  ]

Enter a number to change any of them or press ENTER to continue: 3
Enter new version: 
>> 3.0.0

This package will be built according to these values: 

0 -  Maintainer: [ root@sony ]
1 -  Summary: [ opencv ]
2 -  Name:    [ opencv ]
3 -  Version: [ 3.0.0 ]
4 -  Release: [ 1 ]
5 -  License: [ GPL ]
6 -  Group:   [ checkinstall ]
7 -  Architecture: [ amd64 ]
8 -  Source location: [ release ]
9 -  Alternate source location: [  ]
10 - Requires: [  ]
11 - Provides: [ release ]
12 - Conflicts: [  ]
13 - Replaces: [  ]

Enter a number to change any of them or press ENTER to continue: 

Installing with make install...

========================= Installation results ===========================
[  1%] Built target opencv_hal_pch_dephelp
[  1%] Built target pch_Generate_opencv_hal
[  2%] Built target opencv_hal
[  2%] Built target opencv_core_pch_dephelp
[  2%] Built target pch_Generate_opencv_core
.
.
.

At the end, a deb package (opencv_3.0.0-1_amd64.deb) will be created in the build directory while opencv will be installed as well. You can save the deb package in a different directory for future use. In my case, I had already uninstalled the default version of opencv so as to avoid conflicts.

If there are any questions regarding the procedure, please do feel free to comment.

Find a Network Interface Mac Address Programatically on Linux

Using the Mac Address of Network Interfaces in programs is a common requirement. The old age way of getting the mac address programatically on linux was to parse the not-so-machine-friendly ifconfig output. However with the sysfs file system mounted under /sys, accessing information from kernel sub-systems has become very easy.

e.g. The Mac Address of eth0 interface can be accessed by reading the /sys/class/net/eth0/address file.

Wlan0-Eth0-Address-Programatically-sysfs

The code below is an example of how to use parse this information from within a C program.

#include <stdio.h>
#include <string.h>
#include <stdint.h>

int mac_get_ascii_from_file(const char *filename, char *addr) {
  FILE *fp;
  int i = 0;
  char c;
  fp = fopen(filename, "r");
  if (fp != NULL) {
    while (!feof(fp)) {
      c = fgetc(fp);
      if (c == ':')
        continue;
      if (c == '\n')
        break;
      addr[i++] = c;
    }
  }
  fclose(fp);
  return 0;
}

int mac_get_binary_from_file(const char *filename, uint8_t * mac) {
  int status = 1;
  char buf[256];
  FILE *fp = fopen(filename, "rt");
  memset(buf, 0, 256);
  if (fp) {
    if (fgets(buf, sizeof buf, fp) > 0) {
      sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &mac[0],
             &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
      status = 0;
    }
    fclose(fp);
  }
  return status;
}

int main(void) {
  char macaddr[13];
  uint8_t mac[6];
  memset(macaddr, '\0', 13);
  mac_get_ascii_from_file("/sys/class/net/eth0/address", macaddr);
  printf("My Mac Address - %s\n", macaddr);
  mac_get_binary_from_file("/sys/class/net/eth0/address", mac);
  printf("My Mac Address - %hhx:%hhx:%hhx:%hhx:%hhx:%hhx\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  return 0;
}

The sample output of the above program is shown below.

Output-of-macaddr-program

Using gatttool in a manual/non-interactive mode to read BLE devices

Gatttool is a tool distributed along with Bluez, the default linux bluetooth stack, to interact with Bluetooth Low Energy (BLE) devices. Currently I have a TI SensorTag with me for a project I’m working on and I’m playing around with it. Most of the examples on the internet which show how to use gatttool to read the TI Tag have shown how to use gatttool in its interactive mode (-I). For eg, to read the temperature sensor, you’d do the following using gatttool’s interactive mode

@~ $ sudo gatttool -b BC:6A:29:AE:CC:23 -I
[   ][BC:6A:29:AE:CC:23][LE]> connect
[CON][BC:6A:29:AE:CC:23][LE]> char-read-hnd 0x25
[CON][BC:6A:29:AE:CC:23][LE]> 
Characteristic value/descriptor: 00 00 00 00 
[CON][BC:6A:29:AE:CC:23][LE]> char-write-cmd 0x29 01
[CON][BC:6A:29:AE:CC:23][LE]> char-read-hnd 0x25
[CON][BC:6A:29:AE:CC:23][LE]> 
Characteristic value/descriptor: f0 fe 88 0e 
[CON][BC:6A:29:AE:CC:23][LE]> exit

However gatttool also offers a non-interactive mode which hasn’t been documented. To achieve the above result in manual, non-interactive mode, you would do the following;

@$ sudo hciconfig hci0 down; sudo hciconfig hci0 up
@$ sudo gatttool -b BC:6A:29:AE:CC:23 --char-read -a 0x25; sleep 1; sudo gatttool -b BC:6A:29:AE:CC:23 --char-write -a 0x29 -n 01; sleep 1; sudo gatttool -b BC:6A:29:AE:CC:23 --char-read -a 0x25; 
Characteristic value/descriptor: 00 00 00 00 
Characteristic value/descriptor: 36 ff 68 0e

Loading a Linux Library from a different path – LD_PRELOAD

During the course of development, sometimes one needs to load a specific library from a specific path instead of the stock library that comes installed with the linux operating system. In such cases, LD_PRELOAD is a useful tool.

For example, my Ubuntu 14.04 laptop has the Bluez (linux bluetooth stack) version 4.101-0ubuntu13 installed by default. Thats a pretty old one. Since I wanted to use a newer version of the library for a project of mine and I didn’t want to overwrite my stock library, I installed the newer version (5.19) in a dedicated directory i.e. /home/pratik/Developer/CL/bluez-5.19-install. As a result, the newer version of the library resided at /home/pratik/Developer/CL/bluez-5.19-install/lib/libbluetooth.so.3. So now how do I explicity make a binary which is dependent on the bluetooth library use the one installed at the above mentioned location?

Trick is to use LD_PRELOAD. For eg. If I’m running a program called ‘a-bluetooth-program’ and I want to run it against the new library, this is what I do.

LD_PRELOAD=/home/pratik/Developer/CL/bluez-5.19-install/lib/libbluetooth.so.3 a-bluetooth-program

How do I know the trick is working? Of course by using ldd.

@$ LD_PRELOAD=/home/pratik/Developer/CloudLeaf/bluez-5.19-install/lib/libbluetooth.so.3 ldd st
	linux-vdso.so.1 =>  (0x00007fffe1ee9000)
	/home/pratik/Developer/CloudLeaf/bluez-5.19-install/lib/libbluetooth.so.3 (0x00007f1b5286f000)
	libncurses.so.5 => /lib/x86_64-linux-gnu/libncurses.so.5 (0x00007f1b52628000)
	libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f1b523fe000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1b52038000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1b51e34000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f1b52a90000)

If you look at the output of ldd command which is used to print the shared libraries required by a command, you will see that st is now linking to the newer version of the library.

Fix ‘Skype Always Online’ Problem

Every since Microsoft bought off Skype, they have decided that they are NOT going to let you go offline. Thats how much they love you being online. So well, you have to knock off Microsoft from your Skype account to be able to go offline.

  • Log on to your Skype online account settings => https://secure.skype.com/portal/account/settings
  • Unlink the Microsoft Account. Once unlinked, your Account settings page will look like the screenshot below.
    Skype-Always-Online-Problem
  • In a few seconds, knocking Microsoft out of your Skype account should bear results.
  • Follow suit for other (IT) problems in your life. Say no to Microsoft.

Sniffing Unix Domain Sockets

Usually wireshark is used to sniff packets traversing a network. But how does one sniff a unix domain socket? Using socat as a proxy is a neat trick to capture packets traversing a unix socket.

In the below command, /tmp/originalsocket is the socket the Unix Socket Server is listening on, while /tmp/duplicatesocket is the socket that the unix client should connect to. socat will dump all the transactions that go on in a hexadecimal format

sudo socat -t100 -x -v UNIX-LISTEN:/tmp/duplicatesocket,mode=777,reuseaddr,fork UNIX-CONNECT:/tmp/originalsocket

Multiple Github Accounts and SSH Keys

Besides my regular Github freethinker account, I had to create a new github account for my new job. Problem was how to manage different ssh keys for different github accounts as Github doesn’t allow the same key for more than one account. The Solution is:

1) Create a new alias for github.com in the ~/.ssh/config file.

Host GitHub-readme
  Hostname=github.com
  IdentityFile=~/.ssh/id_rsa_alt

This alias still points to github.com but when you ssh into github using the new alias, it will use the alternative SSH key. It should be noted that Github recognizes you not by your username but by your ssh key.

Before you go on, do remember to ssh-add the key.

ssh-add ~/.ssh/id_rsa_alt

To verify whether the ssh key has been added or not

ssh-add -l 

2) Next, lets verify if our new configuration works with github. To do so, execute ssh -T git@GitHub-readme, where GitHub-readme is the new alias we created in step one with an alternative ssh key.

@~ $ ssh -T git@GitHub-readme
Hi pratikreadmesys! You've successfully authenticated, but GitHub does not provide shell access.

3) Finally either clone a new repository or edit the .git/config of your present repository. Use the new alias that we created in step 1 instead of ‘github.com’ in the command line.

git clone git@GitHub-readme:ReadmeSystemsInc/testrepository.git

Alternatively if you have already checked out the repository, update the remote URL.

[remote "origin"]
  url = git@GitHub-readme:ReadmeSystemsInc/testrepository.git
  fetch = +refs/heads/*:refs/remotes/origin/*