packer.io says they build identical images for multiple platforms such as EC2, VirtualBox, VMWare, and others (with even more on the way via plugins). However, it's more about customizing a machine
already running than it is about fabricating a new machine out of whole cloth and distributing the result to disparate services. That is, the AMI builder starts from another AMI; the VirtualBox builder starts from an installer ISO (with commands to make the install unattended) or an OVF/OVA export and customizes that to produce an output OVF/OVA export. This is, as I understand it, in contrast to Vagrant or Docker images, which build one image that runs on many systems.
Packer is about customizing existing machines that already exist in some form, then building the result as a new image for the same system. If you're really interested in taking "one base image" to many environments, then
Docker is probably the better choice there. It's built on Linux Containers, where the virtualization happens inside the host kernel instead of a dedicated hypervisor, which makes it possible to run a bit-for-bit identical container both inside EC2 (even PV) and inside VirtualBox.
In another contrast to
vagrant, packer supports a shell provisioner that lets you upload a shell script and run wild. Last I knew, which is probably woefully out of date, vagrant supported puppet by default and chef-solo as an option. Since I happen to have an existing build system constructed around shell scripts for provisioning (with a dash of perl or php for the trickier parts), albeit specifically for EC2 instances, packer might suit my codebase and philosophy a little better.
Put another way, and beating the dead horse a bit more, Vagrant and Docker are about creating One True Image and later instantiating that single image on different underlying services (including EC2 and VirtualBox). Packer is about coordinating the construction of native images for those services; it's about making predictable, repeatable changes to a running instance in the service and exporting the result for later use.
Unrelated to the above, packer is written in go 1.2 and distributes binaries for various platforms. Docker is also written in go (but I'm not sure of the version target), leaving Vagrant in Ruby as the odd man out. Having been subjected to rvm to install octopress at one point, I'm much more amenable to smaller dependency footprints... like static binaries produced by Go. (Then again, I heard later that everyone hates rvm.)
Update 14 Feb 2014: I thought of one more useful contrast among the projects. Docker and Packer are aimed toward building immutable, self-contained images. Vagrant is focused on setting up (repeatable) development environments--particularly, in how it includes only the VirtualBox provider by default, and uses shared folders to persist changes as you develop.