Images and drawings

Inline and floating DrawingML pictures in DOCX: supported formats, wrap modes, authoring them from React or Vue, accessibility, and the security boundaries.

DrawingML pictures (w:drawing with pic:pic) lay out, paint, and round-trip through the engine. Both adapters provide insert, wrap, properties, alt text, and selection-overlay authoring.

Supported formats

FormatInsertLayout & paintRound-trip
PNG, JPEG, GIFYes, normalizeImageBytes preflightFull decode at authored wp:extentOriginal media preserved unless replaced
BMP, WebPNo insertFull decode at authored wp:extentOriginal media preserved
SVGNo insertPainted at authored wp:extentOriginal media preserved
TIFF, EMF, WMFNo insertRasterized when conversion succeeds; labeled placeholder otherwisePreserved; no zero-click fetch
External r:link / TargetMode="External"No auto-loadPlaceholder + preserved relPreserved; explicit user gesture to embed

Insert accepts PNG/JPEG/GIF only. Other payloads stay in the package and affect pagination through their authored extent.

JPEG validation accepts large EXIF and ICC metadata segments before the frame header. Intrinsic dimensions account for EXIF orientation, matching the browser's decoded image. The original photo bytes and the authored drawing extent remain unchanged.

BMP and WebP decode in the browser and paint like PNG or JPEG. BMP support includes top-down bitmaps and the 12-byte BITMAPCOREHEADER. WebP support includes lossy, lossless, and extended containers.

TIFF, EMF, and WMF paint when conversion to a validated raster succeeds. The original media stays unchanged in the package through save. When conversion is unavailable, declined, or fails, the image keeps its extent and shows a labeled placeholder.

SVG is painted through an <img>, which puts the browser in secure static mode: scripts in the file never run and external references in it are never fetched. Its intrinsic size is read from width/height/viewBox for reset-to-natural-size; layout always uses the authored wp:extent. An SVG whose root element cannot be read renders as a placeholder rather than inferring missing dimensions.

Reading selection state

Use the canonical read model shared by snapshot and imperative API:

import { useEditorState } from '@docx-editor.dev/react';

const image = useEditorState((s) => s.image);
// SelectedImageState | null: widthEmu/heightEmu, crop, wrap, position, locks, resourceStatus
editor.getSelectedImage(); // same SelectedImageState shape
editor.snapshot().image; // reference-stable until selection or image fields move

SelectedImageState.wrap reports one of these Word menu targets:

ValueText behaviorOOXML mapping
inlinePlaces the picture in the text linewp:inline
squareWraps on both sides of a square boundarywrapSquare, bothSides
squareLeftWraps on the leftwrapSquare, left
squareRightWraps on the rightwrapSquare, right
tightWraps around the authored polygonwrapTight
throughWraps through the authored polygonwrapThrough
topAndBottomKeeps text above and belowwrapTopAndBottom
behindPlaces the picture behind document contentwrapNone, @behindDoc="1"
inFrontPlaces the picture in front of document contentwrapNone, @behindDoc="0"

Images in front of or behind text can paint beyond their anchor cells. Their cell-relative position is preserved, but the cell does not crop these overlays. Page-relative images are clipped to the physical sheet, including its margins.

The resourceStatus field reports image availability:

StatusMeaning
pendingValidation or decoding is in progress
readyValidated image bytes are ready to paint
unrenderableValidation, decoding, conversion, or format support failed
externalThe relationship points outside the package and is not loaded automatically
missingThe relationship target is missing

Authoring surface

Both adapters export the same parts under the same names. Default toolbar slots (contextual image group when a picture is selected):

SlotComponent / hookEngine command
image.insertImageInsertProvider, ImageInsertTriggerexecuteImageCommand({ type: 'insertImage', … })
image.wrapImageWrap, useEditorValueCommand('image.wrap')setImageWrapType via runToolbarCommand
image.altTextImageAltTextsetImageAltText
image.propertiesImagePropertiesTrigger, DocxEditorImagePropertiesDialogsetImageProperties

The packaged Insert menu carries an Image row that opens the same file picker as ImageInsertTrigger. Hide it or place it elsewhere through DocxEditor.Menu.ImageInsert.

widthPoints and heightPoints are the extent to insert at most. An image that fits where the caret flows keeps its natural size; a wider or taller one scales down proportionally to its cell, column, or page content box. Read the committed extent back from snapshot().image.

Insert preflight:

import { normalizeImageBytes } from '@docx-editor.dev/react';

const result = normalizeImageBytes(bytes);
if (result.ok) {
  await editor.executeImageCommand({
    type: 'insertImage',
    data: result.bytes,
    mime: result.mime,
    widthPoints: result.widthPoints,
    heightPoints: result.heightPoints,
  });
}

Floating pictures: select in the canvas, drag to move (setImagePosition), eight handles or Alt+Arrow to resize (setImageProperties), wrap menu for all nine choices. One undo step per completed gesture.

Wrap modes and text reflow

Wrap changes are layout-structural: exclusion zones feed line breaking before paint. Square/tight/through use authored polygons (with distances and effectExtent); top-and-bottom and square variants reflow body text accordingly. Header/footer rule: page-relative anchored letterheads do not inflate the header box. Body flow height still sizes the furniture band.

Text distances inherit each missing side from wp:anchor; an explicit wrap-child value, including zero, overrides that side. When square or rectangular tight wrapping leaves no passage wide enough for the next glyph, text clears the image before continuing. The clearance participates in pagination without repeating the gap on subsequent lines. Nonrectangular contours keep their existing scanline behavior.

Accessibility

Alt text uses @descr, then @title; @name is never announced. A picture with neither description nor title is exposed as decorative. Hidden drawings (@hidden) suppress paint, hit-testing, and handles while remaining preserved on save.

Security and external images

  • No network fetch on open, layout, paint, or save for external relationships.
  • Embedded bytes are signature-checked and dimension-capped before decode.
  • Hyperlinks on drawings (a:hlinkClick) require an explicit gesture and pass through sanitizeHref.
  • Optional explicit download-and-embed path for external targets is user-initiated only (bounded size/content-type).

Drawing limits

The editor renders brightness, contrast, grayscale, and bilevel black-and-white picture adjustments. It preserves image alpha and adjustment markup when you save. PDF export does not apply these adjustments.

Drawing contentStatus
Solid shapes and bounded shape groupsRender geometry with sRGB or theme colors
Charts, SmartArt, unsupported groups, and canvasesPreserve the extent and show a labeled placeholder
Anchored text boxesRender the story read-only and clip it to the extent
Page fields in anchored header or footer text boxesEvaluate per page
Inline text boxes, linked chains, autofit, and rotationShow a placeholder
Standalone VML (w:pict)Render the subset described in Legacy VML previews
w:object and w:altChunkPreserve as generic content with diagnostics
Tracked image insertion and deletionRecord the change in suggesting mode
Tracked image property editsStay unavailable in suggesting mode
Artistic effects (a:effectLst)Do not render; authored markup round-trips

Find text in text boxes

Find searches anchored text boxes in the body, headers, and footers. Selecting a match selects its text box; the content remains read-only. Inline text boxes and text boxes in footnotes or endnotes are not searched.

Use useDocumentSearch to add Find navigation to a custom React or Vue interface.

Legacy VML previews

Standalone w:pict can render unrotated embedded photos and bounded groups of photos, solid rectangles/ellipses, straight line segments with arrows, and straight fit-to-box WordArt (_x0000_t136). Group-local coordinates, picture crops, supported text wrapping, and source order are retained. WordArt uses the authored font when available on the host; curved or rotated WordArt is not supported.

Previews are read-only. Saving preserves the original VML, media, and relationships without adding generated SVG parts or converting the source to DrawingML. Deleting another picture preserves shared photo relationships.

The editor does not partially render unsupported, oversized, or clipped groups. Custom templates, text boxes, curves, image effects, rotation, and unsupported group members prevent a group preview. Only recognized standard shape templates are supported. When a document supplies DrawingML and VML alternatives, the editor displays only the selected alternative.

Standalone photos reuse validated image resources and retain their authored crop. Groups, WordArt, and color-key previews use bounded static SVG resources. Embedded members still pass the normal image validation and decode limits; an external or missing member never triggers a fetch or a misleading partial group preview.

Next steps

On this page