Back to "KI---Powered Alt Text Generation mit meist schlüssigen ,.-llmlltText"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

Accessibility AI ASP.NET Florence-2 Image Processing NuGet

KI---Powered Alt Text Generation mit meist schlüssigen ,.-llmlltText

Tuesday, 25 November 2025

Möchten Sie nett erhalten?,-deskriptive alt Text für Bilder auf Ihren Aufstellungsorten oder jsut extrahieren Text von ihnen.? mostlylucid.llmalttext verwendet Microsoft ,' , Florence , -2 , Vision Sprache Modell zu erzeugen hoch , - , Qualität alt Text automatisch , die vollständig lokal auf Ihrem Computer , , , keine API-Tasten erforderlich

Hinweis: Ich muss diese doc jetzt aktualisieren die Nuget-Paket Wenn du aussiehst Hierher Sie können Download-und Nutzungsmöglichkeiten für eine raffinierte Demo-Website, die Sie herunterladen und verwenden, um diese mit Details in den kommenden Tagen aktualisieren

NuGet Lizenzierungsverbot

Einleitung

Alt text matters-.-Bildschirmleser hängen davon ab -,-SEO-Rankings-Faktor es in -MSC2- und es ist einfach die richtige Sache, für Zugänglichkeit zu tun Aber schreiben gute alt Text für Hunderte von Bildern-MSC5-, Dass - '-, wo die meisten von uns fallen kurz

Dieses Paket löst, dass Problem mit Microsoft .' s Florence . -2 vision language model ?- ? läuft ganz lokal auf Ihrem Computer ? , ? keine API-Tasten erforderlich ?

Quelle: : github-.-com./-scottgal./-mostlylucid-.-nugetverpackungen

Das Problem

Jede <img> Tag sollte einen bedeutungsvollen alt Text haben... aber in der Praxis...

  • Manuelles Schreiben ist mühsam Hunderte von Bildern bedeuten Arbeitsstunden
  • KI-APIs kosten Geld OpenAI Vision, Claude-, usw., addieren Sie schnell
  • Datenschutzbelange Vielleicht möchten Sie Bilder nicht an externe APIs senden.
  • Uneinheitliche Qualität Andere Leute schreiben alt Text anders

Was, wenn du hoch erzeugen könntest?- quality alt Text automatisch?MSC1 laufe komplett auf deiner eigenen Hardware.

Wie es funktioniert

Das Paket verwendet Microsoft-Modell Florenz-Modell über ONNX-Laufzeit.. Hier ist die Verarbeitungspipeline:.

flowchart TB
    subgraph Input[Image Sources]
        A[File Path]
        B[URL]
        C[Stream]
        D[Byte Array]
    end

    subgraph Processing[Florence-2 Pipeline]
        E[Image Preprocessing]
        F[Vision Encoder]
        G[Language Decoder]
    end

    subgraph Output[Results]
        H[Alt Text]
        I[OCR Text]
        J[Content Type]
    end

    A --> E
    B --> E
    C --> E
    D --> E
    E --> F
    F --> G
    G --> H
    G --> I
    G --> J

    style A stroke:#10b981,stroke-width:2px
    style B stroke:#10b981,stroke-width:2px
    style C stroke:#10b981,stroke-width:2px
    style D stroke:#10b981,stroke-width:2px
    style F stroke:#6366f1,stroke-width:2px
    style G stroke:#6366f1,stroke-width:2px
    style H stroke:#ec4899,stroke-width:2px
    style I stroke:#ec4899,stroke-width:2px
    style J stroke:#ec4899,stroke-width:2px

Wesentliche Merkmale

  • Lokale Ausführung Keine API-Anrufe keine Kosten keine Datenschutzbedenken
  • Modell ~800,MB Downloads einmalig gecached für immer
  • Mehrere Aufgabentypen Kurze Beschreibungen - ausführliche Beschreibungen
  • Inhaltsklassifizierung -, weiß wenn es ein Foto ist, ,, Diagramm, Screenshot usw. .,

Schnellstart

Installation

dotnet add package Mostlylucid.LlmAltText

Registerdienste

// Program.cs
builder.Services.AddAltTextGeneration();

Das ist es .. Der erste Lauf lädt das Florence-Modell -2.

Alt-Text generieren

public class ImageController : ControllerBase
{
    private readonly IImageAnalysisService _imageAnalysis;

    public ImageController(IImageAnalysisService imageAnalysis)
    {
        _imageAnalysis = imageAnalysis;
    }

    [HttpPost("analyze")]
    public async Task<IActionResult> Analyze(IFormFile image)
    {
        using var stream = image.OpenReadStream();
        var altText = await _imageAnalysis.GenerateAltTextAsync(stream);

        return Ok(new { altText });
    }
}

Mehrere Eingangsquellen

Der Dienst akzeptiert Bilder von überall aus --Dateien, ,-URLs, ,-Streams oder Byte-Arrays

Aus dem Dateipfad

var altText = await _imageAnalysis.GenerateAltTextFromFileAsync("/images/photo.jpg");

Von der URL

var altText = await _imageAnalysis.GenerateAltTextFromUrlAsync(
    "https://example.com/image.png");

Aus Stream

using var stream = file.OpenReadStream();
var altText = await _imageAnalysis.GenerateAltTextAsync(stream);

Von Byte Array

var bytes = await httpClient.GetByteArrayAsync(imageUrl);
var altText = await _imageAnalysis.GenerateAltTextAsync(bytes);

Aufgabentypen .: . Kontrolle der Detailebene

Florence--2-Unterstützt drei Bildunterschriftsmodi - . Wählen Sie basierend auf Ihren Bedürfnissen -:-

// Brief - "A dog sitting on grass"
var brief = await _imageAnalysis.GenerateAltTextAsync(stream, "CAPTION");

// Detailed - "A golden retriever sitting on green grass in a park"
stream.Position = 0;
var detailed = await _imageAnalysis.GenerateAltTextAsync(stream, "DETAILED_CAPTION");

// Most detailed (default) - Full accessibility description
stream.Position = 0;
var full = await _imageAnalysis.GenerateAltTextAsync(stream, "MORE_DETAILED_CAPTION");
// "A happy golden retriever with light fur sitting on lush green grass
//  in a sunny park, with trees visible in the background."

Wann Sie jedes Mal verwenden müssen

Aufgabentyp für die Aufgabenstellung am besten für die Bearbeitung |-----------|----------| | CAPTION |-Tumbnails,-dekorative Bilder,-schnelle Tooltips | DETAILED_CAPTION Soziale Medien Grundlegende Zugänglichkeit | MORE_DETAILED_CAPTION Weitere Informationen: http:www.cordis.lu/index.html

OCR-Textextraktion

Florence--2 , kann auch Text aus Bildern extrahieren, die für Screenshots nützlich sind., , Dokumente und Diagramme.

// Extract text only
var extractedText = await _imageAnalysis.ExtractTextAsync(stream);

// Get both alt text and extracted text
var (altText, ocrText) = await _imageAnalysis.AnalyzeImageAsync(stream);

Console.WriteLine($"Alt: {altText}");
Console.WriteLine($"OCR: {ocrText}");

Einstufung nach Inhaltstyp

Nicht alle Bilder sind gleich..-Ein Foto braucht beschreibenden alt text, ein Dokument benötigt seinen Text Inhalt.

var result = await _imageAnalysis.AnalyzeWithClassificationAsync(stream);

Console.WriteLine($"Type: {result.ContentType}");        // e.g., "Photograph"
Console.WriteLine($"Confidence: {result.ContentTypeConfidence:P0}"); // e.g., "87%"
Console.WriteLine($"Has Text: {result.HasSignificantText}");

Umgang mit verschiedenen Inhaltstypen

var result = await _imageAnalysis.AnalyzeWithClassificationAsync(stream);

switch (result.ContentType)
{
    case ImageContentType.Document:
        // Documents - prioritize extracted text
        return result.ExtractedText;

    case ImageContentType.Screenshot:
        // Screenshots - combine description with UI text
        return result.HasSignificantText
            ? $"{result.AltText}. Text visible: {result.ExtractedText}"
            : result.AltText;

    case ImageContentType.Chart:
        // Charts - describe the visualization plus data
        return $"{result.AltText}. Data: {result.ExtractedText}";

    case ImageContentType.Photograph:
    default:
        // Photos - just the description
        return result.AltText;
}

Angabe des Inhaltstyps

Beschreibung des Musters des Modells |------|-------------|---------| | Photograph Fotos von der realen - Welt Menschen Landschaften , Produkte | | Document ,| , Text , - , schwerer Inhalt , | , PDFs , , , Formulare und Artikel | Screenshot Software erfasst Websites von |, , und , Apps | Chart Datenvisualisierungen Diagramme Diagramme Tabellen | Illustration Zeichentrickfilme, Zeichentrick-Symbole und -Icons | Diagram Technische Zeichnungen Technische Zeichnungen Flussdiagramme | Unknown Nicht klassifizierte Kantenfälle

Der Auto Alt Text TagHelper

Hier, wo es interessant wird Der TagHelper erzeugt automatisch alt Text für jeden <img> Tag fehlt eins zum Renderzeitpunkt

Einrichtung

// Program.cs
builder.Services.AddAltTextGeneration(options =>
{
    options.EnableTagHelper = true;
    options.EnableDatabase = true;  // Cache results
    options.DbProvider = AltTextDbProvider.Sqlite;
    options.SqliteDbPath = "./alttext.db";
});

var app = builder.Build();
await app.Services.MigrateAltTextDatabaseAsync();

Registrieren Sie den TagHelper in _ViewImports.cshtml:

@addTagHelper *, Mostlylucid.LlmAltText

Wie es funktioniert

flowchart LR
    subgraph Razor[Razor View Rendering]
        A[img tag found]
        B{Has alt attribute?}
        C[Skip - use existing]
        D{In cache?}
        E[Return cached]
        F[Fetch image]
        G[Generate alt text]
        H[Cache result]
        I[Render with alt]
    end

    A --> B
    B -->|Yes| C
    B -->|No| D
    D -->|Yes| E
    D -->|No| F
    F --> G
    G --> H
    H --> I
    E --> I

    style A stroke:#10b981,stroke-width:2px
    style B stroke:#6366f1,stroke-width:2px
    style G stroke:#ec4899,stroke-width:2px
    style I stroke:#8b5cf6,stroke-width:2px

Was verarbeitet wird

<!-- NO ALT - Will be processed -->
<img src="https://example.com/photo.jpg" />

<!-- HAS ALT - Skipped (respects your text) -->
<img src="https://example.com/photo.jpg" alt="My custom description" />

<!-- EMPTY ALT - Skipped (decorative image per a11y standards) -->
<img src="https://example.com/decorative.jpg" alt="" />

<!-- EXPLICIT SKIP - Skipped -->
<img src="https://example.com/photo.jpg" data-skip-alt="true" />

<!-- DATA URI - Skipped (can't fetch) -->
<img src="data:image/png;base64,..." />

<!-- RELATIVE PATH - Skipped (needs absolute URL) -->
<img src="/images/photo.jpg" />

Domänenbeschränkungen

Für die Sicherheit können Sie einschränken, welche Domains der TagHelper aus dem : holen wird

options.AllowedImageDomains = new List<string>
{
    "mycdn.example.com",
    "images.mysite.org",
    "cdn.githubusercontent.com"
};

Datenbank-Caching

Ohne Caching... jede Seite Render würde alt Text regenerieren... das ist langsam und verschwenderisch.... die Datenbank speichert Ergebnisse, die von der Bild-URL geschlüsselt werden.

SQLite-Entwicklung – )

builder.Services.AddAltTextGeneration(options =>
{
    options.EnableDatabase = true;
    options.DbProvider = AltTextDbProvider.Sqlite;
    options.SqliteDbPath = "./alttext.db";
    options.CacheDurationMinutes = 60;
});

PostgreSQL Produktion

builder.Services.AddAltTextGeneration(options =>
{
    options.EnableDatabase = true;
    options.DbProvider = AltTextDbProvider.PostgreSql;
    options.ConnectionString = Configuration.GetConnectionString("AltTextDb");
});

Einrichtungsreferenz

builder.Services.AddAltTextGeneration(options =>
{
    // Model location (~800MB downloaded here)
    options.ModelPath = "./models";

    // Default task type for alt text generation
    options.DefaultTaskType = "MORE_DETAILED_CAPTION";

    // Maximum word count for alt text
    options.MaxWords = 90;

    // Enable detailed logging
    options.EnableDiagnosticLogging = true;

    // TagHelper settings
    options.EnableTagHelper = true;
    options.EnableDatabase = true;
    options.AutoMigrateDatabase = true;

    // Database provider
    options.DbProvider = AltTextDbProvider.Sqlite;
    options.SqliteDbPath = "alttext.db";
    // or
    options.DbProvider = AltTextDbProvider.PostgreSql;
    options.ConnectionString = "Host=localhost;Database=alttext;...";

    // Security
    options.AllowedImageDomains = new List<string> { "cdn.example.com" };
    options.SkipSrcPrefixes = new List<string> { "data:", "blob:" };

    // Caching
    options.CacheDurationMinutes = 60;
});

Echtes Beispiel für die Batch-Verarbeitung von :

Hier ist, wie ich es benutze, um Bilder beim Importieren von Blogposts zu verarbeiten.

public class ImageProcessor
{
    private readonly IImageAnalysisService _imageAnalysis;
    private readonly ILogger<ImageProcessor> _logger;

    public ImageProcessor(
        IImageAnalysisService imageAnalysis,
        ILogger<ImageProcessor> logger)
    {
        _imageAnalysis = imageAnalysis;
        _logger = logger;
    }

    public async Task ProcessMarkdownImagesAsync(string markdownPath)
    {
        var imageDir = Path.Combine(Path.GetDirectoryName(markdownPath)!, "images");
        if (!Directory.Exists(imageDir)) return;

        var images = Directory.GetFiles(imageDir, "*.*")
            .Where(f => IsImageFile(f));

        foreach (var imagePath in images)
        {
            try
            {
                var result = await _imageAnalysis
                    .AnalyzeWithClassificationFromFileAsync(imagePath);

                _logger.LogInformation(
                    "Processed {File}: {Type} ({Confidence:P0})",
                    Path.GetFileName(imagePath),
                    result.ContentType,
                    result.ContentTypeConfidence);

                // Store alt text for later use
                await SaveAltTextAsync(imagePath, result.AltText);
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "Failed to process {File}", imagePath);
            }
        }
    }

    private static bool IsImageFile(string path)
    {
        var ext = Path.GetExtension(path).ToLowerInvariant();
        return ext is ".jpg" or ".jpeg" or ".png" or ".gif" or ".webp" or ".bmp";
    }
}

Leistungsbeurteilungen

Was zu erwarten ist

Metrisches Messergebnis Typischer Wert |--------|--------------| Erster Lauf langsamerer Download von (~800MB Modelllast (msk) Bildbearbeitungs- und -bearbeitungsgeräte für die Bildverarbeitung Verwendung des Speichers von |, empfohlen für 2, Laufwerksspeicher ~800MB für Modelle |

Tipps für die Produktion

// 1. Register as Singleton (model load is expensive)
builder.Services.AddAltTextGeneration(); // Already singleton internally

// 2. Check readiness before processing
if (!_imageAnalysis.IsReady)
{
    return StatusCode(503, "AI model still initializing");
}

// 3. Use cancellation tokens for timeouts
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var altText = await _imageAnalysis.GenerateAltTextFromUrlAsync(url, cts.Token);

// 4. Process in batches, not parallel (memory constraints)
foreach (var image in images)
{
    await ProcessImageAsync(image); // Sequential is safer
}

OpenTelemetrie Integration

Das Paket beinhaltet eingebaute ,-'in Tracing- , :'

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing =>
    {
        tracing.AddSource("Mostlylucid.LlmAltText");
    });

Verfolgte Tätigkeiten

  • llmalttext.generate_alt_text
  • llmalttext.extract_text
  • llmalttext.analyze_image
  • llmalttext.classify_content_type

Gesundheitskontrollen

Fügen Sie einen Gesundheitscheck hinzu, um den Status des Modells zu überwachen.

public class AltTextHealthCheck : IHealthCheck
{
    private readonly IImageAnalysisService _service;

    public AltTextHealthCheck(IImageAnalysisService service)
        => _service = service;

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
        return Task.FromResult(_service.IsReady
            ? HealthCheckResult.Healthy("Florence-2 model ready")
            : HealthCheckResult.Unhealthy("Model not initialized"));
    }
}

// Registration
builder.Services.AddHealthChecks()
    .AddCheck<AltTextHealthCheck>("alttext");

Fehlerbehebung

Modell-Download fehlgeschlagen

Error: Failed to download model files

Lösungen

  • Internet-Verbindung überprüfen
  • Firewall überprüfen ermöglicht Hugging Face Downloads
  • Vergewissern Sie sich, dass der Festplattenspeicher von ~800.MB verfügbar ist
  • Schreibrechte überprüfen auf ModelPath

Dienst nicht bereit

_imageAnalysis.IsReady // Returns false

Lösungen

  • Warten Sie auf Modellinitialisierung
  • Protokolle auf Initialisierungsfehler überprüfen
  • Überprüfe ausreichenden Speicher

Schlechte Qualität Alt Text

Lösungen

  • Verwendung MORE_DETAILED_CAPTION (-default-)-
  • Stellen Sie sicher, dass Eingabebilder klar sind
  • Prüfen Bild ist nicht zu klein oder verschwommen

TagHelper funktioniert nicht

Lösungen

  • Überprüfen EnableTagHelper = true
  • Kontrolle @addTagHelper in der _ViewImports.cshtml
  • Absolute URLs verwenden .( .relative Pfade werden übersprungen .
  • Kontrolle AllowedImageDomains Konfiguration

Best Practices für Barrierefreiheit

Generierter Alttext ist ein Ausgangspunkt für beste Ergebnisse

  1. Überprüfung des Outputs Verifizieren Sie die Genauigkeit
  2. Halten Sie es kurz Maximale Anzahl der Wörter
  3. Deskriptiv sein Einschließlich Themen, Aktionen und Kontext
  4. Redundanz vermeiden Beginnen Sie mit dem Bild von ..."
  5. Überlegener Zweck Text sollte der Rolle des Bildes auf der Seite dienen.
  6. Verwenden Sie leere Alt für dekorative Satz alt="" für rein dekorative Bilder
  7. Sichtbarer Text einschließen Wenn das Bild Text enthält, ist es mit einzufügen.

Schlußfolgerung

Mostlylucid.LlmAltText bringt AIR- powered accessibility zu Ihren Anwendungen ohne die Kosten oder Datenschutz-Bedenken von externen APIs. Der TagHelper macht es besonders einfach. <img> Tags gewinnen automatisch alt text

Das Paket ist Unlicense, öffentliche Domäne, also tun Sie, was immer Sie wollen.

Aufkommen

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.