Skip to content

Image de

Edgar Mesquita edited this page Oct 13, 2026 · 1 revision

Image

🌐 Diese Seite auf: English · Português · Español · Français · Deutsch

Eine Bitmap in einem ausdrücklich dimensionierten Platz. Die Größe ist ein Konstruktorargument und kein Hinweis, denn das Layout kann die Ausdehnung einer Quelle, die es nicht dekodiert hat, nie erschließen, und ein Platz, der auf das Netz wartet, ist eine Seite, die sich vor den Augen der Leserin umbaut.

Image("/images/hero.jpg", 640, 360, label: "The team at the 2026 offsite")

Mit der Factory geschrieben, wie der Rest des Vokabulars. Derselbe Aufruf realisiert sich im Web und auf Photon; nichts darin nennt ein Ziel.

Der Platz

Parameter Typ Bedeutung
source string Wo die Grafik liegt. Ein Pfad, den das Ziel holen kann.
width float Die Breite des Platzes, in dichteunabhängigen Pixeln.
height float Die Höhe des Platzes.
fit ImageFit Wie die Grafik den Platz füllt. Cover als Voreinstellung.
label string Was ein Screenreader sagt. Leer heißt dekorativ, und das ist die HTML-Regel und gilt auf beiden Zielen.

Drei weitere werden als Eigenschaften gesetzt, weil sie die Ausnahme und nicht die Form sind:

Eigenschaft Typ Bedeutung
DarkSource string? Die Grafik für den DUNKLEN Modus, wenn ein Bild nicht beide bedienen kann.
CornerRadius CornerRadii Der Radius je Ecke; die Grafik wird darauf beschnitten.
Fit ImageFit Hier ebenfalls setzbar, für einen Baum, der ohne die Factory gebaut wird.
new Image("/brand/wordmark.svg", 180, 40)
{
    DarkSource = "/brand/wordmark-white.svg",
    CornerRadius = new CornerRadii(8),
    Label = "",           // dekorativ: der Name daneben sagt es schon
}

Fit

ImageFit Was es tut
Cover Füllen mit zentriertem Beschnitt. Die Voreinstellung, und was eine Fotografie will.
Contain Mit Balken im Platz, die ganze Quelle sichtbar.
Stretch Verzerrendes Füllen. Für Grafik reserviert, die das verträgt.

Die dunkle Grafik ist ein PAAR, keine Verzweigung

Eine Wortmarke, in Tinte für helle Flächen und in Weiß für dunkle gezeichnet, kann nicht eine Datei sein. Farben lösen das mit einem ColorToken-Paar; Grafiken können das nicht, also lebt das Paar am Knoten, und der Realisierer löst es auf dieselbe Weise auf: keine Verzweigung im Anwendungscode, und keine Modusfrage zur Malzeit.

Im Web gehen beide Quellen mit, und CSS zeigt eine, der Vorliebe des Betriebssystems und dem erzwungenen Modus der Anwendung selbst folgend, den der Theme-Controller als data-theme einstempelt.

Was jedes Ziel zeichnet

Web: ein <img> mit der Breite und Höhe des Platzes, dem object-fit aus Fit, dem border-radius aus CornerRadius, dem src aus Source und dem alt aus Label.

Photon: Die Engine zeichnet unter demselben Radius eine SurfaceSubtle-Platzhalterbox, bis das Hochladen der Textur landet: das dokumentierte Degradationsmuster, hier gesagt, damit die Form der Seite auf beiden Zielen dieselbe ist, auch während die Pixel es nicht sind.

Zäune der v1, von beiden geteilt: Nine-Slice, die Lade- und Fehlerzustände und das Überblenden beim Dekodieren kommen mit den Asset- und Animationssystemen, statt an diesem Knoten anzukommen.


Serverseitige Bildoptimierung

eQuantic.UI.Images fügt einen Endpoint hinzu: einen eigenständigen Dienst, der Bilder auf Verlangen skaliert, neu kodiert und zwischenspeichert.

Lesen Sie das zuerst, denn die Form dieser Funktion ist nicht, wonach sie aussieht. Der Endpoint ist nicht an den Image-Knoten verdrahtet. Nichts im Vokabular verlangt von ihm eine skalierte Variante, und der Knoten hat keine Eigenschaft für Qualität, srcset oder Opt-in, und die Seite, die Sie lesen, sagte einmal das Gegenteil und beschrieb ein reines Web-Element, das dem Vokabular voranging. Ausgeliefert wird der Dienst; etwas darauf zu richten ist heute der Zug des Aufrufers.

Ihn einschalten

builder.Services.AddUI(options =>
{
    options.UseImageOptimization(opts =>
    {
        opts.DefaultQuality = 80;              // 1-100, Standard 75
        opts.Formats = ["image/webp"];         // bevorzugte Ausgabeformate
        opts.CacheTtlSeconds = 14400;          // Standard 4 Stunden
        opts.MaxSourceSize = 10 * 1024 * 1024; // Standard 10 MB
    });
});

app.UseStaticFiles();
app.MapUI();   // mappt /_equantic/image

Der Kontrakt

GET /_equantic/image?url=<path>&w=<width>&q=<quality>
Parameter Regel
url Pflicht. Muss mit / beginnen und darf kein .. enthalten, kann also den Content-Root nicht verlassen.
w Pflicht. Muss eine der AllowedWidths sein, sonst ist die Antwort 400 und nennt die erlaubten Werte.
q Optional, 1 bis 100. Fällt auf DefaultQuality zurück.

Das Format der Antwort wird aus dem Accept-Header der Anfrage gegen Formats verhandelt, mit einem Rückfall, den der Browser immer lesen kann. Ein Cache-Fehlschlag skaliert, konvertiert und schreibt das Ergebnis in CacheDirectory; ein Treffer liefert die zwischengespeicherten Bytes mit Cache-Control: public, max-age=<CacheTtlSeconds>. Eine Quelle größer als MaxSourceSize wird abgelehnt statt dekodiert, wer sie auch übergibt: Der Optimierer und der Platzhaltergenerator hören am Budget auf zu lesen, also wird ein Strom, den ein Aufrufer öffnet, daran gehalten wie eine Datei unter wwwroot.

Was er liest, und was zurückkommt

Eine Quelle wird gelesen, wenn ihre Bytes ein JPEG, PNG, GIF, WebP oder BMP sind, was ihr Name auch sagt. Ein .tiff wird abgelehnt, bevor es geöffnet wird, und eine Datei, die der Optimierer nicht lesen kann, oder eine, deren Header mehr als 16.383 × 16.383 Pixel verlangt, bekommt 400 geantwortet, ohne dass ein Pixel dekodiert wurde. Der Optimierer läuft auf SkiaSharp, und seine Natives für Linux, macOS und Windows kommen mit dem Paket, es gibt also nichts zu installieren und keinen Lizenzschlüssel zu setzen.

  • Orientierung. Die Orientierung, die eine Kamera aufgezeichnet hat, wird auf die Pixel angewandt, w ist also die Breite wie angezeigt, und ImageOptimizer.GetDimensionsAsync antwortet die Größe wie angezeigt.
  • Animation. Ein animiertes GIF oder WebP wird ausgeliefert, wie es ist, mit seinem eigenen Content-Type, so wie der Optimierer von Next.js eines ausliefert: Kein Encoder hier schreibt Einzelbilder.
  • Die Antwort. Sie ist eines der Formate, die ein Encoder hier schreibt, also nimmt Formats image/webp, image/png und image/jpeg, und jedes andere, image/avif eingeschlossen, hält die Anwendung beim Start an. Die Pixel sind sRGB und tragen kein Farbprofil, was ein Browser als sRGB liest.

Optionen

Option Standard Bedeutung
DefaultQuality 75 Die Qualität, wenn die Anfrage sie nicht nennt.
DeviceSizes 640, 750, 828, 1080, 1200, 1920, 2048, 3840 Breiten für Bilder in voller Breite.
ImageSizes 32, 48, 64, 96, 128, 256, 384 Breiten für Bilder kleiner als der Viewport.
AllowedWidths abgeleitet DeviceSizes und ImageSizes, dedupliziert und sortiert. Die Validierungsliste.
Formats image/webp Ausgabeformate, das beste zuerst: image/webp, image/png, image/jpeg.
CacheTtlSeconds 14400 Was die Antwort dem Browser sagt.
CacheDirectory obj/eQuantic/image-cache Wo die kodierten Ergebnisse liegen.
MaxSourceSize 10 MB Darüber wird eine Quelle abgelehnt, vom Endpoint gelesen oder von einem Aufrufer übergeben.

Unscharfe Platzhalter

BlurPlaceholderGenerator macht aus einem Strom oder einer Datei eine winzige base64-Data-URL. Aus den Diensten aufgelöst, die UseImageOptimization registriert, oder injiziert, liest er keine Quelle über das MaxSourceSize der Anwendung hinaus:

var placeholders = app.Services.GetRequiredService<BlurPlaceholderGenerator>();
var placeholder = await placeholders.GenerateFromFileAsync("wwwroot/images/hero.jpg");

Er ist aus demselben Grund ein eigenständiger Helfer, aus dem der Endpoint es ist: Das Vokabular hat keine Platzhaltereigenschaft, der man das Ergebnis geben könnte.

Siehe auch

  • Komponenten: der Rest des Vokabulars
  • Design System: die Tokens, darunter das ColorToken-Paar, das DarkSource spiegelt
  • Styling: das HtmlElement und die Notluke nur fürs Web

Clone this wiki locally