Exam Area: Area 1 – Product Knowledge (15%) Reference: https://docs.developers.optimizely.com/content-management-system/docs/image-editing
CMS 12 includes an in-browser image editor available to editors directly in the Media Library. No external tools required.
Capabilities:
| Feature | Description |
|---|---|
| Crop | Freeform or aspect-ratio constrained crop |
| Resize | Change image dimensions |
| Rotate | Rotate 90° clockwise / counter-clockwise |
| Flip | Flip horizontally or vertically |
| Focal Point | Mark the visual focus point for smart cropping |
| Reset | Revert to original |
Assets Pane → Media Library → Select an image
→ Click the pencil (✏️) icon OR
→ Right-click → Edit Image
↓
Image editor opens in the Edit View
The focal point marks the most important area of an image. It is used during responsive cropping to ensure the subject stays visible at all screen sizes.
object-position CSS or server-side cropping to respect the focal point// ImageData includes FocalX and FocalY (0-100%)
public class SiteImage : ImageData
{
// FocalX and FocalY are built into ImageData
// Access via: imageData.FocalX, imageData.FocalY
}
@{
var image = Model.Image != null
? _contentLoader.Get<ImageData>(Model.Image)
: null;
}
@if (image != null)
{
<div style="overflow:hidden; width:100%; height:400px;">
<img src="@Url.ContentUrl(image.ContentLink)"
style="object-fit: cover;
object-position: @(image.FocalX)% @(image.FocalY)%;
width: 100%; height: 100%;" />
</div>
}
All uploaded images are stored as ImageData instances:
[ContentType(GUID = "...", DisplayName = "Site Image")]
[MediaDescriptor(ExtensionString = "jpg,jpeg,png,gif,webp,svg")]
public class SiteImageFile : ImageData
{
[Display(Name = "Alt Text", Order = 10)]
public virtual string AltText { get; set; }
[Display(Name = "Caption", Order = 20)]
public virtual string Caption { get; set; }
// Inherited from ImageData:
// - FocalX (double) — % from left
// - FocalY (double) — % from top
// - Thumbnail (BlobReference)
// - IsImage → true
}
// Tells CMS which file extensions map to this content type
[MediaDescriptor(ExtensionString = "jpg,jpeg,png,gif,webp,svg,bmp,tif,tiff")]
public class SiteImageFile : ImageData { }
[MediaDescriptor(ExtensionString = "pdf,doc,docx,xls,xlsx")]
public class DocumentFile : MediaData { }
[MediaDescriptor(ExtensionString = "mp4,webm,mov,avi")]
public class VideoFile : MediaData { }
| Format | Upload | Edit UI |
|---|---|---|
| JPEG (.jpg, .jpeg) | ✅ | ✅ |
| PNG (.png) | ✅ | ✅ |
| GIF (.gif) | ✅ | ✅ |
| WebP (.webp) | ✅ | ✅ |
| SVG (.svg) | ✅ | ⚠️ No raster editing |
| BMP (.bmp) | ✅ | ✅ |
| TIFF (.tif, .tiff) | ✅ | ✅ |
Media files in CMS 12 are stored using blob providers:
// Development: local file system (default)
// Production: Azure Blob Storage (recommended)
// Register Azure Blob provider in Program.cs
builder.Services.AddAzureBlobProvider(options =>
{
options.ConnectionString = configuration["AzureBlobStorage:ConnectionString"];
options.ContainerName = "mysitemedia";
});
// Programmatic blob access
public class ImageService
{
private readonly IBlobFactory _blobFactory;
private readonly IContentRepository _contentRepository;
public ImageService(IBlobFactory blobFactory, IContentRepository contentRepository)
{
_blobFactory = blobFactory;
_contentRepository = contentRepository;
}
public async Task<Stream> GetImageStream(ContentReference imageRef)
{
var image = _contentRepository.Get<ImageData>(imageRef);
var blob = _blobFactory.GetBlob(image.BinaryData.ID);
return await blob.OpenReadAsync();
}
}
// Use IImageService or ImageSharp library (3rd party)
// Built-in thumbnail: image.Thumbnail (low-res preview used in Assets pane)
// For custom resizing, use ImageResizer or ImageSharp:
// Install: EPiServer.ImageResizer.Core (older) or use ImageSharp middleware
// Allow images in a ContentArea
[AllowedTypes(typeof(ImageData))]
[Display(Name = "Hero Image", Order = 10)]
public virtual ContentReference HeroImage { get; set; }
// Or in a ContentArea mixed with blocks:
[AllowedTypes(typeof(IContentData), typeof(ImageData))]
public virtual ContentArea MainContent { get; set; }
FocalX and FocalY stored? (On the ImageData instance, as % values 0-100)