How to open an image from the URL in PIL?

PIL (Python Imaging Library) is a widely used Python library that enables developers to work with image files. It offers a broad range of functionalities for manipulating and handling image files, such as opening and resizing them, converting between different formats, and more.

One frequently encountered task when working with images involves opening an image file from a URL. This is especially useful when working with images that are stored on a remote server, such as those obtained from an online database or a website.

In this article, we will learn how to open an image from the URL in PIL using four different approaches ?

Using the urllib Module

The first method downloads the image to local storage using the urllib.request module, then opens it with PIL.

import urllib.request
from PIL import Image

my_url = "https://www.tutorialspoint.com/images/logo.png"

# Download the image using urllib
urllib.request.urlretrieve(my_url, "logo.png")

# Open the downloaded image in PIL
my_img = Image.open("logo.png")

# Display image information
print(f"Image size: {my_img.size}")
print(f"Image format: {my_img.format}")
print(f"Image mode: {my_img.mode}")
Image size: (135, 60)
Image format: PNG
Image mode: RGBA

Using the requests Module

The second method uses the requests module to download the image and opens it directly from memory using BytesIO.

import requests
from PIL import Image
from io import BytesIO

my_url = "https://www.tutorialspoint.com/images/logo.png"

# Download the image using requests
my_res = requests.get(my_url)

# Open the downloaded image in PIL from memory
my_img = Image.open(BytesIO(my_res.content))

# Display image information
print(f"Image size: {my_img.size}")
print(f"Response status: {my_res.status_code}")
print(f"Content type: {my_res.headers.get('Content-Type')}")
Image size: (135, 60)
Response status: 200
Content type: image/png

Using the io Module with urllib

The third method combines urllib and io modules to read the image data directly into memory without saving to disk.

import urllib.request
from PIL import Image
from io import BytesIO

my_url = "https://www.tutorialspoint.com/images/logo.png"

# Read the image from the URL using the io module
with urllib.request.urlopen(my_url) as my_url_res:
    my_img_data = my_url_res.read()

# Open the image in PIL from memory
my_img = Image.open(BytesIO(my_img_data))

# Display image information
print(f"Image size: {my_img.size}")
print(f"Data size: {len(my_img_data)} bytes")
Image size: (135, 60)
Data size: 5758 bytes

Using Requests with Stream

The fourth method opens the image directly from the URL using requests with streaming, which is memory-efficient for large images.

from PIL import Image
import requests

my_url = "https://www.tutorialspoint.com/images/logo.png"

# Open the image directly from the URL using streaming
my_response = requests.get(my_url, stream=True)
my_img = Image.open(my_response.raw)

# Display image information
print(f"Image size: {my_img.size}")
print(f"Image format: {my_img.format}")
Image size: (135, 60)
Image format: PNG

Comparison

Method Memory Usage Saves to Disk Best For
urllib download Low during processing Yes When you need the file locally
requests + BytesIO Moderate No Small to medium images
urllib + BytesIO Moderate No When avoiding third-party libraries
requests stream Low No Large images or limited memory

Conclusion

Use requests with streaming for memory efficiency with large images. Use urllib to download when you need the file saved locally. For small images, any method works well, but requests provides better error handling and is more user-friendly.

Updated on: 2026-03-27T10:29:51+05:30

6K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements