Serving and converting
GetUrl with an adjustment gives the URL of a variant of a file: resized, cropped or in another
format. The middleware that answers these URLs is in
chapter 18.
var adjustment = new FileAdjustmentImage {
Width = 1200,
Height = 630,
CropMode = ImageCropMode.Fill,
RequestedFormat = FileFormat.Webp,
Quality = 80
};
string url = db.GetUrl(venue.Photo, adjustment);
var path = venue.Photo.PropertyPath!;
bool ready = db.IsFileReady(path, adjustment, requestIfNot: true); // queues it when not ready
if (db.TryGetConversionInfo(path, adjustment, true, out var progress)) { … }Every option of FileAdjustmentImage is nullable. Set only what you need; two requests that ask for
the same thing share one conversion.
| Group | Options |
|---|---|
| Canvas | Width, Height, CropMode (Fill, Fit, Stretch, Auto), BackgroundColor, AutoBackgroundColor |
| Framing | Zoom (percent; above 100 zooms in on the focus), FocusX / FocusY, OffsetX / OffsetY, Rotation (degrees) |
| Tone | Brightness, Contrast, Saturation (−100…100), HueShift (−180…180), Sharpness (0…100) |
| Light/dark | InvertLuminance, AutoLightDarkMode (below) |
| Output | RequestedFormat, Quality (0…100, lossy formats only) |
| From a video | TimeOffsetMs or TimeOffsetPercentage: the frame to take |
RequestedFormat is optional for images: left out, you get the original file when nothing is
adjusted, and otherwise the store's default format
(Image variants adapt by default). FileAdjustmentVideo converts
a video, FileAdjustmentAudio takes the sound of a video or a recording (Mp3 by default), and
FileAdjustmentMeta asks for a file's metadata as JSON.
Conversion runs in the background:
- A URL you just built may not be ready yet.
IsFileReadytells you. PassfirstInQueue: truewhen a web request waits for the result, so it goes ahead of the conversions already queued. Leave it off for background work, or page views wait behind your batch jobs. - A variant that is not ready does not fail. A request for it waits a little, then gets a status picture in the requested format, marked as not cacheable. Never cache such a response.
- A failed conversion is tried again by the first request after an hour.
Converters. Conversion works without registering anything. Every store converts JPEG, PNG, WebP, GIF and BMP pictures itself, and takes frames and sound from video with FFmpeg, which it downloads beside the application the first time it is needed. Converters you add are tried first:
builder.AddRelatudeDB(options => {
options.FileConverters.Add(new SkiaImageConverter()); // adds AVIF, for example
});Size limits. A small file can declare a huge picture, and asset URLs let anyone ask for any size.
So the converters refuse a picture larger than ImageLimits.MaxPixels (200 megapixels), and an
adjustment may enlarge a picture to at most ImageLimits.MaxEnlargedPixels (4096 × 4096). Lower
them at startup on a small server, where a 200-megapixel picture takes 800 MB once decoded:
ImageLimits.MaxPixels = 50_000_000; // namespace Relatude.DB.FileConversion
ImageLimits.MaxEnlargedPixels = 2048 * 2048;