Search Docs
Loading...
Skip to content

Add Watermark

Add text and image watermarks to video content for copyright protection, branding, and content attribution using CE.SDK’s time-aware block system.

8 mins
estimated time
GitHub

Video watermarks in CE.SDK are design blocks positioned over video content. Text watermarks display copyright notices, URLs, or branding text, while image watermarks show logos or graphics. Both watermark types need their duration set so they remain visible throughout video playback.

This guide shows how to create text and image watermarks with the Android Engine API, position them on the page, style them for visibility, and configure their timing to span the full video.

Creating the Scene#

Start from a video scene and read the page dimensions and duration. The dimensions drive placement calculations, while the duration is reused for each watermark block.

val videoUri = Uri.parse("https://img.ly/static/ubq_video_samples/bbb.mp4")
engine.scene.createFromVideo(videoUri)
val page = requireNotNull(engine.scene.getCurrentPage()) {
"Expected createFromVideo() to create a page."
}
val pageWidth = engine.block.getWidth(page)
val pageHeight = engine.block.getHeight(page)
val videoDuration = engine.block.getDuration(page)

createFromVideo() creates the scene and current page from the source video. getDuration() returns the page duration in seconds, which the sample applies to both watermark blocks.

Creating a Text Watermark#

Text watermarks are regular text blocks. We create one, let it size itself to its content, then place it near the bottom-left corner with padding from the page edges.

val textWatermark = engine.block.create(DesignBlockType.Text)
engine.block.setWidthMode(block = textWatermark, mode = SizeMode.AUTO)
engine.block.setHeightMode(block = textWatermark, mode = SizeMode.AUTO)
engine.block.replaceText(block = textWatermark, text = "All rights reserved 2025")
val textPadding = 20F
engine.block.setPositionX(block = textWatermark, value = textPadding)
engine.block.setPositionY(block = textWatermark, value = pageHeight - textPadding - 28F)

Auto width and height keep the watermark frame tied to its text, so the sample only needs position values.

Styling Text Watermarks#

Style the text for readability across changing video backgrounds.

engine.block.setTextFontSize(block = textWatermark, fontSize = 20F)
engine.block.setTextColor(block = textWatermark, color = Color.fromRGBA(1F, 1F, 1F, 1F))
engine.block.setTextHorizontalAlignment(block = textWatermark, alignment = HorizontalAlignment.Left)
engine.block.setOpacity(block = textWatermark, value = 0.7F)

The sample uses white text, left alignment, and 70% opacity. setTextFontSize() applies the font size through the typed Android text API.

Adding Drop Shadow for Visibility#

Drop shadows help the text stay legible over both light and dark frames.

engine.block.setDropShadowEnabled(block = textWatermark, enabled = true)
engine.block.setDropShadowColor(block = textWatermark, color = Color.fromRGBA(0F, 0F, 0F, 0.8F))
engine.block.setDropShadowOffsetX(block = textWatermark, offsetX = 2F)
engine.block.setDropShadowOffsetY(block = textWatermark, offsetY = 2F)
engine.block.setDropShadowBlurRadiusX(block = textWatermark, blurRadiusX = 4F)
engine.block.setDropShadowBlurRadiusY(block = textWatermark, blurRadiusY = 4F)

The black shadow uses 80% alpha, 2 px offsets, and 4 px blur radii to add contrast without making the watermark dominate the video.

Setting Text Watermark Duration#

Set the text block duration to match the page duration and start it at the beginning of the timeline.

engine.block.setDuration(block = textWatermark, duration = videoDuration)
engine.block.setTimeOffset(block = textWatermark, offset = 0.0)
engine.block.appendChild(parent = page, child = textWatermark)

setDuration() controls how long the block is active during playback. setTimeOffset() starts the watermark at 0 seconds, and appendChild() places it above the video content on the page.

Creating an Image Watermark#

Image watermarks use a graphic block with a shape and image fill.

val logoWatermark = engine.block.create(DesignBlockType.Graphic)
val rectShape = engine.block.createShape(ShapeType.Rect)
engine.block.setShape(block = logoWatermark, shape = rectShape)
val imageFill = engine.block.createFill(FillType.Image)
val logoUri = Uri.parse("https://img.ly/static/ubq_samples/imgly_logo.jpg")
engine.block.setUri(
block = imageFill,
property = "fill/image/imageFileURI",
value = logoUri,
)
engine.block.setFill(block = logoWatermark, fill = imageFill)
engine.block.setContentFillMode(block = logoWatermark, mode = ContentFillMode.CONTAIN)

The image URI is assigned to the fill through the fill/image/imageFileURI property. ContentFillMode.CONTAIN keeps the logo inside its frame without cropping.

Positioning Image Watermarks#

Position logos where they do not cover important content.

val logoSize = 80F
val logoPadding = 20F
engine.block.setWidth(block = logoWatermark, value = logoSize)
engine.block.setHeight(block = logoWatermark, value = logoSize)
engine.block.setPositionX(block = logoWatermark, value = pageWidth - logoSize - logoPadding)
engine.block.setPositionY(block = logoWatermark, value = logoPadding)

The sample sizes the logo to 80 x 80 units and places it in the top-right corner with 20 units of padding.

Configuring Opacity and Blend Mode#

Control how the logo integrates with the video.

engine.block.setOpacity(block = logoWatermark, value = 0.6F)
engine.block.setBlendMode(block = logoWatermark, blendMode = BlendMode.NORMAL)

The logo uses 60% opacity for a visible but subtle overlay. BlendMode.NORMAL displays the logo without additional compositing effects.

Setting Image Watermark Duration#

Image watermarks need the same timeline configuration as text watermarks.

engine.block.setDuration(block = logoWatermark, duration = videoDuration)
engine.block.setTimeOffset(block = logoWatermark, offset = 0.0)
engine.block.appendChild(parent = page, child = logoWatermark)

Matching the page duration keeps the logo visible for the full video. A time offset of 0 seconds starts it with the first frame.

Watermark Positioning Strategies#

Choose positions based on the watermark purpose:

  • Bottom-right corner: common for copyright notices and less intrusive branding.
  • Top-right corner: useful for logos that should stay visible but avoid typical lower-third content.
  • Bottom-left corner: a good alternative for text when the opposite corner contains important content.
  • Center: strongest protection for drafts or previews, but it obstructs the video.

Calculate positions from the current page dimensions so the same code works across video aspect ratios.

Best Practices#

Visibility#

  • Use drop shadows on text watermarks for contrast against changing backgrounds.
  • Keep opacity between 50-70% for visible but unobtrusive branding.
  • Test watermark placement against representative video frames.

Time Management#

  • Match watermark duration to the page duration for full-video coverage.
  • Use a 0-second time offset for watermarks that should appear from the start.
  • For time-based variations, create separate watermark blocks with different offsets and durations.

Performance#

  • Use appropriately sized logo assets instead of scaling very large source images.
  • Keep the number of watermark blocks low when rendering many videos.
  • Reuse the same watermark creation logic for batch workflows.

API Reference#

MethodPurpose
engine.scene.createFromVideo(videoUri=_)Create a video scene from a URI
engine.scene.getCurrentPage()Get the page created for the video scene
engine.block.getWidth(block=_)Read the page width for placement calculations
engine.block.getHeight(block=_)Read the page height for placement calculations
engine.block.getDuration(block=_)Read the page or watermark duration in seconds
engine.block.create(blockType=DesignBlockType.Text)Create a text watermark block
engine.block.setWidthMode(block=_, mode=SizeMode.AUTO)Let a text block size itself to its content
engine.block.setHeightMode(block=_, mode=SizeMode.AUTO)Let a text block size itself to its content
engine.block.replaceText(block=_, text=_)Set text watermark content
engine.block.setTextFontSize(block=_, fontSize=_)Set text size
engine.block.setTextColor(block=_, color=_)Set text color
engine.block.setTextHorizontalAlignment(block=_, alignment=_)Set paragraph alignment
engine.block.setDropShadowEnabled(block=_, enabled=_)Enable or disable drop shadow
engine.block.setDropShadowColor(block=_, color=_)Set shadow color and alpha
engine.block.setDropShadowOffsetX(block=_, offsetX=_)Set horizontal shadow offset
engine.block.setDropShadowOffsetY(block=_, offsetY=_)Set vertical shadow offset
engine.block.setDropShadowBlurRadiusX(block=_, blurRadiusX=_)Set horizontal shadow blur
engine.block.setDropShadowBlurRadiusY(block=_, blurRadiusY=_)Set vertical shadow blur
engine.block.create(blockType=DesignBlockType.Graphic)Create an image watermark block
engine.block.createShape(type=ShapeType.Rect)Create a rectangular graphic shape
engine.block.setShape(block=_, shape=_)Apply the rectangular shape to the graphic block
engine.block.createFill(fillType=FillType.Image)Create an image fill for a logo
engine.block.setUri(block=_, property="fill/image/imageFileURI", value=_)Set the logo image URI
engine.block.setFill(block=_, fill=_)Apply the image fill to the graphic block
engine.block.setContentFillMode(block=_, mode=ContentFillMode.CONTAIN)Fit the logo inside its frame
engine.block.setWidth(block=_, value=_)Set watermark width
engine.block.setHeight(block=_, value=_)Set watermark height
engine.block.setPositionX(block=_, value=_)Set horizontal position
engine.block.setPositionY(block=_, value=_)Set vertical position
engine.block.setOpacity(block=_, value=_)Set watermark transparency
engine.block.setBlendMode(block=_, blendMode=_)Set image watermark blend mode
engine.block.setDuration(block=_, duration=_)Set timeline duration
engine.block.setTimeOffset(block=_, offset=_)Set timeline start time
engine.block.appendChild(parent=_, child=_)Add the watermark to the page

Next Steps#

  • Lock the Template - Restrict editing access to watermark elements or properties in templates
  • Export Overview - Explore export options, supported formats, and configuration features for sharing or rendering output
  • Timeline Editor - Arrange and edit video clips, audio, and animations frame by frame
  • Text Styling - Apply fonts, colors, alignment, and other styling options to customize text appearance