loading
Note:
Detection, not recognition This answers "is there a face, and where". It never says whose face it is, and computes nothing that could - no descriptor, no embedding, no identity. Nothing leaves the device either: the detector is the operating system's.
Warning:
Thin support, even by this family's standards Chromium only, off by default on desktop, and behind a flag or an origin trial where it exists at all. Treat it as an enhancement: IsSupported returning false is the common case, and Detect answers with an empty array rather than throwing. BarcodeDetector is the one member of the Shape Detection family with real deployment.

Support check

IsSupported

Returns true when the runtime exposes FaceDetector. During prerender/SSR the check returns false rather than throwing, so defer it to OnAfterRenderAsync.

C#
@inject Bit.Butil.FaceDetector faceDetector

if (await faceDetector.IsSupported() is false)
{
    // offer the manual crop instead
}
Live sample
support check output
Results will appear here when you interact with the samples.

Detect in a camera frame

Detect

Reads one frame of a video, image or canvas element. fastMode trades accuracy for speed, which is what a live preview wants; maxFaces stops the search early when you only need one. Landmarks - eyes, nose, mouth - are the platform's decision, not the browser's, so they are often empty on the same browser version that reports them elsewhere.

Razor
@implements IAsyncDisposable
@inject Bit.Butil.MediaDevices mediaDevices
@inject Bit.Butil.FaceDetector faceDetector

<video @ref="_video" autoplay playsinline muted></video>

@code {
    private ElementReference _video;
    private MediaStreamHandle? _stream;

    private async Task Detect()
    {
        _stream = await mediaDevices.GetUserMedia(audio: false, video: true);
        await _stream!.AttachTo(_video);

        var faces = await faceDetector.Detect(_video, maxFaces: 5, fastMode: true);

        foreach (var face in faces)
        {
            // face.X / Y / Width / Height in source pixels, face.Landmarks
        }
    }

    // The camera light stays on until the stream is disposed, whatever the page does.
    public async ValueTask DisposeAsync()
    {
        if (_stream is not null) await _stream.DisposeAsync();
    }
}
Live sample
camera output
Results will appear here when you interact with the samples.

Detect in an image file

DetectImage

Takes an encoded image's bytes - a PNG or JPEG, not raw pixels - which is what a file the user picked or an image you fetched already is. The decoded bitmap is released as soon as the scan finishes; it holds uncompressed pixels, which would be a real leak in a loop.

C#
var found = await faceDetector.DetectImage(bytes, "image/jpeg", maxFaces: 10);
Live sample
file output
Results will appear here when you interact with the samples.
Note:
Nothing found is not an error Both methods return an empty array rather than throwing - when there is no face, when the API is unavailable, when the video has no frame yet, and when the image couldn't be decoded. Check IsSupported up front rather than inferring it from silence.

API reference

Member
Signature
Description
IsSupported
ValueTask<bool> IsSupported()
True when the runtime exposes FaceDetector. Returns default (false) during prerender/SSR instead of throwing.
Detect
ValueTask<DetectedFace[]> Detect(ElementReference element, int maxFaces = 0, bool fastMode = false)
Scans one frame of a video, image or canvas element. Empty when there is nothing to find, or no frame yet. maxFaces is 0 to 65535 - the spec's own range - and throws outside it.
DetectImage
ValueTask<DetectedFace[]> DetectImage(byte[] imageBytes, string mimeType = &quot;image/png&quot;, int maxFaces = 0, bool fastMode = false)
Scans an encoded image's bytes. Empty when the image couldn't be decoded. maxFaces is 0 to 65535 - the spec's own range - and throws outside it.
DetectedFace
X | Y | Width | Height | Landmarks
One face's bounding box in source pixels, plus whatever features the platform located.
FaceLandmark
Type | X | Y | PointCount
One feature - an eye, the nose, the mouth - with its first point and how many points the platform reported.
An unhandled error has occurred. Reload 🗙