Quick fix

Use from PIL import Image, then Image.open(...). Import every other Pillow module you use the same way (from PIL import Image, ImageDraw, ImageFont). If the error says No module named 'PIL', Pillow is not installed for this interpreter; that is a different problem, covered in No module named 'PIL'.

AttributeError: module 'PIL' has no attribute 'Image'

app.py
import PIL

img = PIL.Image.open("photo.jpg")
Tested on ✓ Linux ✓ Windows ✓ macOS
Output
Traceback (most recent call last):
  ...
AttributeError: module 'PIL' has no attribute 'Image'

import PIL imports only the package, not the modules inside it. PIL.Image exists as an attribute only after something has imported it. That is why this code sometimes works:

app.py
import PIL
import matplotlib.pyplot      # imports PIL.Image internally

img = PIL.Image.open("photo.jpg")
print("works now:", img.size)
Tested on ✓ Linux ✓ Windows ✓ macOS
Output
works now: (1600, 1067)

Matplotlib imports PIL.Image for its own use, which makes the attribute appear. Code that relies on this breaks as soon as the other import is removed or moved below. Import what you use: import PIL.Image or from PIL import Image.

ModuleNotFoundError: No module named 'Image'

old_tutorial.py
import Image
Tested on ✓ Linux ✓ Windows ✓ macOS
Output
ModuleNotFoundError: No module named 'Image'

The original PIL, last released in 2009, could be installed so that import Image worked. Pillow never supported that. Change it to from PIL import Image; the same applies to import ImageDraw, import ImageFont and the rest.

NameError: name 'Image' is not defined

app.py
from PIL import *

img = Image.open("photo.jpg")
Tested on ✓ Linux ✓ Windows ✓ macOS
Output
NameError: name 'Image' is not defined

The PIL package does not export its modules through import *, so a star import gives you nothing useful. Name the modules explicitly. The same error appears when the import line is missing, or sits inside a function or an if block that did not run.

AttributeError: type object 'Image' has no attribute 'open'

Here Image is a class, not the module. open() is a function in the module PIL.Image; the class PIL.Image.Image is the type of an opened image and has no open method:

app.py
from PIL.Image import Image

img = Image.open("photo.jpg")
Tested on ✓ Linux ✓ Windows ✓ macOS
Output
AttributeError: type object 'Image' has no attribute 'open'

The other common cause is a star import from tkinter after the Pillow import. Tkinter defines its own Image class, which replaces the name:

gui.py
from PIL import Image
from tkinter import *          # tkinter has its own class called Image

img = Image.open("photo.jpg")
Tested on ✓ Windows ✓ macOS (Windows and macOS-specific example)
Output on Windows
Traceback (most recent call last):
  File "example.py", line 4, in <module>
    img = Image.open("photo.jpg")
          ^^^^^^^^^^
AttributeError: type object 'Image' has no attribute 'open'

Import tkinter by name (import tkinter as tk) and Pillow's module stays where you put it. We ran this one on Windows and macOS in CI; the Python we use for the main tests is built without tkinter.

Spelling: pillow, pil, PIL.image

spellings.py
import importlib

for name in ["pillow", "pil", "Pillow", "PIL.image", "PIL.Image"]:
    try:
        importlib.import_module(name)
        print(f"{name:<10} ok")
    except ImportError as e:
        print(f"{name:<10} {type(e).__name__}: {e}")
Tested on ✓ Linux ✓ Windows ✓ macOS
Output
pillow     ModuleNotFoundError: No module named 'pillow'
pil        ModuleNotFoundError: No module named 'pil'
Pillow     ModuleNotFoundError: No module named 'Pillow'
PIL.image  ModuleNotFoundError: No module named 'PIL.image'
PIL.Image  ok

You install Pillow but import PIL, in capitals. Module names are case-sensitive on every operating system, even where file names are not.

The import that works, and how to refer to the image type

app.py
from PIL import Image, ImageDraw, ImageOps

img = Image.open("photo.jpg")
print(type(img).__module__, type(img).__name__)   # the class lives in the module PIL.Image
print(isinstance(img, Image.Image))                # module.Class: use this for type checks and hints
Tested on ✓ Linux ✓ Windows ✓ macOS
Output
PIL.JpegImagePlugin JpegImageFile
True

For type hints and isinstance checks, write Image.Image: module, then class. A function signature looks like def thumbnail(img: Image.Image) -> Image.Image:.

The outputs and images on this page are the real results of running every example with Pillow 12.3.0 on Python 3.13 (Linux) on 2026-10-15. Every example is also re-run automatically on macOS (Darwin 25.6.0, Pillow 12.3.0), Linux (Linux 6.17.0-1022-azure, Pillow 12.3.0), Windows (Windows 2025Server, Pillow 12.3.0); the line under each example shows the result per operating system. The DejaVu Sans font files sit next to each script so font examples behave the same everywhere. Sample photos: NASA/Sam Lott, public domain. Spotted something wrong? Tell us.