IRONSOFTWAREHOME
影片

從Windows.Media.Ocr遷移至IronOCR

Kannaopat Udonpant
Kannapat Udonpant
Updated: 2026年8月1日

本指南提供 .NET 開發人員從 Windows.Media.Ocr 遷移到 IronOCR 的逐步遷移路徑。 它涵蓋了名稱空間移除、項目文件更改、遷移過程中最常出現的模式的程式碼遷移範例,以及驗證完成過渡的實際清單。

為什麼要從 Windows.Media.Ocr (UWP/WinRT OCR) 遷移

Windows.Media.Ocr 在其邊界內運作良好。 那些邊界很狹窄,項目通常會超出這些邊界。 團隊遷移的原因可預測地分為幾類。

Windows TFM 阻止所有非 Windows 目標。 項目文件必須聲明一個 net*-windows* 目標框架標識符,才能在編譯時解析 Windows.Media.Ocr 名稱空間。該聲明不是運行時標誌,而是構建約束,傳遞給引用您的每個項目。 共享的 OCR 服務庫、Web API、部署到 Linux 的後台工作程式——它們都繼承了這一約束。 移除它意味著要移除 Windows.Media.Ocr。

語言可用性在運行時由操作系統決定,而不是在編譯時由開發人員決定。 當主機機器上缺少所需的語言包時,OcrEngine.TryCreateFromLanguage 返回空值。開發人員無法從程式碼中安裝語言包,無法將其捆綁到應用程式二進位檔案中,也無法提供後備模式。 在自動化環境中——構建代理、CI 運行器、最小化的雲 VM、容器——很少安裝語言包。 因缺少語言包而導致的生產故障無法通過查看程式碼復現; 它們需要檢查目標機器的操作系統配置。

無預處理意味著對於次優輸入沒有恢復路徑。 API 接受 SoftwareBitmap 並生成文字。 從那兩個點改善影像品質完全是開發人員的責任,使用的是Windows Imaging Component APIs ,這些 API 本身也是僅限於 Windows 使用。 手機照片、不對齊的平板掃描和影印文件無聲地降低準確性,沒有內建機制來診斷或改進結果。

PDF 是企業工作流程中最常見的文件格式。 Windows.Media.Ocr 沒有 PDF 輸入路徑。 要處理掃描的 PDF 需要一個外部渲染器、按頁的光柵化,以及手動結果組合。 渲染器增加了一個依賴性、許可考量和一個獨立的故障表面——這正是 "免費內建的" 庫要避免的複雜性。

伺服器端部署在結構上不支持。 Windows.Media.Ocr 針對客戶端應用程式。 在 Windows Server 上運行它需要桌面體驗功能包,這會增加 VM 成本和基礎設施複雜性。 Docker 部署是不可能的。 基於 Linux 的 Azure Functions、AWS Lambda 和任何基於 Linux 的容器負載無法引用 API。

WinRT 非同步堆疊與標準 .NET 模式不相容。 在開始讀取單個字元之前,需要六個或更多鏈式的 await 呼叫——RecognizeAsync。 將該鏈整合到後台服務中、平行.ForEach 迴圈或標準 ASP.NET 控制器中都是笨拙的。 WinRT IAsyncOperation 機械坐在其下,而與 .NET 的 Task 模型的互動在非 UI 上下文中建立了微妙的邊界情況。

根本問題

Windows.Media.Ocr 中的語言可用性是一個運行時未知數,無法在部署時解決:

// Windows.Media.Ocr: language availability decided by OS admin, not the developer
// Returns null on any machine without the language pack installed
var engine = OcrEngine.TryCreateFromLanguage(
    new Windows.Globalization.Language("ja-JP"));

if (engine == null)
    throw new InvalidOperationException(
        "Japanese OCR unavailable — install the Japanese language pack in Windows Settings.");
//不是recovery path.不是bundled model.不是fallback.
C#
// IronOCR: language availability is a NuGet package, not an OS configuration
// dotnet add package IronOcr.Languages.Japanese
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.Japanese;
var result = ocr.Read("invoice.jpg"); // Works on any OS, any machine
Console.WriteLine(result.Text);
C#

##IronOCR與 Windows.Media.Ocr (UWP/WinRT OCR):功能比較

下表涵蓋了與遷移決策相關的完整功能面。

功能Windows.Media.OcrIronOCR
平台:Windows 10/11
平台:Windows Server有限 (需要桌面體驗)
平台:Linux不是
平台:macOS不是
平台:Docker 容器不是
平台:Azure Functions (Linux)不是
平台:AWS Lambda不是
項目 TFM 要求需要 net*-windows*無 (標準 TFM)
安裝Windows 內建 (無 NuGet)單一 NuGet 包 (IronOcr)
影像輸入 (JPG, PNG, BMP)是 (經由 WinRT pipeline)
PDF輸入不是是(本地)
多頁 TIFF 輸入不是
流和字節陣列輸入否 (僅限 StorageFile)
語言來源系統安裝的語言包125+ 捆綁的 NuGet 包
語言便攜性否 (機器依賴)是 (和應用程式一起部署)
多語言同時支援不是
預處理:自動校正傾斜不是是 (input.Deskew())
預處理:去噪不是是 (input.DeNoise())
預處理:對比度不是是 (input.Contrast())
預處理:二維化不是是 (input.Binarize())
可搜尋的PDF輸出不是是 (result.SaveAsSearchablePdf())
每單字信心水準不是是 (word.Confidence)
結構化輸出 (段,行,字)僅限行級頁、段落、行、字、字元
OCR 過程中的條碼讀取不是
基於區域的OCR不是是 (CropRectangle)
同步 OCR 路徑不是
執行緒安全的並行處理有限全部
商業支持否 (Windows 平台團隊)
許可模式免費 (Windows 內建)永久 ($999 Lite, $1,499 Pro, $2,999 Enterprise)

快速開始:從 Windows.Media.Ocr (UWP/WinRT OCR) 到IronOCR遷移

步驟1:替換NuGet包

Windows.Media.Ocr 沒有 NuGet 套件——它是 Windows Runtime 的一部分,通過 Windows TFM 解析。 移除它意味著要從項目文件中移除特定於 Windows 的名稱空間引用和可能的 Windows TFM。

從所有源文件中移除 Windows.Media.Ocr 名稱空間:

# Audit all files referencing Windows OCR namespaces
grep -r "Windows.Media.Ocr\|Windows.Graphics.Imaging\|Windows.Storage" --include="*.cs" .
SHELL

安裝 IronOCR:

dotnet add package IronOcr

IronOCR NuGet 套件 針對 net8.0net9.0,沒有特定於平台的 TFM。 在移除 Windows OCR 名稱空間後,將項目文件中的 <TargetFramework>net8.0-windows10.0.19041.0 更新為 net8.0 (或適當的版本),前提是項目中沒有其他 WinRT API。

步驟2:更新命名空間

用單個IronOCR名稱空間替換三個 Windows OCR 名稱空間:

// Before (Windows.Media.Ocr)
using Windows.Media.Ocr;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Globalization;

// After (IronOCR)
using IronOcr;
C#

步驟3:初始化許可證

在應用程式啟動時新增許可初始化呼叫——在 Startup.cs 或應用程式主機構建器中:

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

免費試用密鑰可以從 IronOCR 許可頁面 獲得,並可移除試用水印以便於評估。

程式碼遷移範例

在後台服務中替換 WinRT 非同步鏈

Windows.Media.Ocr 在識別開始之前需要至少六個鏈式非同步操作。 在進程文件隊列的後台服務中,該鏈在迴圈中運行——SoftwareBitmap 處理、空值檢查和 WinRT IAsyncOperation 互操作在每次迭代中都會增加摩擦。

Windows.Media.Ocr 方法:

// Windows.Media.Ocr: full async chain required per document
// Requires net8.0-windows10.0.19041.0 TFM — cannot deploy to Linux workers
public async Task<List<string>> ProcessQueueAsync(IEnumerable<string> imagePaths)
{
    var engine = OcrEngine.TryCreateFromUserProfileLanguages();
    if (engine == null)
        throw new InvalidOperationException("No OCR language pack installed on this machine.");

    var results = new List<string>();

    foreach (var path in imagePaths)
    {
        // Each document: 4 async steps before RecognizeAsync
        var file = await StorageFile.GetFileFromPathAsync(path);
        using var stream = await file.OpenAsync(FileAccessMode.Read);
        var decoder = await BitmapDecoder.CreateAsync(stream);
        var bitmap = await decoder.GetSoftwareBitmapAsync();

        var ocrResult = await engine.RecognizeAsync(bitmap);
        results.Add(ocrResult.Text);

        bitmap.Dispose();
    }

    return results;
}
C#

IronOCR方法:

// IronOCR: one call per document, no WinRT, no SoftwareBitmap, no null checks
// Runs on Windows, Linux, macOS, Docker — same binary, no TFM change
public List<string> ProcessQueue(IEnumerable<string> imagePaths)
{
    var results = new List<string>();

    foreach (var path in imagePaths)
    {
        var result = new IronTesseract().Read(path);
        results.Add(result.Text);
    }

    return results;
}
C#

IronOCR 版本消除了 StorageFile 回合、SoftwareBitmap 生命週期和空值檢查防護。 對於非同步原生服務,IronOCR 提供非同步路徑,可以幹淨地整合進 Task 為基礎的管道中,無需 WinRT 互操作開銷。 IronTesseract 設置指南涵蓋了高吞吐量隊列場景中的實例生命週期建議。

消除軟體位圖轉換以進行記憶體中影像資料

已經具有記憶體中影像資料的應用程式——來自網路下載、資料庫 blob 或相機捕捉回調——必須將該資料轉換為 SoftwareBitmap 才能讓 Windows.Media.Ocr 進行處理。 該轉換路徑通過 BitmapDecoder,需要一個流,這意味著將字節陣列複製到 MemoryStream 中。IronOCR直接接受字節陣列和流。

Windows.Media.Ocr 方法:

// Windows.Media.Ocr: byte array must travel through WinRT stream → BitmapDecoder → SoftwareBitmap
public async Task<string> RecognizeFromBytesAsync(byte[] imageBytes)
{
    var engine = OcrEngine.TryCreateFromUserProfileLanguages();
    if (engine == null)
        throw new InvalidOperationException("No OCR language available.");

    // Copy byte array into InMemoryRandomAccessStream (WinRT type)
    using var ras = new Windows.Storage.Streams.InMemoryRandomAccessStream();
    using var writer = new Windows.Storage.Streams.DataWriter(ras);
    writer.WriteBytes(imageBytes);
    await writer.StoreAsync();
    ras.Seek(0);

    var decoder = await BitmapDecoder.CreateAsync(ras);
    var bitmap = await decoder.GetSoftwareBitmapAsync();

    var result = await engine.RecognizeAsync(bitmap);
    bitmap.Dispose();
    return result.Text;
}
C#

IronOCR方法:

// IronOCR: byte array loads directly into OcrInput — no conversion, no WinRT types
public string RecognizeFromBytes(byte[] imageBytes)
{
    using var input = new OcrInput();
    input.LoadImage(imageBytes); // direct byte array load

    var result = new IronTesseract().Read(input);
    return result.Text;
}
C#

Windows.Media.Ocr 路徑需要 InMemoryRandomAccessStream——這是一個無法在 Windows 之外實例化的 WinRT 型別,還有 BitmapDecoderSoftwareBitmap。 而IronOCR路徑使用 OcrInput.LoadImage(byte[]) 並在兩行中產生結果。 流輸入指南涵蓋基於 Stream 的載入模式,其簡單性與字節陣列輸入相同。

無需操作系統協調的多語言文件處理

必須在單次通過中識別英語、法語和德語文字的多語言發票管道在 Windows.Media.Ocr 中面臨架構死衚衕。 API 允許每個引擎實例僅使用一種語言。 處理混合語言文件要麼需要一個最擬合的單語言引擎,要麼進行三次識別並合併結果——這兩者都不會產生可靠的輸出。

Windows.Media.Ocr 方法:

// Windows.Media.Ocr: one language per engine, no simultaneous multi-language support
// Each language requires a separate language pack installed on the machine
public async Task<string> RecognizeMultiLanguageAsync(SoftwareBitmap bitmap)
{
    // Must pick ONE language — no simultaneous recognition
    var engine = OcrEngine.TryCreateFromLanguage(
        new Windows.Globalization.Language("en-US"));
    if (engine == null)
        throw new InvalidOperationException("English language pack not installed.");

    // French and German text on the same document will be misrecognized
    var result = await engine.RecognizeAsync(bitmap);
    return result.Text;
}
C#

IronOCR方法:

// IronOCR: simultaneous multi-language recognition in a single pass
// Language packs are NuGet packages — no OS coordination required
// dotnet add package IronOcr.Languages.French
// dotnet add package IronOcr.Languages.German
public string RecognizeMultiLanguage(string documentPath)
{
    var ocr = new IronTesseract();
    ocr.Language = OcrLanguage.English + OcrLanguage.French + OcrLanguage.German;

    var result = ocr.Read(documentPath);

    // Structured output: walk paragraphs with location data
    foreach (var page in result.Pages)
    {
        foreach (var paragraph in page.Paragraphs)
        {
            Console.WriteLine($"[{paragraph.X},{paragraph.Y}] {paragraph.Text}");
        }
    }

    return result.Text;
}
C#

IronOCR 將語言模型結合在單次識別中,消除了猜測給定區域使用哪種語言的需求。 多語言 OCR 指南涵蓋語言包安裝和所有 125+ 支援語言的 OcrLanguage 枚舉值。 語言索引列表包括 CJK 脚本、阿拉伯語、希伯來語、天城文和西里爾文。

透過平行處理啟用伺服器端 OCR

Windows.Media.Ocr 無法在 Linux 伺服器上下文中運行,無法從跨平台主機上的標準 ASP.NET Core 控制器調用,並且在伺服器場景中從非 UI 執行緒調用時行為不確定。 將 OCR 端點從僅限 Windows 的桌面應用程式移動到可擴展的 Web API 團隊同時面臨所有三個約束。

Windows.Media.Ocr 方法:

// Windows.Media.Ocr: cannot run on Linux, Docker, or Azure Functions on Linux
// UWP/WinRT assumptions about thread context cause failures in ASP.NET pipelines
// The entire approach below is non-deployable outside Windows with Desktop Experience

[HttpPost("ocr")]
public async Task<IActionResult> RecognizeDocument(IFormFile file)
{
    // WinRT requires STA thread context in some scenarios — not guaranteed in ASP.NET
    // Cannot deploy this controller to a Linux App Service plan
    using var stream = file.OpenReadStream();
    // InMemoryRandomAccessStream is a WinRT type — does not exist on Linux
    // var ras = new InMemoryRandomAccessStream(); // compile error on net8.0 TFM
    return StatusCode(503, "Windows-only — cannot deploy cross-platform.");
}
C#

IronOCR方法:

// IronOCR: ASP.NET Core controller running on Linux, Docker, or Windows — same code
[HttpPost("ocr")]
public async Task<IActionResult> RecognizeDocument(IFormFile file)
{
    if (file == null || file.Length == 0)
        return BadRequest("No file provided.");

    using var memoryStream = new MemoryStream();
    await file.CopyToAsync(memoryStream);
    var imageBytes = memoryStream.ToArray();

    using var input = new OcrInput();
    input.LoadImage(imageBytes);
    input.Deskew();   // straighten uploaded scans automatically
    input.DeNoise();  // remove mobile camera noise

    var result = new IronTesseract().Read(input);

    return Ok(new
    {
        Text = result.Text,
        Confidence = result.Confidence,
        Pages = result.Pages.Count
    });
}
C#

此控制器部署到 Linux 應用服務、Docker 和 AWS Lambda,無需更改任何東西。 Docker 部署指南涵蓋了在 Linux 基礎映像上所需的單一 apt-get 依賴性。 Azure 部署指南AWS 指南展示了特定於雲的配置。

從掃描的歸檔生成可搜尋的 PDF

Windows.Media.Ocr 生成純文字字串。 除了 OcrResult.TextOcrResult.Lines 中的行幾何之外,它沒有其他輸出格式。 將掃描的歸檔轉換為可搜尋的 PDF——這是文件管理系統和合規性工作流中的常見要求——需要第三方庫來構建 PDF 輸出層。IronOCR本身就能生成可搜尋的 PDF。

Windows.Media.Ocr 方法:

// Windows.Media.Ocr: plain text output only
// Searchable PDF requires external PDF library + manual text layer construction
public async Task<string> GetTextOnlyAsync(SoftwareBitmap bitmap)
{
    var engine = OcrEngine.TryCreateFromUserProfileLanguages();
    if (engine == null)
        throw new InvalidOperationException("No OCR language available.");

    var result = await engine.RecognizeAsync(bitmap);

    // result.Text is all you get
    // Producing a searchable PDF requires an entirely separate library
    return result.Text;
}
C#

IronOCR方法:

// IronOCR: searchable PDF output is one method call on OcrResult
public void ProcessScannedArchive(IEnumerable<string> pdfPaths, string outputDirectory)
{
    foreach (var sourcePdf in pdfPaths)
    {
        var ocr = new IronTesseract();

        using var input = new OcrInput();
        input.LoadPdf(sourcePdf);   // native PDF input — no external renderer
        input.Deskew();             // correct scan misalignment per page
        input.DeNoise();            // remove scanner speckle

        var result = ocr.Read(input);

        var outputFileName = Path.Combine(
            outputDirectory,
            Path.GetFileNameWithoutExtension(sourcePdf) + "-searchable.pdf");

        result.SaveAsSearchablePdf(outputFileName);

        Console.WriteLine($"Processed: {sourcePdf}{outputFileName} " +
                          $"({result.Pages.Count} pages, {result.Confidence:F1}% confidence)");
    }
}
C#

SaveAsSearchablePdf 呼叫在原始掃描影像上嵌入了一個文字層,保存了視覺保真度,同時使全文字搜尋和在任何 PDF 檢視器中的 Ctrl+F 成為可能。 可搜尋 PDF 如何實現指南涵蓋字體嵌入、文字層定位和多頁輸出選項。 PDF 輸入指南涵蓋密碼保護的 PDF 和大型歸檔的頁面範圍選擇。

使用字級座標提取結構化資料

Windows.Media.Ocr 曝露 OcrResult.Lines 與行級文字和邊界矩形。 字級幾何存在於具有 OcrLine.WordsOcrWord.BoundingRectPages 中,但沒有段落、信心分數,也沒有字元級資料。 對於表單字段提取或發票行項解析,行幾何是不足的——需要段落邊界和字信心分數來區分結構化字段與周圍的文字。

Windows.Media.Ocr 方法:

// Windows.Media.Ocr: line-level geometry, no paragraph grouping, no confidence scores
public async Task<List<string>> ExtractLineTextAsync(SoftwareBitmap bitmap)
{
    var engine = OcrEngine.TryCreateFromUserProfileLanguages();
    if (engine == null)
        throw new InvalidOperationException("No OCR language available.");

    var result = await engine.RecognizeAsync(bitmap);

    var lineTexts = new List<string>();
    foreach (var line in result.Lines)
    {
        // Line text + word bounding rects — no paragraph grouping, no confidence
        lineTexts.Add(line.Text);
    }
    return lineTexts;
}
C#

IronOCR方法:

// IronOCR: full hierarchy — pages, paragraphs, lines, words, characters
// Each element carries coordinates and confidence for downstream validation
public void ExtractStructuredData(string documentPath)
{
    var result = new IronTesseract().Read(documentPath);

    Console.WriteLine($"Overall confidence: {result.Confidence:F1}%");

    foreach (var page in result.Pages)
    {
        Console.WriteLine($"\n--- Page {page.PageNumber} ---");

        foreach (var paragraph in page.Paragraphs)
        {
            Console.WriteLine($"Paragraph at ({paragraph.X},{paragraph.Y}): {paragraph.Text}");

            // Filter words below confidence threshold for validation workflows
            var lowConfidence = paragraph.Words
                .Where(w => w.Confidence < 70)
                .ToList();

            if (lowConfidence.Any())
            {
                Console.WriteLine($"  Low-confidence words: " +
                    string.Join(", ", lowConfidence.Select(w => $"'{w.Text}' ({w.Confidence:F0}%)")));
            }
        }
    }
}
C#

結構化結果模型——Characters——提供了表單字段提取、發票解析和文件布局分析所需的座標和信心資料。 讀取結果指南記錄了完整的 OcrResult 物件圖。 信心分數指南解釋了如何使用每字的信心值標記不確定的提取,以供人工審核。

Windows.Media.Ocr API 到IronOCR映射參考

Windows.Media.OcrIronOCR
OcrEngine.TryCreateFromLanguage(lang)new IronTesseract() + ocr.Language = OcrLanguage.X
OcrEngine.TryCreateFromUserProfileLanguages()new IronTesseract() (預設為英語; 無空值返回)
engine.RecognizeAsync(softwareBitmap)ocr.Read("image.jpg")ocr.Read(ocrInput)
StorageFile.GetFileFromPathAsync(path)ocr.Read("path") 直接 (不需要文件句柄)
file.OpenAsync(FileAccessMode.Read)已消除——OcrInput 直接載入
BitmapDecoder.CreateAsync(stream)input.LoadImage(stream) 透過 OcrInput
decoder.GetSoftwareBitmapAsync()已消除——IronOCR 中沒有 SoftwareBitmap
SoftwareBitmap (WinRT 型別)已消除——OcrInput 接受字節、流、文件路徑
InMemoryRandomAccessStream (WinRT 型別)new MemoryStream() + input.LoadImage(stream)
OcrResult.TextOcrResult.Text
OcrResult.LinesOcrResult.Lines (也有 Pages, Paragraphs, Words, Characters)
OcrLine.TextOcrResult.Lines[i].Text
OcrLine.WordsOcrResult.Wordspage.Paragraphs[i].Words
OcrWord.BoundingRectword.X, word.Y, word.Width, word.Height
無相應物件result.Confidence (總體) / word.Confidence (每字)
無相應物件result.SaveAsSearchablePdf("output.pdf")
無相應物件input.LoadPdf("document.pdf")
無相應物件input.Deskew(), input.DeNoise(), input.Contrast()
無相應物件ocr.Language = OcrLanguage.A + OcrLanguage.B (同時)
無相應物件ocr.Configuration.ReadBarCodes = true
無相應物件input.LoadImage(byteArray)

常見的遷移問題与解決方案

問題 1:遷移後項目文件仍需 Windows TFM

Windows.Media.Ocr: 需要聲明 <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework> 優化解決 WinRT 型別。 不檢查同一項目中的其他 WinRT 相依性而移除 Windows.Media.Ocr 引用,可能會使 TFM 保持不變,從而阻止跨平台構建。

解決方案: 在移除 Windows OCR 名稱空間引用後,在更改 TFM 之前搜尋項目中是否存在其他 WinRT API使用:

# Find remaining WinRT API usage before removing the Windows TFM
grep -r "Windows\." --include="*.cs" .
grep -r "WinRT\|IAsyncOperation\|StorageFile\|SoftwareBitmap" --include="*.cs" .
SHELL

如果沒有剩餘的 WinRT 參考,請更新項目文件:

<!-- Before -->
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>

<!-- After -->
<TargetFramework>net8.0</TargetFramework>
XML

如果其他 WinRT 功能 (Windows 通知、Shell 整合、XAML) 仍在使用,請在介面後抽象 OCR 調用,並提供平台特定的實現,而不是刪除整個項目的 TFM。

問題 2:空引擎檢查沒有IronOCR等價物

Windows.Media.Ocr: 每次調用 TryCreateFromLanguageTryCreateFromUserProfileLanguages 都可能返回空。 所有現有程式碼都包含空值檢查保護語句,在引擎為空值時擲或分支。

**解決方案:**IronOCR在初始化失敗時拋出結構化異常,而不是返回空值。 刪除空值檢查保護語句。 如果您需要將初始化錯誤呈現給調用者,請包裹在標準的 try/catch 中:

// Before: null-check pattern
var engine = OcrEngine.TryCreateFromUserProfileLanguages();
if (engine == null)
    throw new InvalidOperationException("OCR unavailable.");

// After: no null — IronTesseract throws if misconfigured
try
{
    var result = new IronTesseract().Read("document.jpg");
}
catch (IronOcr.Exceptions.OcrException ex)
{
    // structured exception with diagnostic message
    logger.LogError("OCR failed: {Message}", ex.Message);
}
C#

問題 3:現有方法簽名中的 SoftwareBitmap 參數

Windows.Media.Ocr: 實用方法、服務和回購類可能接受 SoftwareBitmap 作為參數型別。 當移除 Windows TFM 時,這些方法簽名無法編譯。

解決方案:byte[]Stream 替換 SoftwareBitmap 參數。IronOCR的 OcrInput 直接接受兩者。 先前構建 SoftwareBitmap 的呼叫位置可以傳遞其底層資料:

// Before: SoftwareBitmap parameter — cannot compile cross-platform
public async Task<string> RecognizeAsync(SoftwareBitmap bitmap) { ... }

// After: byte array parameter — compiles on all platforms
public string Recognize(byte[] imageBytes)
{
    using var input = new OcrInput();
    input.LoadImage(imageBytes);
    return new IronTesseract().Read(input).Text;
}
C#

問題 4:非同步僅限定調用者無法直接使用同步 IronOCR

Windows.Media.Ocr: 每次識別呼叫都是 async。 由於調用者在整個程式碼庫中使用 await 並返回 Task<string>。 在 async 方法內部切換到IronOCR的同步 Read 方法有效,但可能會在 async 在架構下阻塞。

**解決方案:**IronOCR為需要的調用者提供非同步路徑。 在現有的非同步方法中使用 Task.Run 進行 CPU 負載包裝,或使用原生的非同步 API:

// Option A: wrap synchronous call in Task.Run for async callers
public async Task<string> RecognizeAsync(string imagePath)
{
    return await Task.Run(() => new IronTesseract().Read(imagePath).Text);
}

// Option B:IronOCRasync path
// See: https://ironsoftware.com/csharp/ocr/how-to/async/
C#

非同步 OCR 指南記錄了內建的非同步 API,適用於需要火即忘或進度報告模式的上下文。

問題 5:Windows 語言標籤格式無對應

Windows.Media.Ocr: 使用 BCP-47 字串標籤傳遞到 Windows.Globalization.Language("fr-FR") 來指定語言。 這些字串標籤在IronOCR中沒有直接對應。

解決方案: 將 BCP-47 語言標籤映射到 OcrLanguage 枚舉。 對於常見語言,映射是直接的:

// Before: BCP-47 string tags
var engine = OcrEngine.TryCreateFromLanguage(
    new Windows.Globalization.Language("fr-FR"));

// After: OcrLanguage enum
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.French;
// Also: OcrLanguage.German, OcrLanguage.Japanese, OcrLanguage.Arabic, etc.
C#

IronOCR 語言目錄中提供了完整的映射。 對於未包含在主枚舉中的語言,自定義語言包支持 涵蓋直接載入 .traineddata 文件。

問題 6:FileAccessMode.Read 無替代方案

Windows.Media.Ocr: file.OpenAsync(FileAccessMode.Read) 是 WinRT 特定的文件開啟模式。 FileAccessMode 枚舉在標準 .NET 中不存在。

解決方案: 替換為標準 System.IO.File.ReadAllBytesFileStreamOcrInput 接受兩者:

// Before: WinRT file access
using var stream = await file.OpenAsync(FileAccessMode.Read);

// After: standard .NET
var imageBytes = File.ReadAllBytes(imagePath);
using var input = new OcrInput();
input.LoadImage(imageBytes);
C#

Windows.Media.Ocr (UWP/WinRT OCR) 遷移檢查清單

遷移前

在更改之前稽核程式碼庫:

# Find all Windows OCR namespace usages
grep -rn "using Windows.Media.Ocr" --include="*.cs" .
grep -rn "using Windows.Graphics.Imaging" --include="*.cs" .
grep -rn "using Windows.Storage" --include="*.cs" .
grep -rn "using Windows.Globalization" --include="*.cs" .

# Find WinRT type usages
grep -rn "OcrEngine\|SoftwareBitmap\|BitmapDecoder\|StorageFile" --include="*.cs" .
grep -rn "TryCreateFromLanguage\|TryCreateFromUserProfileLanguages\|RecognizeAsync" --include="*.cs" .
grep -rn "InMemoryRandomAccessStream\|DataWriter\|FileAccessMode" --include="*.cs" .

# Find project files with Windows TFM
grep -rn "net.*-windows" --include="*.csproj" .

# Count files requiring changes
grep -rl "Windows.Media.Ocr\|Windows.Graphics.Imaging\|SoftwareBitmap" --include="*.cs" . | wc -l
SHELL

記錄受影響的文件數量、使用的語言標籤 ("en-US", "fr-FR",等等),以及公眾方法簽名中是否存在任何 WinRT 型別物件(這些需要 API 表面更改以及內部重寫)。

程式碼遷移

  1. 安裝 IronOcr NuGet 套件:dotnet add package IronOcr
  2. Program.csStartup.cs 中新增許可初始化呼叫:IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
  3. 從所有源文件中移除 using Windows.Media.Ocr;
  4. 從所有源文件中移除 using Windows.Graphics.Imaging;
  5. 從所有源文件中移除 using Windows.Storage;
  6. 從所有源文件中移除 using Windows.Globalization;
  7. 向所有執行 OCR 的文件中新增 using IronOcr;
  8. new IronTesseract() 替換每個 OcrEngine.TryCreateFromLanguage(new Language("xx-XX")) 呼叫並設置 ocr.Language = OcrLanguage.X
  9. new IronTesseract() 替換每個 OcrEngine.TryCreateFromUserProfileLanguages() 呼叫
  10. 刪除引擎建立結果上的所有空值檢查保護語句
  11. byte[]Stream 替換方法簽名中的 SoftwareBitmap 參數
  12. OcrInput.LoadImage(bytes)OcrInput.LoadImage(stream) 替換 BitmapDecoderSoftwareBitmap 構造鏈
  13. ocr.Read(path)ocr.Read(input) 替換 engine.RecognizeAsync(bitmap)
  14. MemoryStream 替換 InMemoryRandomAccessStreamDataWriter 使用
  15. OcrLanguage 規範值替換 Windows 的 BCP-47 語言標籤字串; 安裝所需的語言 NuGet 套件
  16. 更新 <TargetFramework>,從 .csproj 文件中移除 -windowsX.Y.Z 後綴,無其他 WinRT API 留存

遷移後

  • 確認項目在沒有 Windows TFM 後綴的情況下針對 net8.0 (或您目標版本) 編譯
  • 確認項目在 Linux 環境或 Docker 容器中使用 mcr.microsoft.com/dotnet/aspnet:8.0 編譯和運行
  • 驗證 OCR 輸出文字是否符合測試套件中每種文件型別的預期結果
  • 檢查所有先前支援的語言是否使用IronOCR語言 NuGet 套件產生正確的輸出
  • 驗證多語言檔案是否在單次識別中產生正確的結果
  • 確保在沒有安裝 Windows 語言包的機器上引擎初始化不會出現 NullReferenceExceptionInvalidOperationException
  • 驗證 result.Confidence 值是否在乾淨和低質量輸入文件的預期範圍內
  • 如果應用程式產生文件,驗證 SaveAsSearchablePdf 輸出在 PDF 檢視器中正確打開並支持文字搜尋
  • 運行任何現有的平行或多執行緒處理通道,並在負載下確認執行緒安全性
  • 部署到目標環境 (Docker, Azure 應用服務, AWS, Linux 伺服器) 並執行至少一次完整的端到端 OCR 操作

遷移至IronOCR的主要好處

跨平台部署成為配置決定,而不是程式碼重寫。 遷移之後,OCR 組件在 Windows、Linux、macOS、Docker 和每個主要雲供應商上運行相同。 將 OCR 工作量從 Windows VM 移動到 Linux 容器以降低託管成本是一個部署操作。 Linux 部署指南Docker 部署指南 涵蓋了在 Linux 基本映像上所需的一行依賴性新增。

語言支持隨著應用程式二進位文件移動。 語言包安裝為 NuGet 套件並與IronOCR包版本鎖定。 您應用程式可識別的語言集在項目文件中定義,並且在每台機器上都是相同的——開發者工作站、CI 運行器、預發伺服器和生產主機。 無需操作系統管理員協調,無需求例政策例外,無運行時空值檢查。

OCR 準確性在沒有外部工具的情況下得到提升。 在識別引擎看到影像之前,預處理流水線——Scale——在IronOCR內運行。 由於掃描不對齊或噪音而在 Windows.Media.Ocr 中產生劣質結果的文件,在不新增外部影像處理依賴項的情況下得到改進。 影像品質修正指南過濾嚮導 幫助識別每種文件型別的正確過濾器組合。

PDF 工作流整合到單一庫。 將 Windows.Media.Ocr 和 PDF 輸入連接所需的外部 PDF 渲染器已不再需要。 掃描 PDF 歸檔可以通過與影像相同的 IronTesseract.Read 呼叫進行處理。 可搜尋的 PDF 輸出是結果物件上的一種方法。 兩庫架構消失了,隨之而來的是其版本管理、許可開銷和部署面。

結構化輸出啟用文件智慧管道。 OcrResult 階層——Pages, Paragraphs, Lines, Words, Characters——具有每個元素的座標和信心分數,提供了進行發票字段提取、表單解析和文件分類所需的資料。 Windows.Media.Ocr 的行級輸出對於這些工作流程不夠充分。 使用 IronOCR,信心篩選的詞語提取、段落邊界檢測和基於座標的字段映射是第一級功能,不需要其他庫。

永久許可取代了無界基礎設施依賴。 保持 Windows 語言包在異構大型機上安裝的成本、Windows Server 桌面體驗許可,以及僅供 Windows 使用的 CI 基礎設施是實際的但分散的代價——它會出現在 IT 工單和基礎設施預算中,而不是 OCR 預算中的行項。 一個 $999IronOCRLite 許可消除了單一開發者項目的常見管理成本。 $1,499 的專業許可覆蓋了十個開發人員。 兩者都是一次性購買,包含一年更新。

請注意: Tesseract 和 Windows Media OCR 是其各自所有者的註冊商標。 此站點與Google或Microsoft無任何聯繫、認可或贊助。 所有產品名稱、標誌和品牌均為其各自所有者的財產。 比較僅供資訊用途,並反映撰寫時獲得的公開資訊。

相關文章

Key in blue circle

立即免費取得 30 天試用金鑰

Your trial license will be sent to your email address

無任何限制。100% 解鎖。無需信用卡。

bullet_checked無需信用卡或建立帳號無任何限制。100% 解鎖。無需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
獲取您的無義務諮詢
填寫以下表格或發送電子郵件至sales@ironsoftware.com
您的詳細資訊將始終保密。
被全球數百萬工程師信任
Iron Software的客戶標誌
立即獲取您的30天試用金鑰
無需信用卡或帳戶建立