All posts by a.philippi

simple and smart surveillance with low budget webcams

Let’s say you want to monitor a room and have a running linux machine(in our case ubuntu) with a webcam attached.

Problems that could appear:

  • Recording continuously for a long period can result in extremely large video files, especially when uncompressed, and a pretty high CPU usage.
  • In the case above you would have to compress and “logrotate” your video streams periodically
  • Maybe you do not want to record anything if nothing happens

Our solution:

$ sudo apt-get install webcam

use the following configuration file (webcam.conf)


[grab]
device = /dev/video0
text = "my office %Y-%m-%d %H:%M:%S"
infofile = filename
fg_red = 255
fg_green = 255
fg_blue = 255
width = 320
height = 240
delay = 5
wait = 0
rotate = 0
top = 0
left = 0
bottom = -1
right = -1
quality = 80
trigger = 175
once = 0
archive = take %Y-%m-%d %H:%M:%S

[ftp]
dir = /path/to/images/temp
file = webcam_l.jpeg
tmp = uploading_l.jpeg
passive = 0
debug = 0
auto = 0
local = 1
ssh = 0

And now run


$ webcam webcam.conf &

Now you will get a JPG image from your webcam (quality = 80) every 5 seconds (delay = 5) but only if something changed. The “something changed”-condition is given by the setting trigger = 175.

Programmatically getting a JavaScript list of current country names

I’ve been working on this great and challenging project for quite a bit now, concentrating on backend development at first,
in the last week or so I’ve moved on to the frontend. The link between the two places should, of course, be a Login / Register
part. I’ve handled login thus far and went on towards registration. Andreas said that a field entailing the user’s country should
be present there as well, albeit in an optional form.

My first reaction was “Oh, I’ll just add a normal select and that’s that” — upon second thought though I winded up choosing the
commonly used UX pattern of Autocomplete . However, in this case, local autocomplete is the name of the game, it makes no
sense to issue AJAX requests all over the place, knowing that a current list of country names should be publicly available.

The quest for this semi-elusive publicly available list of country names was on, and after googling around I’ve found a suitable
site, http://www.foreignword.com/countries/German.htm (listed here in German since we are primarily a German-speaking team).
Please notice that it’s table-based and, “programmer-unfriendly” — no API, no “Copy to Clipboard”, anything.

Having implemented some web scraping for other projects, I thought I’ll just write a Rails method for scraping the site, yet another
interesting solution came up : inject jQuery and manually output a JavaScript Array ! We are indeed “web programmers”, so
why not, should be fun, right ?

Load up the site listed below, your trusty Firebug (or “Inspect Element Tool Thingy” for Chrome / Safari) and check out the code
below.

That would be it, I’ve found another site listing country codes but its table-based (!) structure
was a bit less intuitive (to be read “painful to programmatically read even via jQuery”).

I hope this can help someone at some point :-).

Said and done, thank you for reading up to this point, here is the code :

// Gets Country Names from the ForeignWorld website,
// http://www.foreignword.com/countries/English.htm . May break,
// depending on changes to the layout. Can produce output in other
// languages as well, see on-site links above. Found it quite annoying
// that no API whatsoever was provided so built a quick one myself.

// Relies on appending jQuery and then traversing the DOM to
// get the desired names. Should work for all the languages listed
// within the website.

// Available with Firebug / Safari + Chrome Inspector, perhaps
// Opera Dragonfly as well.

// Wait for jQuery to Load before executing the second part of
// the script. You have to clear out the last comma before
// using the array, was a bit lazy to add that as well.

var out = "[";
jQuery.each(jQuery("tr"), function(idx, elem)
{
  var x = jQuery(elem);
  var y = x.children().nextUntil(".center"); 

  if (y.length)
  {
    var z = y.children("a[target='new']");
    var countryName = z.html();
    if ( (z != null) && (countryName != null) )
    {
      out += "\"" + countryName.trim() + "\"" + ",";
    }
  }
}); 

out += "]";
console.log(out);

ugly but efficient php programming

We have a site. The DirectoryIndex (index.php) redirects the user to the starting page based on the browser language or language cookie.

header("Location: ".$base . $lang."/concept.php");

The SEO problem is that google does not like these redirects. But we have a pretty complex structure there, and changing the way files are included/required means changing everything. And since we will completely replace the entire site in aprox. 4 month time…. we were looking for a “simple solution”.

And, tadaaa – that’s our solution. And it works:

echo file_get_contents($base . $lang."/concept.php");

Further reading: PHP: file_get_contents – Manual

However, this shouldn’t be considered the way to go, unless you really have a good reason to. So do NOT consider it a best practice

create 1px alpha transparent png

We needed a background with opacity x% (where x could vary between 30 and 75). We decided to use a “alpha-transparent” PNG24.

How to generate such a PNG using ImageMagick?
Extremely simple – specify a “8-digit” color code using the syntax:

convert -size 1x1 xc:#123456DD test.png

The last 2 digits in the color code (DD) is the alpha channel(opacity/transparency value).

I also wrote a bash-script that generates 255 images for each value of the alpha-channel for a given color:

#!/bin/bash
#
# generate a directory containing 255 semi-transparent png24-files
# with transparencies from 0 to 100% (0-255) for a given color
# author: Andreas Philippi - Cubus Arts 2010                                                                                                                         
#
                                                                                                                                                                       
#convert(Imagemagick must be installed)
type -P convert &>/dev/null || {                                                                                                                                        
    echo "Imagemagick not found on your system." >&2; 
    echo "Debian/Ubuntu: sudo apt-get install imagemagick" >&2; 
    echo "Centos/Red Hat: yum install ImageMagick" >&2; 
    echo "FreeBSD: pkg_add -r ImageMagick" >&2; 
    exit 1; 
    }

#this script gets 1 parameter: the color code
if [ $# == 0 ]; then
   echo 'Usage: transparent_png_creator.sh ';
   echo 'Example: transparent_png_creator.sh 4F6681';
fi

#check the color code
if ! [[ "$1" =~ ^[0-9,A-F,a-f]+$ ]] ; then
    echo "Invalid color code!! Valid range: 000000 - FFFFFF" >&2; 
    exit 1; 
fi
   

#create the directory 
`mkdir $1`

for i in {0..255}
do
   hex_i=$(printf "%02x" $i)
   convert -size 1x1 xc:#$1$hex_i $1/$1_$hex_i.png
done

echo "Successfully created 255 images in directory $1"

typo3 alpha transparency issue with png_truecolor=1 and libpng2=1

Yesterday night we had the following issue with a typo3 GIFBUILDER object:

While trying to overlay 2 images we lost the alpha-transparency. This happened ONLY if we used [GFX][png_truecolor] = 1.

After hours of “investigations” we managed to create a patch for the file t3lib/class.t3lib_stdgraphic.php that solved our problem. The patch can be found here: http://blog.brasov.cubus.ro/user_uploads/patch_truecolor_png_alpha_transparency.diff

First of all, the relevant configurations:

  • php 5.3.2
  • gdlib 2.0
  • Imagemagick 6.5.7

typo3 configs

  • [GFX][gdlib_png] = 1
  • [GFX][png_truecolor] = 1
  • [GFX][gdlib-2] = 1

excerpt from our typoscript

temp.our_image = IMAGE
temp.our_image.file = GIFBUILDER
temp.our_image.file{
XY = 243,171
transparentBackground = 1

10 = IMAGE
10.file = fileadmin/template/main/pics/img_border.png
10.file.width = 243
10.file.height = 171

20 = IMAGE
20.file.import.field = image
20.file.import = uploads/pics/
20.file.import.listNum = 0
20.file.width = 217c
20.file.height = 150
20.offset = 10,7

The image fileadmin/template/main/pics/img_border.png is has alpha-transparency. The resulting image lost the alpha-transparency when setting [GFX][png_truecolor] = 1 from the install tool.

Our solution was to replace line 3022 in the file t3lib/class.t3lib_stdgraphic.php as follows:

original:
return imagecreatetruecolor($w, $h);

new:
$tmpImg = imagecreatetruecolor($w, $h);
imagealphablending( $tmpImg, false );
imagesavealpha( $tmpImg, true );
return $tmpImg;

And now it works fine.

The patch can be found here: http://blog.brasov.cubus.ro/user_uploads/patch_truecolor_png_alpha_transparency.diff

We filed a bug-report at bugs.typo3.org http://bugs.typo3.org/view.php?id=14602

monitor file and send alert mail on change/modify

For some reasons it can be very useful to be alerted on some specific file changes (for instance a database error log).

Using inotify-tools I wrote a script that can monitor a file sending alerts to an email address if that file is changed:


#!/bin/sh
#
# Monitor file $1 for changes
# Send an alert emai to $2 if file $1 changes
# usage: file_change_mail_alert.sh /var/log/messages your.name@domain.com
#

if [ -z "$2" ]; then
echo "Usage: file_change_mail_alert.sh "
exit 1
fi

#if a inotifywait for this file is already running
if [ $(ps aux | grep inotifywait | grep -c "$1" ) -gt '0' ]; then
echo "A process monitoring the file $1 is already running: $(ps aux | grep inotifywait | grep "$1" )";
exit 1;
fi

#if inotifywait exists
type -P inotifywait &>/dev/null || { echo "Error: This script requires inotifywait(http://wiki.github.com/rvoicilas/inotify-tools/) .... apt-get install inotify-tools ... " >&2; exit 1; }

#if the file exists
if [ -f $1 ]; then

echo "Monitoring file $1 for changes - sending alerts to $2"

while inotifywait -e modify $1; do
sleep 1
changes="$(tail -n5 $1)"
echo "The following change occured in the file $1 : $changes" | mail -s "Change in $1" $2
done
else
echo "Error: File $1 not found"
fi

This script can be started on server startup like this:
/path/to/file_change_mail_alert.sh /var/log/something.log your.email@domain.ro

Or put in in the crontab – once a day (it will exit if it detects that another instance of “itself” is already running)
0 6 * * * /path/to/file_change_mail_alert.sh /var/log/something.log your.email@domain.ro