Θέλετε να πάρετε ωραίο, περιγραφικό κείμενο για τις εικόνες στις ιστοσελίδες σας ή κείμενο εκχύλισμα jsut από αυτούς; mostlylucid.llmalttext χρησιμοποιεί το μοντέλο γλώσσας όρασης Florence-2 της Microsoft για να παράγει αυτόματα υψηλής ποιότητας κείμενο alt - τρέχει εξ ολοκλήρου τοπικά στη μηχανή σας, δεν απαιτείται API κλειδιά.
Σημείωση: Πρέπει να ενημερώσετε αυτό το έγγραφο τώρα πακέτο nugetName Αν κοιτάξετε έξω... Ορίστε. θα καλέσετε ένα ωραίο demo site που μπορείτε να κατεβάσετε και να χρησιμοποιήσετε. Θα ενημερώσω αυτό με λεπτομέρειες τις επόμενες ημέρες.
Alt θέματα κειμένου. Οι αναγνώστες οθόνης εξαρτώνται από αυτό, SEO κατατάσσει παράγοντα σε, και είναι απλά το σωστό πράγμα να κάνουμε για την προσβασιμότητα. Αλλά γράφοντας καλό κείμενο για εκατοντάδες εικόνες; Αυτό είναι όπου οι περισσότεροι από εμάς υπολείπονται.
Αυτό το πακέτο λύνει το πρόβλημα χρησιμοποιώντας το μοντέλο γλώσσας όρασης Florence-2 της Microsoft - τρέχει εξ ολοκλήρου τοπικά στη μηχανή σας, δεν απαιτείται API κλειδιά.
Πηγαίος κώδικας: github.com/scottgal/κυρίως διαυγή.nuget packages
Κάθε <img> Αλλά στην πράξη:
Κι αν μπορούσες να παράγεις υψηλής ποιότητας κείμενο αυτόματα, τρέχοντας εξ ολοκλήρου στο δικό σου υλικό;
Το πακέτο χρησιμοποιεί το μοντέλο της Microsoft Florence-2 μέσω του ONNX runtime.
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
Βασικά χαρακτηριστικά:
dotnet add package Mostlylucid.LlmAltText
// Program.cs
builder.Services.AddAltTextGeneration();
Το πρώτο τρέξιμο κατεβάζει το μοντέλο Φλόρενς-2 (~800MB), και μετά είσαι έτοιμος να φύγεις.
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 });
}
}
Η υπηρεσία δέχεται εικόνες από οπουδήποτε - αρχεία, διευθύνσεις URL, ρεύματα ή δέσμες byte.
var altText = await _imageAnalysis.GenerateAltTextFromFileAsync("/images/photo.jpg");
var altText = await _imageAnalysis.GenerateAltTextFromUrlAsync(
"https://example.com/image.png");
using var stream = file.OpenReadStream();
var altText = await _imageAnalysis.GenerateAltTextAsync(stream);
var bytes = await httpClient.GetByteArrayAsync(imageUrl);
var altText = await _imageAnalysis.GenerateAltTextAsync(bytes);
Η Φλωρεντία-2 υποστηρίζει τρεις τρόπους λεζάντας. Επιλέξτε με βάση τις ανάγκες σας:
// 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."
Πότε να χρησιμοποιήσετε το καθένα:
Ο τύπος εργασίας είναι ο καλύτερος για τον τύπο εργασίας.
|-----------|----------|
| CAPTION Εικόνες διακοσμητικές, γρήγορες εργαλειοθήκες
| DETAILED_CAPTION Τα μέσα κοινωνικής δικτύωσης, βασική προσβασιμότητα
| MORE_DETAILED_CAPTION □ Πλήρης προσβασιμότητα, αναγνώστης οθόνης (συνιστάται) □
Η Φλωρεντία-2 μπορεί επίσης να εξάγει κείμενο από εικόνες - χρήσιμο για στιγμιότυπα οθόνης, έγγραφα και διαγράμματα.
// 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}");
Μια φωτογραφία χρειάζεται περιγραφικό κείμενο, ένα έγγραφο χρειάζεται το περιεχόμενό του. Το χαρακτηριστικό ταξινόμησης σας βοηθά να χειριστείτε το καθένα κατάλληλα:
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}");
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;
}
Ο τύπος είναι ο τύπος
|------|-------------|---------|
| Photograph Φωτογραφίες Real-world Άνθρωποι, τοπία, προϊόντα
| Document Το περιεχόμενο του κειμένου είναι βαρύ, σε μορφή PDF, σε μορφή, σε μορφή αντικειμένων.
| Screenshot Το λογισμικό αιχμαλωτίζει □ UI, ιστοσελίδες, εφαρμογές
| Chart Απεικονίσεις στοιχείων & γραφήματα, διαγράμματα πίτας, πίνακες & rsquo;
| Illustration Εικονίδια, εικονίδια, έργα τέχνης, ζωγραφιές
| Diagram □ Τεχνικά σχέδια _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
| Unknown Αταξινόμητες υποθέσεις
Εδώ είναι όπου γίνεται ενδιαφέρον. Το TagHelper παράγει αυτόματα alt κείμενο για κάθε <img> Λείπει μια ετικέτα - κατά την απόδοση του χρόνου.
// 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();
Εγγραφή του TagHelper σε _ViewImports.cshtml:
@addTagHelper *, Mostlylucid.LlmAltText
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
<!-- 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" />
Για την ασφάλεια, μπορείτε να περιορίσετε ποιους τομείς το TagHelper θα φέρει από:
options.AllowedImageDomains = new List<string>
{
"mycdn.example.com",
"images.mysite.org",
"cdn.githubusercontent.com"
};
Χωρίς το caching, κάθε σελίδα θα αναγεννούσε το κείμενο. Αυτό είναι αργό και σπάταλο. Η βάση δεδομένων αποθηκεύει αποτελέσματα κλειδιά από URL εικόνας.
builder.Services.AddAltTextGeneration(options =>
{
options.EnableDatabase = true;
options.DbProvider = AltTextDbProvider.Sqlite;
options.SqliteDbPath = "./alttext.db";
options.CacheDurationMinutes = 60;
});
builder.Services.AddAltTextGeneration(options =>
{
options.EnableDatabase = true;
options.DbProvider = AltTextDbProvider.PostgreSql;
options.ConnectionString = Configuration.GetConnectionString("AltTextDb");
});
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;
});
Εδώ είναι πώς το χρησιμοποιώ για να επεξεργαστώ τις εικόνες κατά την εισαγωγή αναρτήσεων blog:
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";
}
}
Μετρική τιμή Τυπική αξία |--------|--------------| ~ Πρώτη εκτέλεση ~ Πιο αργό (~ 800MB model download) ~ Φόρτωση μοντέλου 1-3 δευτερόλεπτα Μεταποίηση ανά εικόνα 500-2000ms Η χρήση μνήμης συνιστάται 2GB+. Χώρος δίσκου για μοντέλα ~800MB
// 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
}
Η συσκευασία περιλαμβάνει ενσωματωμένο εντοπισμό:
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
tracing.AddSource("Mostlylucid.LlmAltText");
});
Εντοπισμένες δραστηριότητες:
llmalttext.generate_alt_textllmalttext.extract_textllmalttext.analyze_imagellmalttext.classify_content_typeΠροσθέστε έναν έλεγχο υγείας για την παρακολούθηση της κατάστασης μοντέλου:
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");
Error: Failed to download model files
Λύσεις:
ModelPath_imageAnalysis.IsReady // Returns false
Λύσεις:
Λύσεις:
MORE_DETAILED_CAPTION (προκαθορισμένο)Λύσεις:
EnableTagHelper = true@addTagHelper ί ας _ViewImports.cshtmlAllowedImageDomains διαμόρφωσηΔημιουργημένο κείμενο alt είναι ένα σημείο εκκίνησης. Για καλύτερα αποτελέσματα:
alt="" για καθαρά διακοσμητικές εικόνεςMostlylucid.LlmAltText φέρνει τη δυνατότητα πρόσβασης AI στις εφαρμογές σας .NET χωρίς το κόστος ή την προστασία της ιδιωτικής ζωής των εξωτερικών APIs. Το TagHelper το καθιστά ιδιαίτερα εύκολο - απλά ενεργοποιήστε το και σας <img> Οι ετικέτες κερδίζουν αυτόματο κείμενο alt.
Το πακέτο είναι Unlicense (δημόσιος τομέας), οπότε κάντε ό, τι θέλετε με αυτό.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.