Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsUse Pillow to create an image file, publish it at a URL that social-preview crawlers can reach, and reference that URL in your page’s og:image metadata. The tag points to an image; it does not generate or host one. This guide builds a PNG with Python, adds the Open Graph tags, and explains how to check the result.
What you need to generate an Open Graph image
An Open Graph image is an image file associated with a web page through its og:image property. The Open Graph Protocol defines metadata that describes the page and its preview image; Pillow provides Python image-processing operations. You need both pieces: code that creates the asset and a publicly reachable URL where your site serves it.
- A Python environment with Pillow installed.
- A design and pixel size chosen for your own use case. The protocol does not establish one universal image size.
- A way to serve the finished file at a stable, public URL over your site or another accessible host.
- Access to the page’s HTML head so you can add its Open Graph metadata.
The example below makes a 1200 × 630 pixel PNG. Those are dimensions chosen for this example, not a guarantee of how every social platform will display or crop the image. Check the relevant platform’s current preview tool after deployment if the appearance there matters.
Install Pillow and generate a PNG with Python
Install Pillow in the Python environment you will use to run the script:
#1 Best Overall
python -m pip install Pillow
Save the following as make_og_image.py. It creates a canvas, draws a background, and renders a title and subtitle. Pillow’s Image.size property returns a (width, height) tuple in pixels, so the script checks the output dimensions before saving.
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
WIDTH, HEIGHT = 1200, 630
OUTPUT = Path("static/images/python-og.png")
# Create a simple opaque background. Replace these colors and text to fit your page.
image = Image.new("RGB", (WIDTH, HEIGHT), "#101827")
draw = ImageDraw.Draw(image)
# Use a bundled font for consistent output across machines. If it is unavailable,
# Pillow's built-in default font is used instead.
font_path = Path("fonts/DejaVuSans-Bold.ttf")
small_font_path = Path("fonts/DejaVuSans.ttf")
try:
title_font = ImageFont.truetype(str(font_path), 64)
subtitle_font = ImageFont.truetype(str(small_font_path), 30)
except OSError:
title_font = ImageFont.load_default()
subtitle_font = ImageFont.load_default()
margin = 72
draw.rounded_rectangle(
(margin, margin, WIDTH - margin, HEIGHT - margin),
radius=28,
fill="#1d2b43",
outline="#506b91",
width=3,
)
draw.text((margin + 42, margin + 70), "Generate Open Graph Images", font=title_font, fill="white")
draw.text((margin + 44, margin + 180), "A Python and Pillow example", font=subtitle_font, fill="#c9d7eb")
draw.text((margin + 44, HEIGHT - margin - 90), "example.com", font=subtitle_font, fill="#8fb8ff")
if image.size != (WIDTH, HEIGHT):
raise ValueError(f"Unexpected image size: {image.size}")
OUTPUT.parent.mkdir(parents=True, exist_ok=True)
image.save(OUTPUT, format="PNG")
print(f"Wrote {OUTPUT} ({image.width} × {image.height})")
The font paths in the example are relative to the directory from which you run the script. For predictable typography, include the font files in your project and adjust those paths; otherwise the fallback font is used. The fallback keeps the script runnable but may not have the same appearance or support every character. Review the generated image before publishing, especially if your title contains characters outside the font’s coverage.
Choose dimensions and layout deliberately
Set WIDTH and HEIGHT to the canvas you intend to publish. Keep important text and logos inside a margin: a platform may crop or resize a preview, and this example does not claim to match any platform’s current display rules. If a particular network is important, consult its current requirements and inspect its preview rather than assuming the canvas will be shown unchanged.
For generated images that contain dynamic titles, wrap long text or reduce the font size when needed. Pillow’s drawing APIs can measure text, but the example intentionally uses a short title that fits on one line. A production generator should check text bounds before drawing and define what to do when a title does not fit, such as wrapping it or using a smaller font. Do not silently let text spill beyond the canvas.
Rank #2
Select PNG or JPEG based on the image
This example saves an opaque PNG. PNG is also appropriate when you need transparency; create an image with an alpha channel, for example with mode RGBA, if transparent pixels are part of the design. For a photographic image where file size matters, JPEG may be a better fit, but it does not preserve transparency. The right format depends on the image and how you intend to serve it; neither format is universally required by the Open Graph metadata contract.
Pillow can infer a format from a filename extension when saving. This example passes format="PNG" explicitly as well as using a .png filename. If you change the output to JPEG, save in JPEG format and make the public URL, response MIME type, and og:image:type agree with the actual file. A mismatch can make the asset harder for a client to interpret.
Publish the image and add Open Graph metadata
Move or generate the image where your web server will actually serve it, then use its absolute public URL in the page head. A local path such as static/images/python-og.png is not itself the URL a crawler fetches. For example, if your site serves that file at https://example.com/images/python-og.png, reference that full address in the metadata.
The Open Graph Protocol identifies four basic properties for a page: og:title, og:type, og:image, and og:url. Add the image alt text as well; the protocol recommends og:image:alt when an image is specified. Optional image properties can describe the image’s MIME type and dimensions.
Recommended Free Tools
<head>
<title>Generate Open Graph Images in Python</title>
<meta property="og:title" content="Generate Open Graph Images in Python">
<meta property="og:type" content="article">
<meta property="og:url" content="https://example.com/guides/python-og-images">
<meta property="og:image" content="https://example.com/images/python-og.png">
<meta property="og:image:alt" content="A dark graphic titled Generate Open Graph Images, with the subtitle A Python and Pillow example.">
<meta property="og:image:type" content="image/png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
</head>
Replace the example domain, page URL, title, description of the image, and dimensions with the values for your published page and asset. The alt text should describe the image rather than repeat a generic phrase; if the graphic contains text that matters, include that information. The width and height values must describe the file that was actually generated, not merely the intended canvas.
Image-specific properties belong after the og:image declaration they describe. If you publish multiple og:image values, put the preferred image first: the protocol gives the first value preference when there is a conflict. Keep each image’s structured properties in sequence after its root declaration so it is clear which image they describe.
Verify the deployed page and image
- Run the Python script and confirm it reports the intended pixel dimensions. Open the output file and inspect the text, colors, and crop.
- Deploy the image and visit its full public URL. Check that it returns the image itself rather than a login page, an error page, or a redirect to a private location.
- Inspect the deployed page’s HTML head and verify the four basic properties, the absolute image URL, and the matching image metadata.
- Use the relevant social platform’s current preview tooling to inspect its rendering. Platform-specific dimensions, size limits, caching behavior, and crawler rules are not established by the Open Graph property list alone.
A successful local save is not proof that an external crawler can retrieve the asset. Conversely, a valid image URL does not ensure every platform will render it identically. Test the deployed page and image in the environment that matters to you.
Common problems and fixes
The image exists locally, but the preview has no image
The metadata may still contain a filesystem path, relative URL, typo, or development hostname. Replace it with the absolute public URL and check that a browser without your local session can fetch that URL. Confirm that the page being shared is the page whose head contains the tags.
The file is blank, cropped, or has missing text
Open the saved asset itself and compare the rendered result with the code’s coordinates and font sizes. Long text can exceed the space available even when the canvas dimensions are correct. Adjust the layout, wrap or shorten the title, or reduce the font size, then regenerate and inspect the file again.
The metadata says PNG but the file is another format
Check the save call, filename extension, actual image, and server’s response type. Pillow infers a format from the filename unless you pass one explicitly. Make those values consistent, including og:image:type if you include it.
The script cannot find a font
The sample uses paths relative to the working directory, not automatically relative to the script file. Run it from the expected directory, bundle the font at the configured location, or update the paths. The fallback font prevents a missing font file from stopping the example, but its appearance may differ.
A social preview appears stale or differs from the browser
The protocol defines metadata, not each platform’s crawler, cache, or rendering behavior. Check the currently deployed HTML and image URL, then use that platform’s current preview or debugging tool. This guide does not establish a universal cache-clearing procedure or guarantee refresh timing.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteBest Value
Or skip the browser setup
ScreenshotNeo captures a rendered web page; it does not replace Pillow or generate the Open Graph image file. If you want a screenshot of your deployed page to inspect its visual appearance, its API accepts a URL and returns an image or PDF. The request below uses the documented API shape; see the ScreenshotNeo API documentation for options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/guides/python-og-images -o shot.webp
ScreenshotNeo accepts cookie or consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in headers. Its MCP server provides screenshot tools for AI agents, and the free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. See ScreenshotNeo for details. Sign up free for 1,000 screenshots a month, with no card required.
FAQ
Does adding og:image create the image?
No. Generate the image file and make it available at a public URL; the metadata points to that asset.
Does the Open Graph Protocol require the example’s dimensions?
No universal pixel dimensions are established by the protocol properties described here. Choose dimensions for your use case and check the target platform’s current guidance and preview.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Can I generate different images for different pages?
Yes. Generate an asset for each page or set of pages as needed, then point each page’s og:image value to its intended public image URL.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

