Skip to content

Quick start

  1. Configure where images come from (a loader), what transforms them (a transformer), and optionally a placeholder:

    config/packages/picasso.yaml
    picasso:
    loaders:
    filesystem:
    path: '%kernel.project_dir%/public/uploads'
    transformers:
    glide:
    sign_key: '%env(PICASSO_SIGN_KEY)%'
    placeholders:
    blur: { type: transformer } # optional: blurred preview while the image loads

    With a single loader and a single transformer, both are the defaults: no default_loader nor default_transformer to set.

  2. Import the routes, which serve the variants Glide renders:

    config/routes/picasso.yaml
    picasso:
    resource: '@PicassoBundle/config/routes.php'
  3. Render an image:

    <twig:Picasso:Image
    src="photo.jpg"
    width="800"
    height="600"
    sizes="(max-width: 768px) 100vw, 800px"
    alt="A beautiful landscape"
    />

This is the HTML the bundle renders for it, with our 2400 × 1608 sample photo as src. It is unedited, except for the srcsets, shortened to three candidates each:

Rendered HTML
<picture>
<source
type="image/avif"
srcset="/image/glide/filesystem/meeting.jpg?w=16&h=12&fm=avif&q=75&fit=contain&s=990aaabeb12e7406c8fd027b93ea5a6d 16w, /image/glide/filesystem/meeting.jpg?w=32&h=24&fm=avif&q=75&fit=contain&s=442dfaf720ebfdf22e047de3e05b511c 32w, … 13 more …, /image/glide/filesystem/meeting.jpg?w=2144&h=1608&fm=avif&q=75&fit=contain&s=0b000a57f1f0c3e76d87683fedba3baa 2144w"
sizes="(max-width: 768px) 100vw, 800px"
/>
<source
type="image/webp"
srcset="/image/glide/filesystem/meeting.jpg?w=16&h=12&fm=webp&q=75&fit=contain&s=216409c58ef7c691086e961eb6275528 16w, /image/glide/filesystem/meeting.jpg?w=32&h=24&fm=webp&q=75&fit=contain&s=0fcb094a01d8d919f7c0f998c0026df0 32w, … 13 more …, /image/glide/filesystem/meeting.jpg?w=2144&h=1608&fm=webp&q=75&fit=contain&s=ec48c1ef817d35f3aeb9f23a292673c6 2144w"
sizes="(max-width: 768px) 100vw, 800px"
/>
<img
src="/image/glide/filesystem/meeting.jpg?w=800&h=600&fm=jpg&q=75&fit=contain&s=8c9d9461fdc191386b6cc2538b0ad28f"
srcset="/image/glide/filesystem/meeting.jpg?w=16&h=12&fm=jpg&q=75&fit=contain&s=645976813d155ff1872d282113edfd73 16w, /image/glide/filesystem/meeting.jpg?w=32&h=24&fm=jpg&q=75&fit=contain&s=d5179f8b7c41413dbd41efd7acfb680b 32w, … 13 more …, /image/glide/filesystem/meeting.jpg?w=2144&h=1608&fm=jpg&q=75&fit=contain&s=6572a336d7312097fe21ceac54e92161 2144w"
sizes="(max-width: 768px) 100vw, 800px"
width="800" height="600"
loading="lazy"
style="background-size:cover;background-position:center;background-repeat:no-repeat;background-image:url(/image/glide/filesystem/meeting.jpg?w=10&h=8&fm=jpg&q=30&fit=crop&blur=5&s=ef0757d07c30fcfc0ae62ca0fe508e30);"
onload="this.style.backgroundImage=''"
alt="A meeting"
/>
</picture>

That single line of Twig is 50 signed URLs: 16 widths in each of the 3 formats, the fallback src and the placeholder. The largest candidate is 2144 px wide, not 3840: at the 4:3 ratio of width and height, a 1608 px high source gives at most 2144 px, and Picasso never upscales. Nothing is rendered yet. Glide renders a variant the first time a browser asks for it, then serves it from its cache:

  1. Browserpicks one candidate of the srcset
  2. /image/glide/…checks the signature
  3. Gliderenders on the first request only
  4. Cacheserves every next request

Next: choose the sizes that match your layout, and pick a placeholder.