Banner Creation with BptImageEditor
Design multi-format ad banner templates in BptImageEditor's banner mode, then let your customers fill them out via BptBannerProducer — a two-tool workflow that cleanly separates design from production.
.bptt template once, defining the layouts, fonts, colors, and which elements are editable.
BptBannerProducer is for your customers — they load that template and fill it with their
own copy and images across every banner size at once.
Architecture: who uses what
| Component | Audience | File format | Purpose |
|---|---|---|---|
BptImageEditor (default) |
Designer | .bpti |
Standard single-image editing. |
BptImageEditor (BannerEditor mode) |
Designer | .bptt |
Builds a multi-format banner template that produces every banner size simultaneously. |
BptBannerProducer |
Customer | Loads .bptt, outputs PNG/JPEG/WebP |
Fills the template with the customer's text and images, exports finished banners. |
Step 1: Switch the editor to banner mode
The same BptImageEditor component handles both single-image editing and banner template authoring.
The mode is controlled by one parameter:
@page "/admin/banner-designer"
@using Bpt.Components.Tools
<BptImageEditor EditorMode="EditorMode.BannerEditor"
BannerTemplateFormatsMode="BannerTemplateFormatsMode.AddToDefaults"
Height="85vh"
EnableSave="true"
EnableLoad="true" />
With EditorMode.BannerEditor set, the editor reshapes itself for template authoring:
- The "New Image" dialog becomes "New Banner Template" and lets you select multiple banner formats up front (e.g. 300x250 Medium Rectangle, 728x90 Leaderboard, 160x600 Skyscraper).
- The Save action writes a
.bptt(banner template) file instead of.bpti. - The file picker labels switch from "image" to "banner template" everywhere they appear.
AddToDefaults to expose BPT's built-in IAB and social-media sizes alongside any custom dimensions
you add. Set to Custom if you only want to expose the formats you define explicitly.
Step 2: Design the template and mark editable fields
Inside banner mode, every banner size is a tab. Use the layers, text, image, and shape tools just like normal image editing — but anything you want the customer to be able to change later must be marked editable in the layer's property panel. The three editable layer types are:
| Layer type | Customer can change | Designer locks |
|---|---|---|
| Text | The text string, optionally font size within a range | Font family, color, alignment, position |
| Image | The image source (URL or upload) | Crop frame, position, size, filters |
| Color swatch | The fill color of a shape or text | Which shape, where it is, its dimensions |
Everything else — backgrounds, decorative shapes, brand-locked typography — stays exactly as you placed it. This is the central design discipline of banner mode: you decide what the customer can change, they decide what to put in those slots.
Step 3: Ship the .bptt to the customer site
The .bptt file is just bytes. Two common ways to hand it off:
| Approach | When to use |
|---|---|
Static file in wwwroot/banners/ | One template per campaign, designer is also the deployer. |
| DB-stored bytes | Multi-tenant SaaS, designer is internal staff, customers select from a library. |
.bptt with embedded reference images can run into the megabytes. If you store in a DB, use a
varbinary(max) column and stream rather than loading the whole row into memory.
Step 4: Wire BptBannerProducer on the customer page
On the customer-facing site, drop in BptBannerProducer and point it at the template bytes.
The producer renders a multi-banner workspace where the customer edits all sizes simultaneously:
@page "/banners/new"
@using Bpt.Components.Tools
@inject ITemplateStore TemplateStore
<BptBannerProducer TemplateBytes="@_templateBytes"
EnableAi="true"
EnableImageLibrary="true"
EnableSocialMediaFrame="true"
EnableFullScreen="true"
ShowDownloadButton="true"
ShowOrderButton="true"
OrderButtonText="Order banners"
OnExport="HandleExport"
OnOrder="HandleOrder" />
@code {
private byte[]? _templateBytes;
protected override async Task OnInitializedAsync()
{
_templateBytes = await TemplateStore.LoadAsync("spring-2026-campaign");
}
private Task HandleExport(BannerProducerExportResult export)
{
// export.Banners is List<BannerProducerBannerOutput> with one entry per format.
// Each output has Format, Width, Height, ImageBytes, MimeType.
return Task.CompletedTask;
}
private Task HandleOrder(BannerProducerOrderResult order)
{
// order.Banners has the finished banner bytes.
// order.CustomerNotes carries any free-text instructions.
// Push to your print queue or ad-network upload.
return Task.CompletedTask;
}
}The key feature flags decide which producer-side affordances your customer sees:
| Flag | What the customer gets |
|---|---|
EnableAi | An AI assistant panel that can rewrite copy or replace images across selected banners. Has an undo stack scoped to AI changes. |
EnableImageLibrary | Bulk image replacement — swap an image once and propagate the change across every banner format. |
EnableSocialMediaFrame | Preview each banner inside a stylized social media post frame (helpful for selling the design). |
EnableFullScreen | Adds a maximize toggle on the producer surface. |
ShowDownloadButton | Customer can download all finished banners as a ZIP. |
ShowOrderButton | Adds an "Order" CTA that fires OnOrder — wire to your own checkout/print workflow. |
Step 5: Handle the producer's outputs
Both OnExport and OnOrder hand you a result object containing finished banner bytes,
one entry per format. From there it's just plain server-side .NET — queue them, upload to a CDN, push to
Google Ads / Facebook Ads APIs, or write to disk for review.
private async Task HandleOrder(BannerProducerOrderResult order)
{
foreach (var banner in order.Banners)
{
var path = Path.Combine(_outputDir, $"{banner.Format}_{Guid.NewGuid():N}.png");
await File.WriteAllBytesAsync(path, banner.ImageBytes);
}
await _printQueue.EnqueueAsync(order);
}BptBannerProducer (customer side). Don't mix.