[Fixed]-Installing PIL to use with Django on Mac OS X


EDIT: This answer has been getting voted up recently, and I want to modify it to reflect what I’m doing now.

Firstly, I’ve switched from MacPorts to Homebrew for package management on Mac OS X. Secondly, I’ve switched from using my package manager to using pip and virtualenvwrapper to manage my Python libraries.

Why I switched:

At first, with just a few Django projects, it was very easy to keep everything up to date using MacPorts. It was also fairly easy to have multiple versions of Python using python_select. What I didn’t realize was that I was doing a pretty terrible job of keeping multiple libraries working side-by-side. It became obvious as I upgraded my packages that sometimes I really didn’t want a project’s Django version to change. After a couple of Django 1.1 projects (now running Django 1.3) started exhibiting weird behaviour (forms failing to submit because of CSRF middleware changes, small differences in Django libraries, admin app assets changing, and so on) it became clear that I should look into a better solution.

What I do now:

On Mac OS X I’m moved over to using pip and virtualenvwrapper. First off, I install virtualenvwrapper:

pip install virtualenvwrapper

This will grab virtualenv and virtualenvwrapper. You then need to add the following to your .bashrc or .profile and source it or open a new shell.

export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh # where Homebrew places it
export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no-site-packages' # optional

Line 1 sets up the variable workon needs to find its files. Line 2 points to the main shell script (the path here is where Homebrew places the file, it might be different if you’re using another package manager). Line 3 is optional, but I really like it: it makes sure that no currently installed libraries in the "main" site-packages repository will leak into your newly created virtual environment. I find this keeps things clean and leads to fewer surprises down the road as things are upgraded.

The next step is to create a new virtual environment:

mkvirtualenv testEnvironmentName

After making the environment, you’ll be placed into it. If you kept the --no-site-packages flag, you can type pip freeze to see that your Python library slate is now blank. To escape from the virtual environment, use the deactivate command. To get into your virtualenv again, use workon testEnvironmentName. Note that you can use tab completion on the name of the environment. Also note that typing workon by itself will give you a list of available environments. From here you can pip install any libraries you want, including PIL.

To learn more about virtualenvwrapper, I recommend checking out the documentation.

Here’s another great resource which taught me a lot about using virtualenvwrapper (or just view the screencast)


You can also instal PIL using MacPorts. The package name is py-pil. Here’s more information on the package. I’m pretty fond of MacPorts over pip, as I find it gives me a bit more configurability when it comes to keeping several versions of python and several libraries installed.

Here are the installation instructions for MacPorts: http://www.macports.org/install.php

See also: What is the most compatible way to install python modules on a Mac?


Following steps worked for me:

$ brew install pip
$ export ARCHFLAGS="-arch i386 -arch x86_64"
$ pip install pil


Yes, I have issues with PIL on 10.6.6 too, homebrew and easy_install.

The easiest solution for me was to easy_install PIL / pip install PIL, navigate to /Library/Python/2.6/site-packages/, and symlink the PIL-1.1.7-.....egg file to PIL

ln -s PIL-................egg PIL

>>> import PIL
>>> from PIL import Image
# no more problems.

Edit: These days, I try to use Pillow, a library built to help install PIL. Try pip install pillow – can’t hurt!


It might be easier to pinpoint your issue if you can elaborate on what you tried and what error messages were generated with those attempts. Here’s some probable solutions that you may or may not have attempted:

pip install pil

if you dont have pip, try

easy_install pil

Since you’re on the Mac, you can also get HomeBrew (a package manager) and then try

brew install pil

or Macports has a PIL package here.

Or build from source?

More importantly, the PIL README states,


Additional notes for Mac OS X

On Mac OS X you will usually install additional software such as
libjpeg or freetype with the “fink” tool, and then it ends up in
“/sw”. If you have installed the libraries elsewhere, you may have
to tweak the “setup.py” file before building.*

That could be your issue. Good luck!


After fresh OS installation tried these steps:

  1. Installed homebrew
  2. brew install libjpeg
  3. brew install pil
  4. easy_install pil
  5. cd /Library/Python/2.6/site-packages
  6. ln -s /usr/local/Cellar/pil/1.1.7/lib/python2.6/site-packages/PIL PIL

After that I was able to load and save jpeg files… I know that this issue has a lot of different solutions and I’m not 100% my way will work for other, but it’s worth to try if you just bumping your head in to the wall 🙂


I’m using OS X 10.5.8, gcc 4.2.1, python 2.7.5, libjpegv9 and Pillow 2.1.0 (which is based on PIL).

My problem apparently (but it’s just a guess) was caused by architecture incompatibilities of the libjpeg and python (and Pillow) builds.

Building python and libjpeg from source using only 32bit arch solved it. I installed all the other python libraries, Pillow included, just by using

pip install xxxxx

and it worked fine.


First I tried both a dmg from the python.org site and a universal build installed via macports. I had not specified universal when installing but macports installed both i386 and ppc architectures anyways.

That caused me problems because libjpeg compiles only to i386 by default.

To check the build of the binaries, I did:

file /usr/bin/python

/usr/bin/python: Mach-O universal binary with 2 architectures

/usr/bin/python: Mach-O executable i386

/usr/bin/python: Mach-O executable ppc

file /usr/local/lib/libjpeg.dylib 

/usr/local/lib/libjpeg.dylib: Mach-O dynamically linked shared library i386

When building PIL (or Pillow), it seemed to use the same build options as python “-gcc i386 -gcc ppc” (which seems logical).

All went well until it built the “_imaging” module. There, it showed a warning that libjpeg.dylib was not of the right architecture but in the end it showed that JPEG was available just the same.



There is a packaging fork of PIL that attempts to make it easier to install and support on many modern platforms, including OS X:

You should be able to install it on OS X with pip or easy_install (assuming you have XCode). If you have any trouble, please open a ticket here:



Hey check out this article, worked wonders for me on Snow Leopard.

I’d also recommend using libjpeg 0.6 instead of 0.7 noted in the article.

Good luck.



I have issues installing PIL with brew and easy_install on my Mac too. My solution is to download source code from http://www.pythonware.com/products/pil/, extract the tar ball and use

python setup.py install

to compile and install the package.


Leave a comment