Relatude Help

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. IsFileReady tells you. Pass firstInQueue: true when 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;