eQuantic.UIeQuantic.UI
Docs
Playground
GitHub
DocsÖkosystem
Image
Edit this page
5 min read
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.
1
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.
1
2
3
4
5
6
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
1
2
3
4
5
6
7
8
9
10
11
12
13
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
1
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:
1
2
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