Rendering Images
Images are stored as originals in the Alchemy picture library. Editors assign these images to Picture ingredients on elements. You control the rendering dimensions, cropping, and output format through ingredient settings and rendering options.
Alchemy supports two storage adapters: ActiveStorage and Dragonfly. Both use the same rendering API, so you can switch between them without changing your templates.
Configuration
Image rendering is configured in your initializer. See the Configuration guide for all available options.
# config/initializers/alchemy.rb
Alchemy.configure do |config|
config.output_image_quality = 85
config.preprocess_image_resize = "1000x1000"
config.image_output_format = "original"
config.sharpen_images = false
endTIP
You can override the output format and quality per ingredient by passing format and quality as rendering options.
Rendering
In most cases, rendering a Picture ingredient through el.render(:image) in your element view is all you need. It generates the correct image URL with all configured options applied.
<%# app/views/alchemy/elements/_article.html.erb %>
<%= el.render(:hero_image) %>The output depends on what the editor has configured on the picture:
- Image only — renders an
<img>tag - With caption — wraps in a
<figure>with a<figcaption> - With link — wraps the image in an
<a>tag - With caption and link — wraps the linked image in a
<figure>with a<figcaption>
Ingredient Settings
Configure rendering in your elements.yml definition.
- name: article
ingredients:
- role: hero_image
type: Picture
settings:
size: 1200x600
crop: trueSee the Picture ingredient settings for the full list of options.
Rendering Options
These options control how the image variant is generated.
size
String
The dimensions to resize the image to, preserving aspect ratio. Example: "400x300".
crop
Boolean
Crop the image to exactly match the given size.
format
String
The output format: "jpg", "png", "gif", or "webp".
quality
Integer
The quality of rendered JPEG and WebP images.
upsample
Boolean
Allow the image to be scaled up beyond its original dimensions. By default, images are only scaled down.
Responsive Images
Use the srcset and sizes ingredient settings to generate responsive <img> tags with multiple sources.
- role: photo
type: Picture
settings:
size: 1200x800
crop: true
srcset: ['400x267', '800x533', '1200x800']
sizes: ['(max-width: 600px) 400px', '(max-width: 900px) 800px', '1200px']This renders an <img> tag with a srcset attribute containing URLs for each size and a sizes attribute telling the browser which source to use at each viewport width.
Formats 8.4+
Since Alchemy 8.4, the format setting converts the image into another format, and srcset entries can be a hash with a size and their own format.
- role: photo
type: Picture
settings:
format: webp
srcset:
- 400x267
- size: 800x533
format: png
- size: 1200x800
format: webpThe main image and the 400x267 entry are rendered as WebP because of the format setting, the 800x533 entry as PNG. A format is only applied if the picture can be converted, so SVG files are rendered as they are.
All entries end up in the srcset of a single <img> tag, where the browser chooses by width only. Entries with the same size in different formats do not act as fallbacks for each other. To offer a format with a fallback, render a <picture> element with one <source> per format yourself, using ingredient.picture_srcset_options, which returns the url, desc, width, height and mime type of each entry.
TIP
New formats create new image variants. Generate them upfront instead of on the first request with:
bin/rake alchemy:generate:ingredient_picture_thumbnailsSet ELEMENTS=element1,element2 to only generate thumbnails for some elements and ASYNC=true to enqueue them as background jobs (ActiveStorage only).
Remote Storage
In production you typically want to store images on a remote service like Amazon S3, Google Cloud Storage, or Azure Storage instead of the local filesystem.
With ActiveStorage, configure your storage service in config/storage.yml and set the active service in your environment config, just like any Rails application. See the Active Storage Overview in the Rails guides.
# config/storage.yml
amazon:
service: S3
access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
region: eu-central-1
bucket: my-app-production# config/environments/production.rb
config.active_storage.service = :amazonWith Dragonfly, use the alchemy-dragonfly-s3 extension to store images on S3 compatible services.
TIP
See Extensions for all available storage add-ons.
Caching
Alchemy caches rendered image variants automatically. The caching strategy depends on your storage adapter.
ActiveStorage uses Rails' built-in variant caching. Variants are generated on first request and stored alongside the original blob.
Dragonfly uses Alchemy's PictureThumb model to cache rendered variants in the database. Three admin thumbnail sizes are pregenerated on upload.
In both cases, adding a CDN in front of your application is recommended for production to avoid hitting the application server for repeated image requests.