Files
mabibli/MaBibli.Client/Scan/BancEssaiScan.cs
T
mathieuandClaude Opus 5 f7ad9582f6 Ajouter le scan camera du code-barres ISBN
Le decodage EAN-13/EAN-8 est fait en C# par ZXing.Net (IsbnScanner), conformement
a la decision actee dans CLAUDE.md : le JavaScript ne fournit que les pixels de la
camera, aucune logique de decodage ne lui est confiee.

Le scan se greffe en amont du flux d'ajout par ISBN existant : des qu'un code est
lu et reconnu comme ISBN-13 valide, la recherche de notices est declenchee sans
que l'utilisateur ait a retaper quoi que ce soit. La saisie manuelle reste
accessible en permanence, y compris quand la camera echoue.

Points traites explicitement :
- camera arriere par defaut (facingMode "environment", en "ideal" pour ne pas
  echouer sur un PC sans camera arriere) ;
- liberation de la camera a l'annulation, au succes et au demontage du composant ;
- cadence limitee a ~12 images/s et decodage restreint a la bande centrale
  reduite a 640 px de large : inutile de decoder chaque frame en pleine taille ;
- messages distincts pour permission refusee, absence de camera, camera occupee
  et contexte non securise (getUserMedia exige HTTPS ou localhost : une IP de
  reseau local en http ne marchera jamais, c'est une source de confusion garantie).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 23:32:05 +02:00

41 lines
1.6 KiB
C#

using System.Diagnostics;
using Microsoft.JSInterop;
namespace MaBibli.Client.Scan;
/// <summary>
/// Mesure du coût réel du décodage <b>dans le navigateur</b>.
///
/// CLAUDE.md ne dispose que de chiffres JIT x64 (0,53 ms/frame dans le pire cas) et d'une
/// extrapolation non vérifiée pour le WASM interprété (~5-10 ms/frame). Ce banc d'essai
/// donne le chiffre constaté, sur la machine de l'utilisateur, sans caméra ni code-barres.
///
/// On mesure volontairement le <b>pire cas</b> — une frame de bruit sans code-barres —
/// car c'est l'échec de décodage qui coûte le plus cher, et la quasi-totalité des frames
/// d'une caméra sont dans ce cas. C'est donc lui qui gouverne le framerate atteignable.
///
/// Depuis la console du navigateur :
/// <code>await DotNet.invokeMethodAsync('MaBibli.Client', 'MesurerScan', 640, 288, 20)</code>
/// </summary>
public static class BancEssaiScan
{
[JSInvokable("MesurerScan")]
public static double MesurerPireCasMs(int largeur, int hauteur, int iterations)
{
var rgba = new byte[largeur * hauteur * 4];
new Random(1234).NextBytes(rgba);
// Un tour à blanc : la première exécution paie l'initialisation de ZXing,
// qui n'a rien à voir avec le coût par frame en régime établi.
IsbnScanner.TryDecode(rgba, largeur, hauteur);
var depart = Stopwatch.GetTimestamp();
for (var i = 0; i < iterations; i++)
{
IsbnScanner.TryDecode(rgba, largeur, hauteur);
}
return Stopwatch.GetElapsedTime(depart).TotalMilliseconds / iterations;
}
}