Creating an Image with Dynamic Text in PHP

As Christmas approaches, many of my friends have begun their countdowns to that wonderful holiday at the end of the year.

One of my friends started her countdown back in August, when she opened up her calendar and had to count the number of days until Christmas and continuously keep track of what day it was and where her count was. I told her that I could spend the 5 minutes to help her out using the power of the internets, and that’s how my Christmas page was born.

Today, I spent a bit more time spicing up the page. It now has a Calvin & Hobbes image that has a bunch of static text, but will update the number of days dynamically.



style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-9705548764325874"
data-ad-slot="6321796284">

To preface: I had no idea how to do this, and found out that PHP has a rather sizeable GD and Image Function library. I used this example to start:

1
2
3
4
5
6
7
8
9
10
11
12
<!--?php 
 
header("Content-type: image/png");
$string = $_GET['text'];
$im     = imagecreatefrompng("images/button1.png");
$orange = imagecolorallocate($im, 220, 210, 60);
$px     = (imagesx($im) - 7.5 * strlen($string)) / 2;
imagestring($im, 3, $px, 9, $string, $orange);
imagepng($im);
imagedestroy($im);
 
?-->

Unfortunately, you can only use some LATIN2 font with imagestring(), and did it fit the style of the Calvin & Hobbes comic I was using, but it was a good start.

In order to load your own font and dictate its size, we can use imagettftext(). I had to include the Comic Sans (Don’t hurt me!) font file in the same folder as the PHP file.

Here is the complete code for my dynamic Christmas image:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!--?php 
// Filename: christmas-image.php
 
header("Content-type: image/png");
$string = $_GET['days'];
$im     = imagecreatefrompng("calvin_resolutions.png");
$black = imagecolorallocate($im, 0, 0, 0);
$font = 'comicsans.ttf';
 
$initialX = '153';
$initialY = '35';
$increaseY = '23';
 
$fontSize = '16';
$fontRotation = '0';
 
$firstline = 'What do you mean';
$secondline = 'there are ' . $string . ' days until';
$thirdline = 'Christmas?! What am';
$fourthline = 'I supposed to do until';
$fifthline = 'then? WAIT?! I am';
$sixthline = 'not a patient man!';
 
//imagestring($im, $font, $px, 20, $string, $black);
imagettftext($im, $fontSize, $fontRotation, $initialX, $initialY, $black, $font, $firstline);
imagettftext($im, $fontSize, $fontRotation, $initialX, $initialY+$increaseY, $black, $font, $secondline);
imagettftext($im, $fontSize, $fontRotation, $initialX, $initialY+($increaseY*2), $black, $font, $thirdline);
imagettftext($im, $fontSize, $fontRotation, $initialX, $initialY+($increaseY*3), $black, $font, $fourthline);
imagettftext($im, $fontSize, $fontRotation, $initialX, $initialY+($increaseY*4), $black, $font, $fifthline);
imagettftext($im, $fontSize, $fontRotation, $initialX, $initialY+($increaseY*5), $black, $font, $sixthline);
imagepng($im);
imagedestroy($im);
 
?-->

The positioning of the text is specific to the Calvin & Hobbes image I used, and I made it easier on myself by creating a variable for the X and Y positions as well as the amount I wanted to push the next lines down.

All you have to do now is refer to the PHP file and pass the variables through the URL.

<img alt="" src="christmas-image.php?days=&lt;?php echo $remainingDays; ?&gt;" />

The PHP file will create a PNG that has the updated text. That was pretty simple, no?

Lessons from Filming a Wedding

Yesterday, I attended Belle and Kevin’s wedding at Hazelton Manor, and they also asked me to help them capture their day with video. I was a nervous train wreck for the entire week leading up to the event because of two reasons: I have never shot a video before, and I love Belle and Kevin to bits and didn’t want to screw up.


Photo: Tim Chong Photography

Well, I survived and I think I did alright. Here’s a list of things I learned about shooting weddings:

  • You will have to fight for position. Chances are that there will be a photographer there, in addition to everyone else who is holding a camera.
  • Get a vest and stabilizer. Weddings are very long, your arms are going to get tired very quickly.
  • Be familiar with your equipment. I have never used a Steadicam Merlin before, and I didn’t have enough time to get it balanced properly, so I couldn’t use it, which sucks!
  • Bring all the wires you could possibly need. I brought a Zoom H4N to record audio, and I got lucky that the DJ had a spare set of XLR wires. I have perfect audio of the reception thanks to him.
  • Scout the venues ahead of time. I didn’t get a chance to take a look at the venue beforehand, and I had to make some really quick choices at the very last minute on how I was going to shoot everything.

Lessons for next time. Working on getting the videos together, but thankfully I can start showing people the video I helped them make to kick off their reception!

Thanks, Steve.

In 2006, I decided to purchase a 13″ white MacBook, the first of its kind to have Intel-based CPUs. My first ever Apple product.

I made this purchase because an Intel-based CPU meant I could dual-boot to Windows, for gaming, and use the OSX side of things for my media-related work.

Fast-forward five years and the machine is still in use, and it still works just as good as the day I got it. That MacBook saw me through all of university, helping me learn the ins and outs of much of the Adobe Creative Suite, learn how to edit videos with Final Cut Pro, and to develop iOS apps. I have since purchased an iMac, an iPhone, an iPad, and a MacBook Air, and it’s not easy to keep my loyalty toward a single tech company.

Steve, you were a legend, a hero, and an amazing role model. It sucks that you left the world so early, but your legacy shall live on through Apple.

As usual, I don’t deal very well with sad news, so I leave you with a bit of humour that I hope will put a smile on your face.

Rest in peace, Steve.

Thanks for having me, New York City

I made a visit to New York City from September 28th to October 1st, and I had a blast. I had dozens of restaurants mapped out, some attractions lined up, and just a plan to enjoy myself and explore a city that I have never had the chance to explore.

We grabbed some tickets from Porter Airlines for 50% off, flew into Newark, and caught the NJ Transit train into New York Penn Station; that was the start of an amazing adventure.

I have compiled a list of things that I have noticed during my time in New York. Hope you find them useful!

  • Pedestrians are quick to jump the light or jaywalk; running yellows (as a car) is dangerous in New York because you never know if you might hit someone who has jumped the light early.
  • The subway system may seem complicated at first, but you can easily learn. I started by looking at the closest subway stations for my destination and looking at what train line it was on, then how would I get onto that train line. The real mistake we made was not realizing that some subway stations aren’t connected on both sides and you MUST use the proper entrance. Google Maps directions will be your friend here.
  • Airbnb is an awesome way to secure a decent apartment for much cheaper than any hotel room you will find in Manhattan. We were minutes away from Times Square, and we had plenty of food options around us as well as subway entrances!
  • Figure out where you want to eat and map them out so you can easily figure out places to eat as you plan your day. However, feel free to just walk down the streets and look for any restaurants that interest you. Walking down 9th street from 40th all the way to 60th, we ran into MANY restaurants that we could have eaten at!
  • Walking is FANTASTIC for discovery. It was a great way to explore the city, find interesting shops and restaurants, and get some much needed exercise. (Much needed because I was stuffing my face.)
  • Many New Yorkers are super kind and helpful people. A lost traveler on the subway asked me for directions, and I really didn’t know much aside from which subway stop he should get off at, but plenty of others jumped in and gave him good directions.
  • Listen to what the street solicitors yell at you; we managed to secure tickets to Avenue Q for almost half the price of retail ticket price, thanks to stopping and listening to what a guy off the street had to say.

New York was a blast to visit, and I definitely want to go back to experience more. Food, shops, shows, what else could you really want out of a city you are visiting?

Thanks for having me, New York.

UPDATE: Here’s a link to the map we used for food: New York City Eats

Games I’m Playing!

One of those things that I get asked semi-often: What games are you playing?

I don’t have all that much time for video games, but I do set aside from some time for gaming because it’s a fantastic outlet for me during really stressful times.

That said, check out my new Games I’m Playing page to take a look at what I am playing!

My Gorillapod is Here!

As some of you know, I am heading to New York City at the end of the month to eat all the food I could possibly eat. However, stabilization while traveling is one of those luxuries that I really never had.

Until now.

Ordered the Joby Gorillapod SLR with bubble level from Amazon a couple weeks back and it finally came today!

Watch out New York, I’m going to do my best to use that sucker on every imaginable surface.

Quit Hijacking My Typos, Rogers.

My fingers are fat and stubby, and they can be a little stupid at times. I’m okay with that. I have learned to love them.

However, while surfing at home, my fat fingers occasionally will enter an incorrect or incomplete typo and take me to an error page. It usually looks like this:

Upon seeing this page, an electronic signal is sent, via your Rogers connection, to the brain of one of their executives. He wakes up from his slumber (their executives are in perpetual slumber, due to being so encumbered from all the money they pilfer) and emits an audible “Yippee!”

Our cute and cuddly little executive then falls back asleep, dreaming of his next pillage and plunder scheme. (“Hey, let’s make a bank!”)

If you don’t want to disturb that executive’s peaceful slumber, feel free to jump onto alternative DNS providers such as OpenDNS and Google. (Thanks Jason, Justin, and Moeed!)

Happy surfing!

Google Spreadsheets: Using COUNT with Multiple Conditions

This past week, I spent a good amount of time analyzing our current customers with PostageApp and figuring out some of the metrics that we use to determine the health of Postage.

Of course, there’s only one tool for the job: a spreadsheet.

Being somewhat familiar with Microsoft Excel, I figured this would be a piece of cake to do on Google Docs Spreadsheets, considering I won’t be doing anything ridiculous. I’d just have to record all of our data and use a bunch of math to figure out some numbers.

Then I hit a snag: I couldn’t count the number of rows if I had more than one condition.

I was using the COUNTIF function to count the number of rows given a specific value inside a column, but it would fail if I tried to do more than one at a time.

I searched for solutions and found quite a few, but many that did not work, especially with Google Spreadsheets. Finally, I stumbled onto a solution: using COUNT with FILTER!

What?

Here’s an example, multiple column data sheet that has some string information along with numeric information:

Let’s say I wanted to get a count of how many rows there were with ‘223’ under the ‘Derp Column’ and ‘Herp’ under the ‘Herp Again’ column. (Don’t ask, I’ve been on Reddit far too much.)

This is the formula you would use to get that count:

1
=COUNT(FILTER(B:B ; B:B=223 ; C:C="Herp"))

The important part here is the FILTER function. The first parameter (B:B)) is the row or column which you are trying to sort through (should be the one you are applying at least one condition on), which in our case is column B (‘Derp Column’), and any other parameters (as separated by the semi-colon) are conditions which you are applying to filter the row. The result should be, of course, 1.

You can be pretty flexible when applying conditions. For example, you can also use this to figure out how many rows have a number greater than 100 in ‘Derp Column’:

1
=COUNT(FILTER(B:B ; B:B&gt;=100))

This is a really neat way to quickly sort and count through data programmatically, and I hope it can be useful to those of you who are using Google Docs Spreadsheets to do calculations like I am! Cheers.

Beauty of a Bride

On July 24th, my friend Belle asked me to help her film her bridal shower, and of course I couldn’t say no to my former LIVE Conference Co-Chair! It was a really fun, cute, and sweet event, makes me really happy to see Belle surrounded by such amazing and dedicated friends and family.

Still learning to shoot with a DSLR, but we’re getting there. Slowly.