How to Add Drawing Shapes to Word Documents in .NET
This guide shows how to add content to the drawing layer of a Word document with Aspose.Words FOSS for .NET: inserting an AutoShape, adding a picture, positioning it and wrapping text around it, filling and styling it, grouping several shapes, and setting a watermark. Aspose.Words FOSS for .NET is not yet published as a NuGet package, so reference it by building from source first.
Step-by-Step Guide
Step 1: Get the Library
Clone the repository and build Aspose.Words.sln in Release configuration, then add a project reference to Aspose.Words.csproj from your own .NET project, as described in the Installation guide. Add using Aspose.Words; and using Aspose.Words.Drawing; at the top of any file that works with shapes.
Step 2: Add an AutoShape
Construct a shape directly with new Shape(doc, shapeType), where shapeType is a ShapeType value such as Rectangle, Ellipse, Star, or TextBox, then insert it into the tree with DocumentBuilder.InsertNode(node). Shape is the concrete, sealed class you construct and configure; it derives from the abstract ShapeBase, which defines position (Left, Top, Width, Height, Rotation) and formatting sub-objects (Fill, Stroke, ShadowFormat, Glow, Reflection) shared with GroupShape.
Step 3: Add a Picture
DocumentBuilder.InsertImage is the direct route for pictures: overloads accept an Image, a file path, a Stream, or a raw byte array, with further overloads that take explicit width/height or full positioning arguments (horzPos, left, vertPos, top, width, height, wrapType). The resulting Shape’s ImageData property holds the picture data — call ImageData.SetImage(...) to swap the image, and use CropTop/CropBottom/CropLeft/CropRight, Brightness, Contrast, and GrayScale for basic adjustments.
Step 4: Position the Shape and Wrap Text
An inline shape (the default result of InsertImage) flows with the surrounding text and ignores positioning properties until it floats — check IsInline to confirm which mode a shape is in. To float a shape, set WrapType to a non-inline value and set RelativeHorizontalPosition / RelativeVerticalPosition (each relative to Page, Margin, Column, or a similar anchor) together with the Left/Top offsets. WrapSide controls side-specific wrapping, and HorizontalAlignment / VerticalAlignment handle simple relative alignment instead of explicit offsets.
Step 5: Fill and Style the Shape
Shape.Fill (a Fill object) paints the shape’s interior: Fill.Solid(color) for a flat color, Fill.OneColorGradient(...) / Fill.TwoColorGradient(...) for gradients, Fill.Patterned(patternType) for a pattern, and Fill.SetImage(...) for a picture fill — FillType reports which one is currently active. The outline comes from the Stroke property. For effects, ShadowFormat, Glow (GlowFormat), Reflection (ReflectionFormat), and SoftEdge (SoftEdgeFormat) each expose their own settings and a Remove() method that clears the effect back to none.
Step 6: Group Multiple Shapes
Combine several shapes into one unit with DocumentBuilder.InsertGroupShape(shapes), which returns a GroupShape. GroupShape is itself a ShapeBase, so it carries its own Fill, ShadowFormat, Glow, and Reflection that apply to the group as a whole; move or resize the GroupShape rather than its individual children so the group’s coordinate transform stays consistent. For a shape that carries text, Shape.TextBox (a TextBox object) controls padding (InternalMarginLeft/Right/Top/Bottom), auto-sizing (FitShapeToText), text direction (LayoutFlow), and vertical alignment (VerticalAnchor).
Step 7: Add a Watermark
Document.Watermark manages a single document-wide watermark independent of any shape you inserted manually. Call Watermark.SetText(text) or SetText(text, options) for a text watermark, or SetImage(...) for a picture watermark; Watermark.Remove() clears it, and Watermark.Type reports the current WatermarkType (Text, Image, or None). TextWatermarkOptions sets FontFamily, FontSize, Color, and Layout (WatermarkLayout.Horizontal or Diagonal); ImageWatermarkOptions sets Scale and IsWashout.
Common Issues and Fixes
Setting Left/Top on a shape has no visible effect.
The shape is still inline (IsInline == true). Set WrapType to a floating value and set RelativeHorizontalPosition/RelativeVerticalPosition so the offset properties take effect.
Shape.ImageData throws or returns nothing.
The shape isn’t a picture shape. Check Shape.HasImage before reading ImageData.
A group’s child shapes don’t move together.
The children were repositioned individually instead of through the group. Move or resize the GroupShape itself so its coordinate transform applies to every child.
Watermark text doesn’t use the requested font.
No TextWatermarkOptions was passed. Call Watermark.SetText(text, options) with a TextWatermarkOptions instance whose FontFamily is set.
Frequently Asked Questions
What’s the difference between Shape and ShapeBase?
ShapeBase is the abstract base class shared by Shape and GroupShape. Write code against ShapeBase when it should handle either kind uniformly; use Shape directly for members specific to a single drawing object, such as ImageData.
How do I insert a picture with a specific size?
Use a DocumentBuilder.InsertImage overload that accepts explicit width and height arguments, alongside the image source (an Image, file path, Stream, or byte array).
How do I make a shape float instead of sit inline with text?
Set its WrapType to a non-inline value and set RelativeHorizontalPosition / RelativeVerticalPosition so the Left/Top offsets are interpreted relative to the page, margin, or column.
Can a document have both a text and an image watermark at once?
No. Document.Watermark.Type reports the current watermark’s type; calling SetText or SetImage again replaces whatever watermark was previously set.
How do I remove a shadow or reflection from a shape?
Call Remove() on the corresponding formatting object — Shape.ShadowFormat.Remove() or Shape.Reflection.Remove().