using ZXing; using ZXing.Common; namespace MaBibli.Client.Scan; /// /// Décodage d'un code-barres EAN-13 / EAN-8 à partir d'un buffer de pixels RGBA. /// /// Décision actée dans CLAUDE.md : le décodage reste **entièrement en C#** (ZXing.Net), /// le JavaScript ne sert qu'à fournir les pixels de la caméra. Cette classe ne dépend /// donc ni du navigateur, ni de Blazor : elle est réutilisable telle quelle hors WASM /// (app native, décodage d'une photo côté serveur, scan en masse). /// public static class IsbnScanner { // ZXing.Net n'est pas thread-safe sur ce lecteur, mais le WASM est mono-thread // et la boucle de scan est séquentielle : une instance partagée suffit et évite // de reconstruire les hints à chaque frame. private static readonly MultiFormatReader Reader = new() { Hints = new Dictionary { [DecodeHintType.POSSIBLE_FORMATS] = new List { BarcodeFormat.EAN_13, BarcodeFormat.EAN_8, }, [DecodeHintType.TRY_HARDER] = true, }, }; /// /// Tente de décoder un code-barres. Renvoie le texte brut du code, ou null /// si la frame n'en contient aucun de lisible — cas très majoritaire en usage réel. /// /// Buffer brut issu de ctx.getImageData(...).data (4 octets par pixel). public static string? TryDecode(byte[] rgba, int largeur, int hauteur) { ArgumentNullException.ThrowIfNull(rgba); if (largeur <= 0 || hauteur <= 0 || rgba.Length < largeur * hauteur * 4) { return null; } // RGBLuminanceSource consomme directement le buffer du canvas : // aucune bibliothèque d'image nécessaire (ni SkiaSharp, ni ImageSharp). var source = new RGBLuminanceSource( rgba, largeur, hauteur, RGBLuminanceSource.BitmapFormat.RGBA32); // La version .NET de ZXing renvoie null sur échec (pas d'exception). return Reader.decode(new BinaryBitmap(new HybridBinarizer(source)))?.Text; } }