====== std.image — Bildverarbeitung ====== Das ''std.image''-Paket stellt eine einheitliche API zum Laden und Verarbeiten von Rasterbildern bereit. Alle Formate werden auf ein gemeinsames internes Format normalisiert: RGBA, 4 Kanäle, 8 Bit pro Kanal, zeilenweise top-down. → [[lyx_-_programmiersprache:units|Units-Übersicht]] · [[lyx_-_programmiersprache:start|Lyx-Sprache]] ---- ===== Units ===== ^ Unit ^ Code ^ Beschreibung ^ | [[lyx_-_programmiersprache:units:image:core|std.image.core]] | GRF-00 | ''GrfImage''-Struct, Pixel-Operationen, Format-Erkennung, Datei-I/O-Helper | | [[lyx_-_programmiersprache:units:image:image|std.image.image]] | GRF-08 | Unified Facade: Auto-Detect + Dispatch auf alle Format-Decoder | | ''std.image.bmp'' | GRF-01 | BMP-Decoder | | ''std.image.png'' | GRF-02 | PNG-Decoder | | ''std.image.jpeg'' | GRF-03 | JPEG-Decoder | | ''std.image.gif'' | GRF-04 | GIF-Decoder | | ''std.image.tiff'' | GRF-05 | TIFF-Decoder (Little-Endian und Big-Endian) | | ''std.image.webp'' | GRF-06 | WebP-Decoder | | ''std.image.avif'' | GRF-07 | AVIF-Decoder | Für die meisten Anwendungsfälle genügt der Import von ''std.image.image'': import std.image.image; import std.alloc; import std.io; fn main(): int64 { var img: int64 := GrfImageAlloc(0, 0); // nur Struct, noch keine Pixel var ok: int64 := ImageDecode("foto.jpg"c, 0, img); if (ok == 0) { PrintLn("Fehler beim Laden"); return 1; } var w: int64 := ImageGetWidth(img); var h: int64 := ImageGetHeight(img); PrintLn(StrConcat(StrConcat(StrConcat("Breite: ", IntToStr(w)), " Höhe: "), IntToStr(h))); // Pixel an (100, 50) lesen — Format: 0xRRGGBBAA var px: int64 := ImagePixelAt(img, 100, 50); PrintLn(StrConcat("Rot: ", IntToStr((px >> 24) & 255))); ImageFree(img); return 0; } ---- ===== GrfImage-Struct ===== ''GrfImage'' ist ein 56-Byte-Kontroll-Struct im Heap. Alle Felder sind ''int64'' (8 Bytes): ^ Konstante ^ Offset ^ Inhalt ^ | ''GRF_OFF_WIDTH'' | 0 | Breite in Pixeln | | ''GRF_OFF_HEIGHT'' | 8 | Höhe in Pixeln | | ''GRF_OFF_CHANNELS'' | 16 | Kanalanzahl (immer 4 = RGBA) | | ''GRF_OFF_DEPTH'' | 24 | Bits pro Kanal (immer 8) | | ''GRF_OFF_FORMAT'' | 32 | Quellformat (''GRF_FMT_*'') | | ''GRF_OFF_PIXELS'' | 40 | Zeiger auf Pixel-Buffer | | ''GRF_OFF_PIXLEN'' | 48 | Größe des Pixel-Buffers (= w×h×4 Bytes) | | ''GRF_SIZE'' | 56 | Gesamtgröße des Structs | Das Pixel-Format ist RGBA row-major top-down: Byte 0 = R, Byte 1 = G, Byte 2 = B, Byte 3 = A.\\ Als gepackter int64: ''0xRRGGBBAA''. ---- ===== Format-Konstanten ===== ''GrfDetectFormat()'' erkennt das Format anhand der Magic-Bytes am Anfang des Puffers: ^ Konstante ^ Wert ^ Format ^ Magic ^ | ''GRF_FMT_UNKNOWN'' | 0 | Unbekannt | — | | ''GRF_FMT_BMP'' | 1 | BMP | ''BM'' (0x42 0x4D) | | ''GRF_FMT_PNG'' | 2 | PNG | ''89 50 4E 47'' | | ''GRF_FMT_JPEG'' | 3 | JPEG | ''FF D8 FF'' | | ''GRF_FMT_GIF'' | 4 | GIF | ''GIF8'' | | ''GRF_FMT_TIFF'' | 5 | TIFF | ''II 2A 00'' oder ''MM 00 2A'' | | ''GRF_FMT_WEBP'' | 6 | WebP | ''RIFF....WEBP'' (ab Offset 8) | | ''GRF_FMT_AVIF'' | 7 | AVIF | ''ftyp avif/avis'' (Offset 4/8) | ---- ===== Öffentliche API (std.image.image) ===== ==== Laden ==== // Aus Speicher-Puffer laden (Format wird automatisch erkannt) // img muss vorher mit GrfImageAlloc alloziert werden. // Gibt 1 bei Erfolg zurück, 0 bei Fehler. var ok: int64 := ImageDecodeFromMem(buf, len, img); // Aus Datei laden (liest Datei intern, ruft ImageDecodeFromMem auf) // plen: Zeiger auf int64, erhält Dateigröße; oder 0 wenn nicht benötigt. var ok: int64 := ImageDecode(path, plen, img); ==== Freigeben ==== ImageFree(img); // gibt Pixel-Buffer + Struct frei ==== Accessor-Funktionen ==== var w: int64 := ImageGetWidth(img); // Breite in Pixeln var h: int64 := ImageGetHeight(img); // Höhe in Pixeln var ch: int64 := ImageGetChannels(img); // immer 4 // Pixel-Wert als 0xRRGGBBAA var px: int64 := ImagePixelAt(img, x, y); var r: int64 := (px >> 24) & 255; var g: int64 := (px >> 16) & 255; var b: int64 := (px >> 8) & 255; var a: int64 := px & 255; ---- ===== Core-API (std.image.core) ===== Für direkten Zugriff auf das Struct oder wenn ein Bild programmatisch erzeugt werden soll: ==== Allokation ==== // Alloziert GrfImage-Struct + RGBA-Pixel-Buffer (w*h*4 Bytes). // Gibt 0 bei ungültigen Dimensionen oder OOM zurück. var img: int64 := GrfImageAlloc(w, h); // Freigabe GrfImageFree(img); ==== Pixel-Operationen ==== // Lesen: gibt 0xRRGGBBAA zurück var px: int64 := GrfImageGetPixel(img, x, y); // Schreiben: rgba = 0xRRGGBBAA GrfImageSetPixel(img, x, y, rgba); // Alle Pixel mit einer Farbe füllen GrfImageClear(img, 0xFF0000FF); // vollständig rot, volle Deckkraft ==== Format-Erkennung ==== // Mindestens 4 Bytes (WebP/AVIF brauchen 12). // Gibt GRF_FMT_* zurück. var fmt: int64 := GrfDetectFormat(buf, len); if (fmt == GRF_FMT_PNG) { PngDecode(buf, len, img); } ---- ===== Format-spezifische Decoder ===== Alle Decoder haben dieselbe Signatur: // buf: Pointer auf Bildaten im Speicher // len: Länge des Puffers in Bytes // img: vorher alloziertes GrfImage (GrfImageAlloc oder leer via alloc(GRF_SIZE)) // Rückgabe: 1 = Erfolg, 0 = Fehler fn XxxDecode(buf: int64, len: int64, img: int64): int64; ^ Funktion ^ Unit ^ Format ^ | ''BmpDecode'' | ''std.image.bmp'' | Windows-Bitmap | | ''PngDecode'' | ''std.image.png'' | Portable Network Graphics | | ''JpegDecode'' | ''std.image.jpeg'' | JPEG / JFIF | | ''GifDecode'' | ''std.image.gif'' | Graphics Interchange Format | | ''TiffDecode'' | ''std.image.tiff'' | TIFF (LE und BE) | | ''WebpDecode'' | ''std.image.webp'' | WebP | | ''AvifDecode'' | ''std.image.avif'' | AVIF / AV1-basiert | ''std.image.image'' importiert alle Format-Units automatisch; wer nur einen bestimmten Decoder benötigt, kann die jeweilige Unit direkt importieren. ==== Zusätzliche Funktionen der Format-Units ==== Neben ''XxxDecode'' bringen einige Units mehr mit, als die Fassade anbietet: ^ Funktion ^ Unit ^ Beschreibung ^ | ''BmpDecodeFile(path, plen, img)'' | ''std.image.bmp'' | Direkt aus einer Datei laden — ebenso ''PngDecodeFile'', ''JpegDecodeFile'', ''GifDecodeFile'', ''TiffDecodeFile'', ''WebpDecodeFile'' | | ''PngEncode(img, outBuf, maxLen): int64'' | ''std.image.png'' | **Schreiben** — PNG erzeugen | | ''BmpEncode(img, outBuf, maxLen): int64'' | ''std.image.bmp'' | **Schreiben** — BMP erzeugen | | ''JpegMeta(buf, len, img): int64'' | ''std.image.jpeg'' | Maße und Kanäle in ''img'' schreiben, **ohne** die Pixel zu dekodieren | | ''WebpMeta(buf, len, img): int64'' | ''std.image.webp'' | dito für WebP | | ''AvifMeta(buf, len, img): int64'' / ''AvifDetect(buf, len): int64'' | ''std.image.avif'' | Maße lesen bzw. nur prüfen, ob es AVIF ist | | ''GifGetFrameCount(buf, len): int64'' | ''std.image.gif'' | Anzahl der Einzelbilder einer Animation | | ''GifDecodeFrame(buf, len, frameIdx, img): int64'' | ''std.image.gif'' | Ein bestimmtes Einzelbild dekodieren | > **Geschrieben werden können nur PNG und BMP.** Für die übrigen Formate gibt es Decoder, aber keinen Encoder. Und: Die Fassade ''ImageDecode'' liefert bei einer GIF-Animation stets das **erste** Bild — für die weiteren ''GifGetFrameCount'' und ''GifDecodeFrame'' direkt aufrufen. > > Wer nur Breite und Höhe braucht (Vorschau-Layout, Größenprüfung beim Upload), nimmt ''JpegMeta''/''WebpMeta''/''AvifMeta'' statt eines vollständigen Dekodierlaufs — das spart den Pixel-Puffer und die Rechenzeit. ---- ===== Quelldateien ===== ^ Datei ^ Inhalt ^ | ''std/image/core.lyx'' | GRF-00: GrfImage-Struct, Allokation, Pixel-Zugriff, Format-Erkennung | | ''std/image/image.lyx'' | GRF-08: Unified Facade (ImageDecode, ImageDecodeFromMem, Accessoren) | | ''std/image/bmp.lyx'' | GRF-01: BMP-Decoder | | ''std/image/png.lyx'' | GRF-02: PNG-Decoder | | ''std/image/jpeg.lyx'' | GRF-03: JPEG-Decoder | | ''std/image/gif.lyx'' | GRF-04: GIF-Decoder | | ''std/image/tiff.lyx'' | GRF-05: TIFF-Decoder | | ''std/image/webp.lyx'' | GRF-06: WebP-Decoder | | ''std/image/avif.lyx'' | GRF-07: AVIF-Decoder | Letzte Aktualisierung: 2026-06-15 Codebeispiele geprüft: gegen **lyxc 1.2.5C** übersetzt (Prüflauf 2026-09-08 über die gesamte Doku: 574 Vollprogramme, 0 echte Fehler; zusätzlich 5159 Aufrufe gegen die ''pub fn''-Signaturen in ''aurum/std'' gehalten, 0 Abweichungen).