OPF
DocsReferenceView source

Images: backgrounds, image blocks and treatments

OPF 0.15 has two places for a picture, with one fit vocabulary:

  • A background is the slide's canvas fill. A picture background fills the whole slide behind everything and never moves content.
  • An image block holds every content picture. It carries fit, focus, the treatment vocabulary below, and an optional placement that bleeds it to one slide edge.

opf-render draws both as SVG and opf-pptx exports them as native PowerPoint DrawingML, from the same core geometry. This page also maps each of the 15 pptx.gallery image treatments to OPF, with its support status and the reason. The reference deck fixtures/image-treatments.opf.json has one slide per gallery treatment. Core's test/image-blocks.test.mjs checks it against core 0.14's frozen picture geometry, and pnpm test:image-treatments checks it across core, SVG and PPTX.

Backgrounds

json
{
  "design": {
    "background": {
      "type": "image",
      "src": "./images/harbour.jpg",
      "alt": "Container ships at dawn",
      "fit": "cover",
      "focus": { "x": 0.5, "y": 0.7 },
      "overlay": { "color": "dark1", "opacity": 0.4 }
    }
  }
}

The effective background is the slide's design.background, then the deck's, then the theme's. A picture background has these properties:

PropertyMeaning
srcThe picture: asset:<id>, an HTTPS URL, a data URI or a relative path.
altAlternative text. With alt the picture is meaningful, and PPTX export draws it as a full-slide picture at the back that carries the text. Without alt it is decorative and exports as the native slide background. A referenced asset's alt text does not count. In the preview a picture with alt is an image with that name, and one with alt: "" is hidden from assistive technology.
fitcover (the default) fills the slide and crops around focus. contain shows the whole picture over the colour scheme's default background. stretch scales it to the slide. tile repeats it at its own size from the top-left corner.
focus{ x, y } in 0 to 1: the point of the picture that a cover crop keeps in view. The default is the center.
opacityPicture opacity. The overlay keeps its own.
recolor"grayscale", or { dark, light } for duotone, as on an image block. Recolor and opacity apply to the picture's pixels; the overlay is drawn above them.
overlayA scrim over the whole picture, or a band along one edge (edge, size; see Overlay).

The string shorthand "asset:hero" (or any source starting with asset:, https://, data:, ./ or ../) is a cover picture background. Theme slots (light1) and hex colours keep their meaning, and any other string is invalid.

composeSlide reports the picture as SlideComposition.backgroundImage: the canvas box, fit, focus, opacity, recolor, the overlay box, and the fit placement when core can read the picture's proportions. The headings and the body compose exactly as on a slide without the background. A slide with only a title over a picture background is a cover, and its title centers like any cover's.

Image blocks

json
{ "image": { "src": "asset:hero", "alt": "Harbour" }, "fit": "cover", "focus": { "x": 0.3, "y": 0.5 }, "shape": "rounded", "border": { "color": "accent5", "width": 1 } }

Slide.image is source shorthand for one image block, with the effective design.imageFit: it takes no fit, focus, treatment or placement keys of its own (the schema rejects them on the slide). To treat or place a picture, write an image block in blocks. Every property below is optional, valid only on an image payload, and additive.

PropertyMeaningNative PPTXSVG preview
fitcover fills the frame and crops around focus. contain shows the whole picture. stretch scales it to the frame. Default: the effective design.imageFit (the slide's, the deck's, then the layout's), else cover.a:srcRect: positive insets crop, negative insets padthe shared placement (fitImage)
focus{ x, y }: the point a cover crop keeps in view.a:srcRectthe same placement
aspectRatioThe largest centered frame with this width/height ratio (circle uses 1).frame geometryframe geometry
shaperectangle, rounded, circle or hexagon.a:prstGeom rect / roundRect / ellipse / hexagon with core's guide valuesclipPath with core's outline of the same preset formula
cornerRadiusRadius of a rounded frame as a share of the shorter side. Default 0.16667.roundRect adjcircular arcs with the same radius
border{ color, width }. The line is centered on the outline, and its width is in reference pixels.a:ln with solidFill, algn="ctr" and a miter joinstroke on the same outline, miter join
opacityOpacity of the picture's pixels only.a:alphaModFixopacity on the image only
recolor"grayscale", or { dark, light } for duotone. Luminance uses Rec. 601 weights on sRGB.a:grayscl / a:duotonefeColorMatrix in sRGB
overlayA scrim in the frame's shape, or an edge band on a rectangle frame.one p:sp directly above the picturepath with fill-opacity
placement{ edge, size, inset }: bleed the block to one slide edge (see below).frame geometryframe geometry

Colors accept the usual ColorRef forms: hex, scheme slot or role, or var:<id>. Eight-digit hex alpha is kept as native a:alpha and SVG opacity. Alt text comes from the image's asset.

composeSlide reports every image item's picture as ComposedItem.image: the region (the cell, or the placement band), the frame box, fit, focus, the shape with its DrawingML preset and SVG outline, border, opacity, recolor, overlay and placement. Both engines draw exactly that. The paint order is the same in both: the picture with its recolor and opacity, clipped to the shape, then the line, then the overlay.

Placement

placement: { edge: "left" | "right" | "top" | "bottom", size: 0.1–0.9 (default 0.5), inset: false } gives the image a band along that edge of the slide, edge to edge, and the headings and other content compose in the rest of the slide at the normal padding. size is the band's share of the slide width (left, right) or height (top, bottom). inset: true puts the frame inside the slide padding of the band, like a card. Header and footer bands keep their full-width placement.

  • Only a top-level block (slides.N.blocks.I) can be placed, and each slide edge takes at most one placed image. A placed block inside a group or a promoted region, or a second block on the same edge, is an opf/image-placement-invalid error.
  • Bands are taken in block order. Each spans the free area left by the earlier ones.
  • A layout's image placeholder may carry the same placement. The layout's n-th image placeholder places the slide's n-th top-level image (an image block, or Slide.image) unless that block sets its own; this is the only way a root Slide.image is placed.
  • A slide whose only body is placed images is composed like a cover: its headings center in the free area beside the image.
  • In a right-to-left deck left is the start side, drawn at the right. Edge overlays mirror the same way.

Placement is the only mechanism that moves content aside. A background never does.

Overlay

{ color, opacity, edge?, size? } is shared by backgrounds and image blocks. Without edge it covers the whole frame in the frame's shape. With edge (top, bottom, left or right) it covers a band of size (default 0.3) of the frame along that edge, for example a caption strip. An edge overlay on a non-rectangle image frame reports unsupported-image-treatment at ...overlay.edge, and neither engine draws it. That diagnostic never fails strict layout. Text over a picture background is certified readable (opf/text-on-image) only through a full-frame overlay strong enough for every possible pixel; an edge band does not count.

An unchanged export imports back as the same OPF: the background and the image blocks with their treatments, plus a data URI of each embedded picture. The OPF_IMAGE_V1 and OPF_IMAGE_OVERLAY_V1 shape tags record the native geometry of an image block. A picture that was moved, re-cropped or recolored stays an ordinary image and reports its provenance diagnostic. An edited overlay drops only the overlay.

pptx.gallery treatments

Gallery treatmentOPFStatusReason or gap
full-bleedbackground {type: image, src, overlay: {color: dark1, opacity: 0.2}}supported
text-overlaybackground with overlay: {color: dark1, opacity: 0.55}supportedHeading color still follows the theme background. Use a dark theme or background for light text over photos.
side-by-sideimage block, placement: {edge: left, size: 0.46}supported
caption-overlayimage block, overlay: {color: dark1, opacity: 0.75, edge: bottom, size: 0.25}supportedSquare corners. An edge band cannot follow a rounded mask as one native shape. The gallery's card sits inside the slide padding, which a background cannot do, so the picture is content below the headings. Without the inset it is a background with the same edge-band overlay.
masked-shapeimage block, shape: hexagon, aspectRatio: 1.1547, placement: {edge: right, inset: true}supportedMasks are limited to the four presets. Arbitrary polygon and custom-geometry masks are not in the vocabulary.
circular-cropimage block, shape: circle, placement: {edge: left, size: 0.4, inset: true}supportedThe gallery's small shadow is not drawn (see shadows).
rounded-cardimage block, shape: rounded, cornerRadius: 0.05, border: {color: accent5, width: 1}supported, without shadowThe optional card shadow is unsupported (see shadows).
duotonebackground with recolor: {dark: accent1, light: light1}supportedNative raster parity of PowerPoint's luminance weights is unverified (see fidelity).
background-blurbackground with overlay: {color: light1, opacity: 0.4}, plus contentBox: trueunsupported: blurBlur is not expressible. The mapping keeps the light scrim and the sharp card, without the blur.
image-stripimage block, placement: {edge: bottom, size: 0.3}partialA placed block is one picture. A strip of several images is content: image blocks in a row composition.
collage-grid4 image blocks, composition: {mode: grid, columns: 2}, imageFit: coversupported via content blocksA collage is content composition, not a single-image treatment.
device-frameimage block, aspectRatio: 0.5, shape: rounded, cornerRadius: 0.12, border: {color: dark1, width: 12}, placement: {edge: right, inset: true}partialThe bezel is a thick line on a rounded portrait frame. Device artwork (notch, buttons, device-specific screens) is not expressible.
cutout-subjectimage block, fit: contain, placement: {edge: right}, with a transparent PNGpartialBackground removal is unsupported. PowerPoint's Remove Background produces an edited bitmap, not a declarative effect. Supply a pre-cut transparent PNG, and both engines keep its alpha. The grounding shadow is unsupported (see shadows).
watermarkimage block, fit: contain, opacity: 0.1, recolor: grayscalesupporteddesign.watermark remains a separate, preview-only feature.
cinematic-cropimage block, aspectRatio: 2.39, with design.background: dark1supported

The frames of full-bleed, text-overlay, background-blur, duotone, side-by-side, masked-shape, circular-crop, image-strip, device-frame, cutout-subject and collage-grid are those of core 0.14. Caption-overlay, rounded-card, watermark and cinematic-crop were 0.14 slide images behind the headings that need an inset, a mask, a line or an aspect ratio, which a background does not have. In 0.15 they are image blocks below the headings, and their treatment geometry within the frame is unchanged. The gallery snippets themselves live in pptx.gallery (FF-30).

Unsupported effects

These effects are left out of the vocabulary on purpose. A value that both engines cannot draw identically would break the preview/export contract.

  • Blur (a:blur inside a blip, or the Office 2010 a14:imgEffect artistic blur): PowerPoint's blur kernel and radius scale are not specified. There is also no native evidence that PowerPoint renders a blip a:blur on pictures. An SVG feGaussianBlur cannot be shown to match. background-blur is therefore unsupported.
  • Shadows and soft edges (a:outerShdw, a:softEdge in a:effectLst): these are native, but PowerPoint's blur kernel for them is unspecified. An SVG drop shadow would only approximate it.
  • Background removal: this is a bitmap edit, not an effect. Use a transparent source.
  • Device artwork and arbitrary masks: these would need custom geometry and composed artwork. The treatment vocabulary is limited to preset masks and a line.
  • Tint, brightness and contrast (a:lum, a:clrChange, a:tint): no gallery treatment needs them. They are left out until they have the same luminance-formula verification as grayscale and duotone.
  • Frame treatments on backgrounds: a background has fit, focus, opacity, recolor and an overlay (with edge bands). A masked, bordered, inset or aspect-ratio picture is an image block.

Fidelity boundary

These checks prove the shared contract: geometry, preset guides and outlines, line width and color, recolor endpoints, alpha, overlay and round trip (pnpm test:image-treatments, plus the tests in each engine). They do not prove PowerPoint raster parity. Office runs are root-only, and the following are still unverified in native PowerPoint:

  • negative a:srcRect insets for contain;
  • the luminance weights PowerPoint uses for a:grayscl and a:duotone. The preview uses Rec. 601 on sRGB, as LibreOffice does.
  • line joins on the hexagon outline.