Skip to Content
FeaturesModulesLLM IntegrationVision & OCR

Vision & OCR

The VisionClient provides image analysis and OCR capabilities with automatic resizing for token optimization.

Token Cost Optimization

OpenAI Vision API charges based on image size:

Detail ModeSizeTokensUse Case
low512x51285 fixedOCR, text extraction
high768px short85 + 170/tileDetailed analysis
autoAdaptiveVariesAuto-select

Cost savings example:

  • 15,000 images/day: $1.72 → $0.19 (90% savings)

Quick Start

from django_cfg.modules.django_llm.features.vision import VisionClient # Default: auto_resize=True, default_detail="low" client = VisionClient() # Analyze image (auto-resized to 512x512 = 85 tokens) response = client.analyze( image_source="https://example.com/image.jpg", query="Describe this image" ) print(response.content) print(f"Cost: ${response.cost_usd:.4f}")

VisionClient Configuration

client = VisionClient( api_key="sk-or-v1-...", # Optional, auto-detected auto_resize=True, # Enable auto-resize (default) default_detail="low", # low/high/auto (default: "low") max_tokens=1024, # Max response tokens temperature=0.2, # Generation temperature )

Image Analysis

Basic Analysis

# Simple analysis response = client.analyze( image_source="https://example.com/image.jpg", query="What objects are in this image?" ) # With resize override response = client.analyze( image_source="https://example.com/detailed-chart.jpg", query="Analyze this chart in detail", resize=True, detail="high" # Use high detail for this call ) # Disable resize for specific call response = client.analyze( image_source="https://example.com/image.jpg", query="Describe", resize=False )

Quality Presets

# With quality preset response = client.analyze_with_quality( image_url="https://example.com/image.jpg", prompt="Analyze this image", model_quality="balanced" # fast, balanced, best )
PresetModelUse Case
fastAuto cheapestQuick checks, high volume
balancedllama-3.2-11bGeneral purpose
bestgpt-4oComplex, accuracy critical

Structured Analysis

# Returns ImageAnalysisResult + VisionResponse result, response = client.analyze_structured( image_source="https://example.com/image.jpg", context="Product catalog image" ) print(result.extracted_text) print(result.description) print(result.language) # e.g., "en"

OCR (Text Extraction)

Basic OCR

# Simple extraction response = client.extract_text( image_url="https://example.com/document.jpg" ) print(response.content)

OCR with Modes

response = client.ocr( image_url="https://example.com/receipt.jpg", mode="base" # tiny, small, base, gundam ) print(response.text)
ModeDescription
tinyMinimal, fastest
smallBasic extraction
baseStandard detailed
gundamMaximum detail, preserves formatting

Async OCR

response = await client.aocr( image="base64_encoded_data", mode="gundam" )

Image Resizer

Direct access to the resizer for custom workflows.

Resize PIL Image

from django_cfg.modules.django_llm.features.vision import ImageResizer from PIL import Image img = Image.open("photo.jpg") resized = ImageResizer.resize_image(img, detail="low") # Returns PIL Image resized to fit 512x512

Resize Bytes

resized_bytes, content_type = ImageResizer.resize_bytes( image_bytes, detail="low", output_format="JPEG", quality=85 )

Get Optimal Size

new_w, new_h = ImageResizer.get_optimal_size(2000, 1500, "low") # Returns (512, 384) - maintains aspect ratio

Estimate Savings

savings = ImageResizer.estimate_savings(4000, 3000, "low") print(f"Original tokens: {savings['original_tokens']}") print(f"Resized tokens: {savings['resized_tokens']}") print(f"Saved: {savings['savings_percent']}%") # Example: 88.9% savings

Image Fetcher

Fetch images with automatic resize.

from django_cfg.modules.django_llm.features.vision import ImageFetcher fetcher = ImageFetcher( timeout=30.0, max_size_mb=10, resize=True, # Auto-resize (default) detail="low", # Detail mode (default) ) # Async fetch with resize data, content_type = await fetcher.fetch( "https://example.com/image.jpg" ) # Override resize per call data, content_type = await fetcher.fetch( "https://example.com/image.jpg", resize=False, detail="high" ) # Sync versions data, content_type = fetcher.fetch_sync(url) data_url = fetcher.fetch_as_base64_url_sync(url)

Token Estimation

from django_cfg.modules.django_llm.features.vision import ( estimate_image_tokens, get_optimal_detail_mode, ) # Estimate tokens tokens = estimate_image_tokens( width=1024, height=1024, detail="high" ) # Returns: 765 (85 base + 170 * 4 tiles) # Low detail is always 85 tokens = estimate_image_tokens(2000, 2000, "low") # Returns: 85 # Auto-detect optimal mode mode = get_optimal_detail_mode(512, 512) # "low" mode = get_optimal_detail_mode(2048, 2048) # "high"

Async Methods

All methods have async versions:

# Async analyze response = await client.aanalyze( image_source="https://example.com/image.jpg", query="Describe" ) # Async with quality preset response = await client.aanalyze_with_quality( image="base64_data", model_quality="balanced" ) # Async OCR response = await client.aocr( image_url="https://example.com/doc.jpg", mode="base" )

Django Model Integration

Analyze images from Django model fields:

from pydantic import BaseModel class ChartAnalysis(BaseModel): trend: str confidence: float summary: str # Analyze with schema result = client.analyze_model( instance=media_instance, image_field="file", prompt="Analyze the chart trend", schema=ChartAnalysis ) # result is ChartAnalysis instance print(result.trend) print(result.confidence)

Best Practices

When to Use Low Detail

  • OCR and text extraction
  • Quick content checks
  • High-volume processing
  • When 512x512 is sufficient

When to Use High Detail

  • Complex charts/diagrams
  • Fine print analysis
  • When detail matters
  • Quality over cost

Disable Resize When

  • Image is already small
  • You need exact pixels
  • Using cached images
# Already small - skip resize if width <= 512 and height <= 512: response = client.analyze(url, query, resize=False)

Flow Diagram

TAGS: vision, ocr, image-resize, token-optimization

Last updated on