How To
Menggunakan .NET / C#
Penggunaan RustODotnet pada aplikasi C# dan .NET di Windows, Linux, dan macOS.
Paket NuGet RustODotnet menyediakan binding C# berkinerja tinggi dan menyertakan runtime native bawaan untuk Windows (x64, arm64), Linux (x64, arm64), dan macOS (x64, arm64).
Instalasi
Pasang paket inti dari NuGet:
dotnet add package RustODotnet
Opsional: pasang paket model resmi untuk menyertakan aset model secara otomatis tanpa konfigurasi manual:
dotnet add package RustODotnet.Models.PPOCRv6.Tiny
1. Siklus Hidup Mesin & Inisialisasi
RustO mengelola pointer memori native unmanaged melalui IDisposable. Selalu gunakan pernyataan using atau lakukan Dispose() saat instans tidak lagi digunakan:
using System;
using RustODotnet;
// 1. Inisialisasi menggunakan model bawaan default PP-OCRv6
using var ocr = RustO.Initialize();
// Atau tentukan path model kustom secara eksplisit:
var customConfig = new InitializeConfig
{
Template = "ppv6",
Detection = new DetectionConfig { ModelPath = "models/det.rten", LimitSideLen = 736 },
Recognition = new RecognitionConfig
{
ModelPath = "models/rec.rten",
DictPath = "models/dict.txt"
}
};
using var customOcr = RustO.Initialize(customConfig);
2. Opsi Permintaan Lokal (OcrRunOptions)
Konfigurasikan opsi per panggilan deteksi tanpa perlu mengalokasikan ulang sesi inferensi:
var options = new OcrRunOptions
{
Output = OutputGranularity.Lines, // Lines, Words, atau Spatial
LineYThreshold = 0.5f,
WordXThreshold = 0.4f,
TextScore = 0.55f,
MaxSideLen = 1600f,
Detection = new DetectionRunOptions
{
LimitSideLen = 960,
LimitType = "max"
},
Postprocess = new PostprocessRunOptions
{
UseDilation = true,
UnclipRatio = 2.0f
}
};
3. Sumber Gambar yang Didukung
ImageSource menerima path berkas/URI atau larik byte dalam memori RAM:
using System.IO;
// 1. Path filesystem atau file:// URI
var uriSource = new UriImageSource("invoices/sample.jpg");
// 2. Larik byte dalam memori (misal dari stream atau ASP.NET Core IFormFile)
byte[] imageBytes = await File.ReadAllBytesAsync("invoices/sample.jpg");
var bytesSource = new BytesImageSource(imageBytes);
4. Contoh Praktis & Penanganan Keluaran
Contoh A: Deteksi Baris Terstruktur dengan Koordinat Frame
using System;
using RustODotnet;
using var ocr = RustO.Initialize();
var result = ocr.DetectText(new UriImageSource("receipt.jpg"));
if (result is StructuredDetectTextResult structured)
{
Console.WriteLine($"Ditemukan {structured.Items.Count} baris teks:\n");
foreach (var item in structured.Items)
{
Console.WriteLine($"[{item.Frame.Left:F0}, {item.Frame.Top:F0}, {item.Frame.Width:F0}x{item.Frame.Height:F0}]");
Console.WriteLine($" Teks: {item.Text}");
Console.WriteLine($" Skor: {item.Score:P1}");
}
}
Contoh Keluaran:
Ditemukan 3 baris teks:
[40, 30, 200x24]
Teks: TOKO MAJU JAYA - PUSAT
Skor: 99.1%
[40, 75, 150x20]
Teks: Subtotal: Rp450.000
Skor: 98.4%
[40, 105, 150x20]
Teks: Total: Rp495.000
Skor: 99.5%
Contoh B: Mengekstrak Tabel Dokumen ke Tata Letak Spasial
using System;
using RustODotnet;
using var ocr = RustO.Initialize();
var spatialOptions = new OcrRunOptions
{
Output = OutputGranularity.Spatial,
LineYThreshold = 0.5f,
WordXThreshold = 0.4f
};
var spatialResult = ocr.DetectText(new UriImageSource("invoice_table.png"), spatialOptions);
if (spatialResult is SpatialDetectTextResult spatial)
{
Console.WriteLine("--- Teks Spasial Hasil Rekonstruksi ---");
Console.WriteLine(spatial.Text);
}
Contoh Keluaran:
--- Teks Spasial Hasil Rekonstruksi ---
Deskripsi Layanan Jumlah Tarif Subtotal
Jasa Konsultasi 8 Rp1.500.000 Rp12.000.000
Lisensi Perangkat Lunak 1 Rp4.990.000 Rp4.990.000
Hosting Cloud 1 Rp500.000 Rp500.000
───────────────────────────────────────────────────────────
Total Pembayaran: Rp17.490.000
Contoh C: Implementasi Controller ASP.NET Core Web API
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using RustODotnet;
using System.IO;
using System.Threading.Tasks;
[ApiController]
[Route("api/[controller]")]
public class OcrController : ControllerBase
{
private readonly RustO _ocr;
public OcrController()
{
// Pada aplikasi web, inisialisasi satu kali sebagai service singleton / scoped
_ocr = RustO.Initialize();
}
[HttpPost("scan")]
public async Task<IActionResult> ScanDocument(IFormFile file)
{
if (file == null || file.Length == 0)
return BadRequest("Tidak ada berkas gambar yang diunggah.");
using var memoryStream = new MemoryStream();
await file.CopyToAsync(memoryStream);
var result = _ocr.DetectText(
new BytesImageSource(memoryStream.ToArray()),
new OcrRunOptions { Output = OutputGranularity.Spatial }
);
if (result is SpatialDetectTextResult spatial)
{
return Ok(new { text = spatial.Text });
}
return StatusCode(500, "Pemrosesan OCR gagal.");
}
}