Nick Tomlin

Front-End Development from Chicagoland

Replacing Common Photoshop Workflows With ImageMagick

Permalink

Photoshop is a wonderful tool, but it tends to require mousing (even with shortcuts), likes to eat up as much RAM as possible, and doesn’t play nice with bash scripts. Thats why I prefer Image Magick: a quirky, insanely full-featured CLI image manipulation library. I’ll run through some examples of using it do a few common tasks that I previously used photoshop for, such as:

  • Identify the size/type of image
  • Convert image types
  • Resize images to a maximum width/height
  • Reduce image filesize
  • Trim Whitespace
  • Create new images from scratch
  • Add borders

Example Repository

If you want to follow along, i’ve created an example repository with some source files. I’ll be referencing them through the post.

Installation

Mac Os X

Mac users can (and should) use brew :

brew install imagemagick

Linux

Most linux distributions should have the imagemagick package available by default.

For Ubuntu:

apt-get install imagemagick

There be dragons: Mogrify Vs. Convert

One important thing to cover before we start slicing and dicing images is that IM has two major methods for manipulating images: convert and mogrify. Convert takes a source file, makes whatever changes you desire to it and ouptus them to a file you specify. Mogrify only accepts one file, and makes all changes on that file (unless you specify a destination directory). mogrify has a simpler syntax for performing batch operations on images, but that elegance comes with the potential of deleting precious content. There’s an example of how to handle batch operations using both commands in the “resize” section later on. For now, just be warned that mogrify will write any changes you make to the original files. Back up early; back up often.

Identify the size and type of images

identify is great for getting a quick overview of an image’s properties.

Our example’s source file includes an image file named 300, which i’ve nabbed from PlaceKitten. Photoshop doesn’t know what to do with the image, because it is missing an extension, and while we could try and guess the extension by renaming the file to (gif|png|jpg) and seeing what happens, but it’s cooler (and faster) to use the identify command to figure things out:

identify 300 300 JPEG 200x200 200x200+0+0 8-bit sRGB 8KB 0.000u 0:00.009

Ah, a jpeg. I suspected it all along.

Formatting identify’s output

The default output of the identify command is a little verbose for my taste. We can trim it down by using IM built in -format escapes

 # Print the name, and dimensions of the file named 300
  identify -format "Name: %f Dimensions: %P Type: %m" 300 

Batch identification is simple with your shell’s built in globbing:


  # '*' will get you more than you ask for, so it's best to narrow
  # things down based on the file structure you are dealing with
  identify *

Convert image formats

Imagemagick’s powerhouse is the convert command. You can use it to do almost anything you can imagine through some terrifyingly complex flags. We’ll try to keep things simple : )

Convert from tiff to jpg

Image magick can effortlessly convert images between various formats. A problem one of my coworkers ran into recently involved clients needing images in the tiff format. Photoshop can do batch operations, but the process is clunky, and — in my experience— unreliable.

Single Images:

  • convert convert.tiff kitten.jpg Simple, no?

Multiple Images:

  • destroying the original image:
    • mogrify mogrify --format tiff *.jpg
  • retaining the original image, the mogrify command can be used with the -path flag
    • mogrify --format tiff -path converted *.jpg
    • The path (in this case the ‘converted’ directory) must exist, or IM will complain
    • Make sure that this path is different than the files you are using mogrify on, or they will be overwritten.
  • retaining the original image, you can use a longconvert statement (see batch resizing below).

Resize images

Simple Resize

convert kitten.jpg -resize 80% resized-kitten.jpg

Batch Resizing

Clients rarely have a images in a uniform, web-optimized format, and even if they do I usually need need two copies: retina-ready images, and images for us normal folks. ImageMagick makes generating those a snap.

In our resize/batch folder:

convert *.jpg -resize 80% -set filename:f '%t@2x' '%[filename:f].jpg'

Here we are resizing all jpg images by 80%, setting the filename the filename %t plus the string @2x to follow apple’s convention for retina images, and then outputting the file. The syntax is a little esoteric (more details on that here), but once you get the hang of it it can be quite useful.

We can now run mogrify !(*@2x).jpg -resize 40% to cut the non retina images down to size (note, this will “destroy” the original images – I have a backup handy).

Resizing to a maximum pixel width

If you have do not have a specific size for your images, but want to keep things small, you can use the following syntax:

In our resize folder, there is a max width image. Running identify gives us the following:

max-width.jpg JPEG 408x287 408x287+0+0 8-bit sRGB 15.8KB 0.000u 0:00.000

Let’s resize that to a max width of 200px:

convert max-width.jpg -resize 200\> max-width-resized.jpg

One special thing to note is the icky need for the \ in \>. This is necessary to escape to prevent your shell from interpreting that as an output redirection >.

Replacing “save-for-web” and reducing file size with -strip

When resizing images (especially large images), you may notice that the file size of the images does not decrease as much as you might expect. This is typically due the meta-data and other kruft that may come attached to your image file. Using the -strip flag on any IM operation will remove this data, which, in my experience, typically results in a 10-30% reduction in size.

In our trim folder: convert -strip strip.jpg stripped.jpg

Use identify to compare the file sizes. Not a huge reduction (this image is pretty slim already), but imagine those percentage savings being applied to a larger image.

Obviously, Photoshop’s “Save for web” combines resizing and optimizing functions, but you can too.

convert sample.png -strip -resize 80% optimized.png

Borders

Add a 5px black border to an image.

In our borders folder:

convert kitten.jpg -bordercolor '#000' -border 5 bordered.jpg

Trim Whitespace

My jaw dropped when I first found out about this command (thanks to this brilliant gentleman)

In our trim-whitespace folder

convert trim.png -trim trimmed.png

Unfortunately, for images with gradients, or subtle transitions between subject/background, the results are not quite as spectacular:

convert not-quite-trim.jpg -trim not-quite-trimmed.jpg

Will output an image that still has a background bleed :(

Create Images from the command line

Imagemagick can also help you with bespoke iamges as well, if you need some filler content and can’t use a service like placehold.it or (my favorite) placekitten.com.

To create a simple gray (usinga hex value), sized 100x100 you can use the convert command.

  • Solid Color: convert -size 100x100 canvas:#a19c9e canvas.png (note, you may need to quote/escape hex colors, as your shell may try glob them)

  • Gradient: convert -size 100x100 gradient:#a19c9e-#000000 canvas.png

  • Pattern: convert -size 100x100 pattern:HEXAGONS canvas.png

There are a host of options here

The start of a beautiful friendship

Hopefully these examples have whet your appetite for handling images on the command line. IM can do so so much more, and all those features are listed in IM’s extensive documentation.

Notes

Os X Users: sips

If you don’t want to bother installing IM, or you are on a friend’s Macbook and can’t. Use the built-in utility sips to do some batch image processing. While not as robust as ImageMagick, it suffice in a pinch. More on that here.

IM and Build Processes

While IM is an excellent choice for performing large batch operations on images, it has been my experience that it is better suited for one off batch jobs than a constant build/deploy process. I’d suggest using tools like the HTML5 BoilerPlate Build script or Grunt with the grunt-contrib-imgmin plugin on projects that may need to consistently run and rerun optimization.

A note on Performance

ImageMagick has a more performant fork GraphicsMagick if you are concerned about keeping resource usage down or if you are etsy. Most of the commands are similar, but the differences between the command structure and GM’s elusive api documentation make starting with imageMagick a better fit. You can always move on to GM when performance becomes a concern.

Corrections

If you are a command-line master, and i’ve missed something or missed a performant shortcut, don’t hesitate to note it in the comments. Or open an issue

Let’s Send an Html Email Using PHPmailer

Permalink

I recently needed to send a create a form that would send an html email with a PDF attachement. Due to some project constraints, using a service like MailChimp (which I do love oh so much) was out of the question, so I had to work a little magic of my own. Let’s go on a little journey, shall we?

Email: code like it’s 1999

Email is still an anomly when it comes to web standards, where the old school way of doing thing still reigns. Be not afraid, however, because are a few tools that make things quite a bit easier.

For starters: HTML Boilerplate

There are a lot of quirks in email markup, and the HTML Email Boilerplate does a great job of setting things up. You get tweaks for the various mail cients, a style reset, and a very basic markup template.

The good stuff: your design

Enjoy implementing your snazzy design here, but be sure to stay within the recommended 550-650px width (Mailchimp recommends 600px, so i’d say that’s a safe bet).

Feel free to write you styles in the <style></style> to make things easier as you design. We’ll use Premailer later on to move them inline.

Images can be hosted on your website, a CDN, or you can attach them to the email with PHPmailer.

Finishing things off: Premailer

Now that we have our beautiful template all tabled up and ready, we want to make sure it plays nicely with as many email clients as possible. The best way that i’ve found is to use Premailer. Premailer will take your lovely html template, work some magic on it, and give you a leaner, friendler version that even picky clients like outlook (and, suprisingly, gmail) will love.

Save the premailer formatted html to a file in your project directory (we’ll need to reference it in our PHP script later on).

Let’s Send this puppy!

We are so close, but… now we actually have to send the thing. Easier said than done.

MIMEs are a pain

The first hurdle is getting the proper MIME headers for the various elements of our email. We could just use PHP’s built in mail() and write our own MIME headers for all the content (which supposes that you know enough to write your own MIME headers – I don’t), but let’s take a look at how much fun that is:

1
2
$body .="Content-Type: text/html; charset=\"iso-8859-1\"";
$body .= "Content-Transfer-Encoding: 8bit";

Now imagine having to set that for your attachments (which you need to open and encode properly), the html email file, and the plain text version of your email. If you get things wrong, it’s up to you to figure out the esoteric error messages of mail() and various email clients. Whooo… no thanks. That’s why we’ll use PHPmailer to do it for us.

PHPMailer to the rescue

PHPMailer is an apache extra that takes a lot of the confusion out of sending emails. Just download it to your project directory, include it in your PHP file and follow the tutorial here or modify my script below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
require_once(includes/phpmail.class) // or wherever you put phpmail.class 
 
body = file_get_contents('email/htmlemail.html'); // include our formatted email

$mail->AltBody = "To view this message please use an HTML compatible email viewer, or visit http://mysite.com/emailcampaign"; // give folks who can't read HTML email something to read
$mail->SetFrom($email,$name);
$address = $email; 
$mail->AddAddress($address, $name);
$mail->Subject = "Subject";
$mail->MsgHTML($body);
$mail->addAttachment("email/attachment.pdf"); // just repeat this for multiple attachments

// send statement, followed by error reporting (comment out for production)
if(!$mail->Send()) {
  echo "Mailer Error: " . $mail->ErrorInfo; // for testing
} else {
  echo 'Message sent!'; // for testing
}

The end.

And there we have it, a functional workflow for an html email with some killer attachments. It’s not perfect by any means, but it has made things a lot less easier for me. Suggestions for improvement are more than welcome, just shoot me a comment.

Happy Emailing,
Nick

A Command Line Manifesto

Permalink

Note: I will be using “terminal” and “the command line” interchangeably. If there’s better language to use, drop me a comment and I will change things around.

My first experience with the command line was trying to play Wolfenstein 3D in windows 3.1. It was off-putting, a little scary, and I viewed the experience as a painful – but necessary – hurdle on the road to fun. From conversations i’ve had with others, this is not an uncommon perspective on terminal in the front-end community.

I felt the same until my stint as the IT admin/developer/sysadmin for a non-profit. I found myself developing on several servers of varying Linux flavors and, since some of these boxes were headless, I found myself having to break open the command line. My initial reaction to doing everything on the command line was terror but now, I try to do as much as I can on the command line.

Here’s why:

Speed

Things are just faster on the command line. Consider the following:

Workflow: Installing wordpress

GUI
  1. Download www.wordpress.org/latest.zip in your browser
  2. Find and unzip the files on your local machine
  3. Log into your site via FTP
  4. Upload the files via FTP
  5. Make a sandwich
  6. Run setup
Command Line (via ssh)
1
2
3
wget www.wordpress.org/latest.zip 
unzip latest.zip  
# run setup / or nano config file 

Not only does the command line version get things done 2 lines (possibly one, if you have more command-fu than I do), but it does also it significantly faster by removing the local machine from the process. Waiting for 500+ files to transfer one by one via FTP is no fun.

Things are even better for Drupal, using drush, but I won’t go into detail about that here.

Simplicity

I work in Mac Os X, which is based on Unix, and all of the sites work in a LAMP (Linux/apache/mysql/php) environment, so I find it pretty natural moving between the server and my local machine. This means tricks I pick up locally work remotely, and vice versa.

In addition, It’s quite helpful to be familiar with the environment where the things I make are going to live. If something doesn’t go according to plan on the server, I know some basic things to try, and I can give a lot more informed report to my sysadmin if I need help.

Finally, if you use SASS, LESS, or GIT you can run those from terminal without having to buy a gui app (however nice). All those new tools fit harmoniously into the same environment you are used to without any added overhead/app funkiness.

Extensibility

One of my initial frustrations with working on the command line was the sheer amount of time it took to get around. The shortcuts that i’d relied on (liking dragging a folder into “favorites”) were gone. While customizing things is not the most intuitive process initially, you really can have things formatted however you like, and do some crazy stuff you could never do with a GUI. I’d never go back now, simply because I wouldn’t have the same options that I do on the command line.

A few customizations i’ve found helpful:

  1. Open files in Photoshop

    I created a shop alias, so I don’t have to leave the command line and hunt through finder. For example, I can open all the transparent .png files for my home page with: shop images/home-*.png

  2. Open files in my text editor from the command line

    A simple subl . and an entire directory opens up as a project, or subl *.php and i’ve opened all php files.

  3. Use bashmarks to get around fast

    I use s sites to book mark my sites directory. Then, g sites gets me back.

This is just scratching the surface of what you can do; these were all simple to set up and I use most of them everyday. Pretty fantastic if you find yourself repeating some common tasks.

No pressure

All that said, the beauty of the command line is that you can use as much or as little as you want. If you find that it saves you time to deploy via the command line, but you prefer to do everything else via a GUI, then that’s more than fine. I think the most important thing is to not be afraid of the command line – or at least know what you are afraid of. I still do a lot of things the “old fashioned” way, but I have found the command line to be a helpful addition to my toolkit. Hopefully it will do the same for you : )

Happy coding,
Nick

REM Mixin for Sass

Permalink

Update: I’ve switched from LESS to SASS! (Whoah!) I might write a post explaining why, but for now i’ll just post a handy snippet.

The beauty and danger of EM

I love sizing in em’s but i’ve been bitten too many times by the weird em inheritance that can happen when i’ve shifted a module into a different context. It’s not fun having a <small> tag scale to 92px, and it’s even less fun making every last element play nice with calculations like 1.29284932930em.

Enter the REM

Rem sizing provides the proportional benefits of ems without the dangers of em innheritance. Smarter people than I have written about it. In short, I believe it is a perfect way to responsively size elements that would normally just get a PX value for safety. It’s annoying having “almost responsive” designs that scale typography or grid size, but still have buttons or images with “4px” padding.

One quick media query on <html> and a whole design scales in an instant. Beautiful!

The mixin

Here is a quick mixin + function pair I’ve made (inspired by this Chris Coyier post.) to quickly set rem for a property with a PX fallback.

Function & Mixin

1
2
3
4
5
6
7
8
9
10
11
// returns a target / context value
  @function remcalc($target,$context){
      @return ($target/$context)
  }
  
// grabs the desired size (in px) and spits out a REM value

  @mixin rem($selector,$target,$context:$root-font-size) {
      #{$selector} : ($target) + px;
      #{$selector} : remcalc($target,$context) + rem;
  }

SASS

1
2
3
4
5
6
7
8
9
10
.btn {
  @include rem(padding, 12) // assuming a root font size of 16 here
}

### Output

.btn {
  padding: 12px;
  padding: 0.75rem;
}

It works great for design elements like buttons, <em> or <small> that may be dropped in to any number of contexts.

Notes

  • Rem sizing is meaningless without proper responsive calculations, and is not a replacement for using ems in all scenaries

  • The mixin currently it only works with long-hand CSS properties like margin-bottom or padding-left. Shorthand properties will have to manually use the rem calc function (padding: 0 remcalc(120,16) 0 remcalc(60,16);) to return a value. Or wait until I or someone smarter writes a conditional mixin to provide that functionality