Trongate PHP Framework Docs
Introduction
Quick Start
Basic Concepts
Understanding Routing
Intercepting Requests
Module Fundamentals
Database Operations
Templates
Helpers
Form Handling
Form Validation
Working With Files
Image Manipulation
Working With Dates & Times
Language Control
Security
Tips And Best Practices

Outputting and Saving Images

After bringing images into memory using (for new uploads) or (for existing images) you need to do something with them. Trongate gives you two options:

  1. Save them to disk for permanent storage
  2. Output them directly to the browser for immediate display

Understanding when to save versus when to output - and how to control compression, format, and permissions - separates amateur image handling from professional implementations.

Save vs Output:

  • - Writes image to disk as a file. Use for permanent storage, user uploads, generated thumbnails, or any image that needs to persist.
  • - Streams image directly to browser without disk storage. Use for dynamic images, watermarks, on-the-fly transformations, or temporary displays.

Saving Images to Disk

The method writes the currently loaded image to a file with optional compression and permission settings.

Basic Saving

After using to bring an image into memory and performing any manipulations, use to write it to disk:

Method Signature

Overwriting vs Creating New Files

Destructive Operations: When saving to the same path you loaded from, you overwrite the original file permanently. For production systems, consider keeping originals and saving manipulated versions with different names.

Controlling Image Quality

The compression parameter (0-100) controls the trade-off between file size and visual quality for JPEG and WEBP formats.

Quality Guidelines

Quality by Use Case

Image Type Recommended Quality Reasoning
Hero images, banners 90-95 High visibility, worth the file size
Product photos 85-90 Balance of quality and performance
Content images 80-85 Good quality, faster page loads
Thumbnails 75-80 Small display size hides artifacts
Background images 70-75 Often blurred or overlaid

Format-Specific Compression Behavior:

  • JPEG and WEBP respond to quality settings:
    The quality parameter (0-100) determines the trade-off between file size and visual fidelity.
    • Lower values = smaller files with more compression artifacts
    • Higher values = better quality with larger file sizes
    • 85-90 = recommended sweet spot for web images
  • PNG and GIF ignore quality settings:
    These formats use lossless compression that preserves all image data.
    • The quality parameter has no effect
    • PNG preserves exact pixel values and alpha transparency
    • GIF preserves binary transparency with maximum 256 colors

Practical tip: Use JPEG/WEBP for photographs where file size matters, and PNG/GIF for logos, graphics, and images requiring transparency.

Setting File Permissions

Control who can read, write, or execute saved images using the permissions parameter:

Permission Recommendations:

  • 0644 - Public images (web galleries, user avatars, product photos)
  • 0640 - Semi-private (group-readable only)
  • 0600 - Private images (documents, scanned files, sensitive photos)

Working with Different Formats

The Image module automatically detects and preserves the original format, but you can change formats by changing the file extension:

Format Conversion

Format Selection Guide

Format Best For Compression Transparency
JPEG Photos, complex images Lossy, adjustable No
PNG Logos, graphics, screenshots Lossless Yes (alpha)
GIF Simple graphics, animations Lossless, limited colors Yes (binary)
WEBP Modern web, photos + graphics Lossy or lossless Yes (alpha)

Outputting Images to Browser

The method streams an image directly to the browser without saving it to disk. Perfect for dynamic image generation or temporary displays.

Direct Browser Output

Always Set Content-Type: When using output() to stream images to browsers, you must set the Content-Type header using get_header(). Without this header, browsers may fail to display the image or attempt to download it as a file.

Capturing Image Data as String

Getting the Correct MIME Type

When outputting images to browsers, you must set the correct Content-Type header. Use to get the appropriate MIME type:

Supported MIME Types

  • image/jpeg - JPEG images
  • image/png - PNG images
  • image/gif - GIF images
  • image/webp - WEBP images

Real-World Example: Dynamic Avatar System

Generate multiple avatar sizes from a single upload without storing every size:

Dynamic vs Pre-Generated: This avatar system generates sizes on-demand rather than pre-generating all sizes during upload. The browser cache (1 hour) ensures subsequent requests are fast without repeatedly processing the image.

Save vs Output: Decision Guide

Use save() when:

  • Images need to persist between requests
  • You're processing user uploads
  • Generating thumbnails or variants for later use
  • Creating static assets for deployment
  • Performance matters (serve static files via web server)
  • Building image galleries or catalogs

Use output() when:

  • Generating images dynamically per request
  • Adding watermarks or overlays on-the-fly
  • Creating temporary previews or proofs
  • Serving user-specific customized images
  • Avoiding disk storage for security or space reasons
  • Testing or debugging image operations

Performance Considerations

Caching Headers for Dynamic Images

ETags and Browser Caching: Using ETags (entity tags) with cache headers prevents unnecessary image regeneration. When the browser sends the ETag back, return a 304 Not Modified response instead of regenerating the image. This dramatically reduces server load for frequently accessed dynamic images.

When to Pre-Generate vs On-Demand

Scenario Strategy Reasoning
User uploads (avatars, photos) Pre-generate common sizes Predictable sizes, frequent access
Product images Pre-generate High traffic, consistent sizing
Admin previews On-demand Infrequent access, varied sizes
Watermarked images On-demand Prevents unauthorized distribution
User-specific customizations On-demand Unique per user, storage waste
Blog post images Pre-generate Consistent layouts, public access

Complete Example: Professional Upload Handler

Best Practices

Output and Saving Guidelines:

  • ✅ Use quality 85-90 for production web images
  • ✅ Set appropriate file permissions (0644 for public, 0600 for private)
  • ✅ Always set Content-Type header when using output()
  • ✅ Add caching headers (Cache-Control, ETag) for dynamically served images
  • ✅ Pre-generate common sizes during upload
  • ✅ Use output() for watermarks and user-specific content
  • ✅ Store originals and generate variants as needed
  • ✅ Validate size parameters when serving on-demand
  • ✅ Call destroy() after output() to free memory
  • ✅ Check file existence before load() operations
  • ✅ Consider WEBP for modern browsers (better compression)
  • ❌ Never output images without setting Content-Type header
  • ❌ Avoid storing binary image data in databases (use filesystem)
  • ❌ Don't generate unlimited sizes (validate against allowed list)

We're continually improving the Trongate documentation. If anything is incorrect, unclear, incomplete, or could be better, we'd genuinely appreciate your input.

Share your thoughts in the Documentation Feedback.

Leave Feedback About This Page