C# | IronPDF'de Unicode ve Uluslararası Dil Barkodları Nasıl Yazılır?
ZXing.Net'ten IronBarcode'a Geçiş
Bu kılavuz, .NET barkod okuma ve üretme uygulamaları için ZXing.Net'den IronBarcode'ye tam geçişi kapsar. ZXing.Net'in çekirdek paketi ve bağlama paketlerinin kaldırılmasına, mevcut olan yerde PdfiumViewer geçici çözümlerinin ortadan kaldırılmasına ve her durumsal BarcodeReader örneklemesinin IronBarcode'ın statik API'si ile değiştirilmesine değinmektedir. Her bölüm, genellikle ZXing.Net entegrasyonlarında uygulanan desenlerden alınmış öncesi ve sonrası kod içerir.
Neden ZXing.Net'ten Geçiş Yapılmalı
ZXing.Net, on yılı aşkın bir süredir .NET topluluğuna ücretsiz, Apache 2.0 barkod kütüphanesi olarak iyi hizmet vermiştir. Ancak, birkaç mimari kısıtlama, uygulamalar ölçek veya karmaşıklık olarak büyüdükçe operasyonel maliyetler haline gelir.
Thread Safety Sahipliği: ZXing.Net'in BarcodeReader bir durumsal objedir. Kütüphanenin kendi belgeleri, örneklerin iş parçacıkları arasında paylaşılmaması gerektiğini belirtir. Pratikte bu, her bir eşzamanlı işleme yolunun — eşzamanlı istekleri yönetmekte olan her denetleyici eylemin, paralel bir grupta yer alan her görevin — kendi okuyucusunu ayırması, yapılandırması ve atması gerektiği anlamına gelir. İstek hacmi arttıkça, bu ayırma deseni ölçülebilir bellek baskısı oluşturur. ThreadLocal<BarcodeReader> alternatifi tahsis sıklığını azaltır ancak kendi bertaraf karmaşıklığını beraberinde getirir. Her iki durumda da, eşzamanlılık altında doğruluk, kitaplığın sunduğu bir garanti değil, arayanın problemidir.
Biçim Belirtimi Riski: ZXing.Net, her çözme işlemi öncesinde reader.Options.PossibleFormats doldurulmasını gerektirir. Bu listedeki bir formatta olmayan bir barkod null döndürür — hiçbir istisna, uyarı, barkodun var ama tanınmıyor olduğuna dair bir belirti yoktur. Dış ortaklardan belgeler alan uygulamalar için, bu sessiz kaçırma davranışı bir güvenilirlik riskidir: bir yanlış gönderilen sipariş, kaçırılan hasta kayıt giriş kaydı veya hiç yazılmayan bir denetim kaydı, daha önceki bir gereksinim için yapılandırılmış ve asla güncellenmemiş bir format listesinden kaynaklanabilir.
PDF İşleme Boşluğu: ZXing.Net sadece bit eşlemlerini okur. Kaynak belgeler PDF ise — faturalar, nakliye manifestoları, uygunluk sertifikaları — arayanlar, ayrı bir PDF işleme kütüphanesi entegre etmeli (PdfiumViewer en yaygın), bir sayfa numaralama döngüsünü yerine getirmeli, DPI yapılandırmalı, geçici dosyaları yönetmeli ve başarı ve başarısızlık yollarının her ikisinde de temizleme işlemleriyle uğraşmalıdır. Bu, ZXing.Net'in okuyamadığı (PDF'leri) dönüştürmeye yarayan, sadece 30 ila 50 satırlık altyapı kodudur. Bu altyapının kendi bağımlılıkları, kendi dağıtım gereksinimleri ve kendi hata modları vardır.
Platform Bağlama Parçalanması: ZXing.Net'in görüntü yükleme yeteneği, platforma özgü bağlama paketleri arasında bölünmüştür. Windows bağlaması System.Drawing.Bitmap kullanır; platformlar arası bağlama farklı bir genel tür parametresi ve farklı bir using yönergesi ile SixLabors.ImageSharp kullanır. Windows'ta başlayıp daha sonra Linux üzerinde konteynerleştiren bir proje, hem NuGet referanslarını hem de imaj yüklü kodunu değiştirmek zorunda kalmalıdır. Aynı işlem için iki kod yolu, hata alanını genişletir ve tarama katmanında gelecekteki değişikliklere sürtüşme ekler.
Temel Sorun
ZXing.Net mimarisinin en açık bir göstergesi, bir tek iş parçacıklı çağrı ile eşzamanlı bir çağrı arasındaki farktır. ZXing.Net'te, eşzamanlı işleme, paralel operasyon başına tam bir okuyucu nesnesi oluşturulmasını gerektirir:
// ZXing.Net: full reader instantiation and configuration on every parallel task
Parallel.ForEach(files, file =>
{
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
};
using var bitmap = new Bitmap(file);
var result = reader.Decode(bitmap);
if (result != null)
processed[file] = result.Text;
});
// ZXing.Net: full reader instantiation and configuration on every parallel task
Parallel.ForEach(files, file =>
{
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
};
using var bitmap = new Bitmap(file);
var result = reader.Decode(bitmap);
if (result != null)
processed[file] = result.Text;
});
Imports ZXing
Imports System.Drawing
Imports System.Threading.Tasks
Parallel.ForEach(files, Sub(file)
Dim reader As New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
}
Using bitmap As New Bitmap(file)
Dim result = reader.Decode(bitmap)
If result IsNot Nothing Then
processed(file) = result.Text
End If
End Using
End Sub)
IronBarcode bu nesneyi tamamen ortadan kaldırır. Statik çağrı, bir iş parçacığında veya yüz iş parçacığında çalıştırılsa da aynıdır:
// IronBarcode: static call, same code for single-threaded and concurrent use
Parallel.ForEach(files, file =>
{
var result = BarcodeReader.Read(file).FirstOrDefault();
if (result != null)
processed[file] = result.Value;
});
// IronBarcode: static call, same code for single-threaded and concurrent use
Parallel.ForEach(files, file =>
{
var result = BarcodeReader.Read(file).FirstOrDefault();
if (result != null)
processed[file] = result.Value;
});
Imports IronBarCode
Imports System.Threading.Tasks
Parallel.ForEach(files, Sub(file)
Dim result = BarcodeReader.Read(file).FirstOrDefault()
If result IsNot Nothing Then
processed(file) = result.Value
End If
End Sub)
IronBarcode vs ZXing.Net: Özellik Karşılaştırması
| Özellik | ZXing.Net | IronBarcode |
|---|---|---|
| Lisans | Apache 2.0 (ücretsiz) | Ticari |
| İş Parçacığı Güvenliği | İş parçacığı güvenli değil — her iş parçacığı için yeni örnek gerekiyor | İş parçacığı güvenli statik API |
| Format Algılama | Manuel — PossibleFormats listesi gereklidir |
Otomatik — 50+ format |
| PDF Okuma | Hayır — PdfiumViewer veya benzeri gerekiyor | Yerel — tek bir yöntem çağrısı |
| Platform Desteği | Her platform için ayrı bağlama paketleri | Tek paket, tüm platformlar |
| Görsel Başına Birden Fazla Barkod | Evet — DecodeMultiple |
Evet — varsayılan davranış |
| Barkod Üretimi | Bitmap döner, manuel kaydetme gerektirir |
Yerleşik çıkışa sahip akıcı API |
| QR Kod Logo Desteği | Hayır | Evet |
| QR Kod Renk Kontrolü | Hayır | Evet |
| Hasarlı Barkod Kurtarma | TryHarder bayrağı |
ML destekli görüntü düzeltme |
| Docker Ekstra Bağımlılıklar | libgdiplus gerektirebilir |
None |
| Ticari SLA Desteği | Hayır | Evet |
| Gerekli NuGet Paketleri | 2–3 (çekirdek + bağlama + isteğe bağlı ImageSharp) | 1 |
Hızlı Başlangıç
Adım 1: ZXing.Net Paketlerini Kaldırın
Projeden tüm ZXing.Net ve ilgili paketlerini kaldırın:
dotnet remove package ZXing.Net
dotnet remove package ZXing.Net.Bindings.Windows.Compatibility
dotnet remove package ZXing.Net.Bindings.ImageSharp
dotnet remove package PdfiumViewer
dotnet remove package ZXing.Net
dotnet remove package ZXing.Net.Bindings.Windows.Compatibility
dotnet remove package ZXing.Net.Bindings.ImageSharp
dotnet remove package PdfiumViewer
Yerel PdfiumViewer ikili dosyaları ayrı bir paket olarak yüklendiyse:
dotnet remove package PdfiumViewer.Native.x64.v8-xfa
dotnet remove package PdfiumViewer.Native.x64.v8-xfa
Dockerfile apt-get install -y libgdiplus içeriyorsa — Linux üzerinde Windows bağlaması üzerinden System.Drawing desteklemesi için eklenmişse — bu satır göç sonrası kaldırılabilir.
2. Adım: IronBarcode'u Kurun
dotnet add package IronBarcode
dotnet add package IronBarcode
Ek bağlama paketleri veya platforma özgü bağımlılıklar gerekmemektedir. Aynı NuGet paketi, Windows, Linux, macOS ve Docker kapsayıcılarında çalışmaktadır. Dağıtım detayları için, IronBarcode Docker ve Linux kurulum kılavuzu, tam Dockerfile desenini kapsar.
Adım 3: Ad Alanlarını Güncelleyin ve Lisansı Başlatın
Barkod işlemleri kullanan her dosyadan tüm ZXing ilgili ad alanlarını çıkarın:
// Remove all of these:
using ZXing;
using ZXing.Common;
using ZXing.Windows.Compatibility;
using ZXing.ImageSharp;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using PdfiumViewer;
// Add this single import:
using IronBarCode;
// Remove all of these:
using ZXing;
using ZXing.Common;
using ZXing.Windows.Compatibility;
using ZXing.ImageSharp;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using PdfiumViewer;
// Add this single import:
using IronBarCode;
Imports IronBarCode
Herhangi bir barkod işlemi öncesinde, uygulama başlangıcında lisans başlatma ekleyin:
// Program.cs or Startup.cs — initialise once at startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
// Program.cs or Startup.cs — initialise once at startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
' Program.vb or Startup.vb — initialise once at startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Lisans anahtarı, bir ortam değişkeninden, appsettings.json üzerinden veya bir gizli yönetici aracılığıyla yüklenebilecek düz bir dizedir. Yerleştirilecek bir dosya yoktur ve yapılandırılacak bir yol yoktur.
Kod Göç Örnekleri
Görselden Tek Bir Barkod Okuma
Bu örnek, en yaygın ZXing.Net kullanım desenini değiştirir: bir okuyucuya başlamak, format listesini yapılandırmak, bir bit eşlemi yüklemek ve çözmek.
ZXing.Net Yaklaşımı:
using ZXing;
using ZXing.Windows.Compatibility;
using System.Drawing;
public string ReadSingleBarcode(string imagePath)
{
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
};
using var bitmap = new Bitmap(imagePath);
var result = reader.Decode(bitmap);
return result?.Text ?? string.Empty;
}
using ZXing;
using ZXing.Windows.Compatibility;
using System.Drawing;
public string ReadSingleBarcode(string imagePath)
{
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
};
using var bitmap = new Bitmap(imagePath);
var result = reader.Decode(bitmap);
return result?.Text ?? string.Empty;
}
Imports ZXing
Imports ZXing.Windows.Compatibility
Imports System.Drawing
Public Function ReadSingleBarcode(imagePath As String) As String
Dim reader = New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
}
Using bitmap As New Bitmap(imagePath)
Dim result = reader.Decode(bitmap)
Return If(result?.Text, String.Empty)
End Using
End Function
IronBarcode Yaklaşımı:
using IronBarCode;
public string ReadSingleBarcode(string imagePath)
{
var result = BarcodeReader.Read(imagePath).FirstOrDefault();
return result?.Value ?? string.Empty;
}
using IronBarCode;
public string ReadSingleBarcode(string imagePath)
{
var result = BarcodeReader.Read(imagePath).FirstOrDefault();
return result?.Value ?? string.Empty;
}
Imports IronBarCode
Public Function ReadSingleBarcode(imagePath As String) As String
Dim result = BarcodeReader.Read(imagePath).FirstOrDefault()
Return If(result?.Value, String.Empty)
End Function
Biçim listesi, Bitmap tahsisi ve using bloğu tamamen kaldırılmıştır. IronBarcode, bir dosya yolunu doğrudan kabul eder ve tüm desteklenen formatları otomatik olarak tespit eder. Önceden çözülen dizeyi döndüren özellik ZXing.Net'te result.Text idi; IronBarcode'da result.Value.
Görselden Tüm Barkodları Okuma
Bu örnek, ZXing.Net'te sessiz kaçırmaları önlemek için kapsamlı bir format listesi gerektiren DecodeMultiple yerine geçmektedir.
ZXing.Net Yaklaşımı:
using ZXing;
using ZXing.Windows.Compatibility;
using System.Drawing;
public List<string> ReadAllBarcodes(string imagePath)
{
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.CODE_39,
BarcodeFormat.EAN_13,
BarcodeFormat.EAN_8,
BarcodeFormat.UPC_A,
BarcodeFormat.DATA_MATRIX,
BarcodeFormat.PDF_417
};
reader.Options.TryHarder = true;
using var bitmap = new Bitmap(imagePath);
var results = reader.DecodeMultiple(bitmap);
return results?.Select(r => r.Text).ToList() ?? new List<string>();
}
using ZXing;
using ZXing.Windows.Compatibility;
using System.Drawing;
public List<string> ReadAllBarcodes(string imagePath)
{
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.CODE_39,
BarcodeFormat.EAN_13,
BarcodeFormat.EAN_8,
BarcodeFormat.UPC_A,
BarcodeFormat.DATA_MATRIX,
BarcodeFormat.PDF_417
};
reader.Options.TryHarder = true;
using var bitmap = new Bitmap(imagePath);
var results = reader.DecodeMultiple(bitmap);
return results?.Select(r => r.Text).ToList() ?? new List<string>();
}
Imports ZXing
Imports ZXing.Windows.Compatibility
Imports System.Drawing
Public Function ReadAllBarcodes(imagePath As String) As List(Of String)
Dim reader = New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.CODE_39,
BarcodeFormat.EAN_13,
BarcodeFormat.EAN_8,
BarcodeFormat.UPC_A,
BarcodeFormat.DATA_MATRIX,
BarcodeFormat.PDF_417
}
reader.Options.TryHarder = True
Using bitmap As New Bitmap(imagePath)
Dim results = reader.DecodeMultiple(bitmap)
Return If(results?.Select(Function(r) r.Text).ToList(), New List(Of String)())
End Using
End Function
IronBarcode Yaklaşımı:
using IronBarCode;
public List<string> ReadAllBarcodes(string imagePath)
{
return BarcodeReader.Read(imagePath)
.Select(r => r.Value)
.ToList();
}
using IronBarCode;
public List<string> ReadAllBarcodes(string imagePath)
{
return BarcodeReader.Read(imagePath)
.Select(r => r.Value)
.ToList();
}
Imports IronBarCode
Public Function ReadAllBarcodes(imagePath As String) As List(Of String)
Return BarcodeReader.Read(imagePath) _
.Select(Function(r) r.Value) _
.ToList()
End Function
BarcodeReader.Read her zaman bir koleksiyon döner ve asla null döndürmez, sonuç üzerinde null guard'u ortadan kaldırır. Hız ile doğruluk dengesini ayarlamak için, biçim kapsamını daraltmadan ReadingSpeed enumsını kapsayan okuma hız seçenekleri kılavuzuna bakınız.
Eşzamanlı Toplu İşleme
Bu örnek iş parçacığı güvenliği farkını en doğrudan şekilde gösterir. ZXing.Net, her paralel operasyon için yeni bir okuyucu gerektirir;IronBarcode eşzamanlılık seviyesi ne olursa olsun aynı statik çağrıyı kullanır.
ZXing.Net Yaklaşımı:
using ZXing;
using ZXing.Windows.Compatibility;
using System.Collections.Concurrent;
using System.Drawing;
public Dictionary<string, string> ProcessBatch(IEnumerable<string> filePaths)
{
var output = new ConcurrentDictionary<string, string>();
Parallel.ForEach(filePaths, new ParallelOptions { MaxDegreeOfParallelism = 4 }, file =>
{
// ZXing.Net is not thread-safe — a new reader is required per parallel operation
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128
};
using var bitmap = new Bitmap(file);
var result = reader.Decode(bitmap);
if (result != null)
output[file] = result.Text;
});
return output.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
using ZXing;
using ZXing.Windows.Compatibility;
using System.Collections.Concurrent;
using System.Drawing;
public Dictionary<string, string> ProcessBatch(IEnumerable<string> filePaths)
{
var output = new ConcurrentDictionary<string, string>();
Parallel.ForEach(filePaths, new ParallelOptions { MaxDegreeOfParallelism = 4 }, file =>
{
// ZXing.Net is not thread-safe — a new reader is required per parallel operation
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128
};
using var bitmap = new Bitmap(file);
var result = reader.Decode(bitmap);
if (result != null)
output[file] = result.Text;
});
return output.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
Imports ZXing
Imports ZXing.Windows.Compatibility
Imports System.Collections.Concurrent
Imports System.Drawing
Public Function ProcessBatch(filePaths As IEnumerable(Of String)) As Dictionary(Of String, String)
Dim output = New ConcurrentDictionary(Of String, String)()
Parallel.ForEach(filePaths, New ParallelOptions With {.MaxDegreeOfParallelism = 4}, Sub(file)
' ZXing.Net is not thread-safe — a new reader is required per parallel operation
Dim reader = New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128
}
Using bitmap As New Bitmap(file)
Dim result = reader.Decode(bitmap)
If result IsNot Nothing Then
output(file) = result.Text
End If
End Using
End Sub)
Return output.ToDictionary(Function(kvp) kvp.Key, Function(kvp) kvp.Value)
End Function
IronBarcode Yaklaşımı:
using IronBarCode;
using System.Collections.Concurrent;
public Dictionary<string, string> ProcessBatch(IEnumerable<string> filePaths)
{
var output = new ConcurrentDictionary<string, string>();
var options = new BarcodeReaderOptions { MaxParallelThreads = 4 };
Parallel.ForEach(filePaths, file =>
{
var result = BarcodeReader.Read(file, options).FirstOrDefault();
if (result != null)
output[file] = result.Value;
});
return output.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
using IronBarCode;
using System.Collections.Concurrent;
public Dictionary<string, string> ProcessBatch(IEnumerable<string> filePaths)
{
var output = new ConcurrentDictionary<string, string>();
var options = new BarcodeReaderOptions { MaxParallelThreads = 4 };
Parallel.ForEach(filePaths, file =>
{
var result = BarcodeReader.Read(file, options).FirstOrDefault();
if (result != null)
output[file] = result.Value;
});
return output.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
Imports IronBarCode
Imports System.Collections.Concurrent
Public Function ProcessBatch(filePaths As IEnumerable(Of String)) As Dictionary(Of String, String)
Dim output = New ConcurrentDictionary(Of String, String)()
Dim options = New BarcodeReaderOptions With {.MaxParallelThreads = 4}
Parallel.ForEach(filePaths, Sub(file)
Dim result = BarcodeReader.Read(file, options).FirstOrDefault()
If result IsNot Nothing Then
output(file) = result.Value
End If
End Sub)
Return output.ToDictionary(Function(kvp) kvp.Key, Function(kvp) kvp.Value)
End Function
Korunacak veya izole edilecek bir okuyucu örneği yoktur. Asenkron boru hattı desenleri ve iş parçacığı sayısı yapılandırması için asenkron ve çok iş parçacıklı barkod okuma kılavuzunu inceleyin.
Bir PDF'den Barkod Çıkarma
Bu örnek PdfiumViewer render döngüsünü değiştirir. Var olan entegrasyon, PdfiumViewer yerine Ghostscript veya iText kullanıyorsa, önceki blok ayrıntılarda farklı görünecektir ama yapı olarak aynı olacaktır: ZXing.Net'e bit haritaları besleyen bir sayfa enum döngüsü.
ZXing.Net Yaklaşımı:
using ZXing;
using ZXing.Windows.Compatibility;
using PdfiumViewer;
using System.Drawing;
using System.Drawing.Imaging;
public List<string> ExtractBarcodesFromPdf(string pdfPath)
{
var collected = new List<string>();
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.PDF_417
};
using var document = PdfDocument.Load(pdfPath);
for (int page = 0; page < document.PageCount; page++)
{
string temp = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.png");
try
{
using var rendered = document.Render(page, 200, 200, PdfRenderFlags.CorrectFromDpi);
rendered.Save(temp, ImageFormat.Png);
using var bmp = new Bitmap(temp);
var decoded = reader.DecodeMultiple(bmp);
if (decoded != null)
collected.AddRange(decoded.Select(d => d.Text));
}
finally
{
if (File.Exists(temp))
File.Delete(temp);
}
}
return collected;
}
using ZXing;
using ZXing.Windows.Compatibility;
using PdfiumViewer;
using System.Drawing;
using System.Drawing.Imaging;
public List<string> ExtractBarcodesFromPdf(string pdfPath)
{
var collected = new List<string>();
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.PDF_417
};
using var document = PdfDocument.Load(pdfPath);
for (int page = 0; page < document.PageCount; page++)
{
string temp = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.png");
try
{
using var rendered = document.Render(page, 200, 200, PdfRenderFlags.CorrectFromDpi);
rendered.Save(temp, ImageFormat.Png);
using var bmp = new Bitmap(temp);
var decoded = reader.DecodeMultiple(bmp);
if (decoded != null)
collected.AddRange(decoded.Select(d => d.Text));
}
finally
{
if (File.Exists(temp))
File.Delete(temp);
}
}
return collected;
}
Imports ZXing
Imports ZXing.Windows.Compatibility
Imports PdfiumViewer
Imports System.Drawing
Imports System.Drawing.Imaging
Public Function ExtractBarcodesFromPdf(pdfPath As String) As List(Of String)
Dim collected As New List(Of String)()
Dim reader As New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.PDF_417
}
Using document = PdfDocument.Load(pdfPath)
For page As Integer = 0 To document.PageCount - 1
Dim temp As String = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.png")
Try
Using rendered = document.Render(page, 200, 200, PdfRenderFlags.CorrectFromDpi)
rendered.Save(temp, ImageFormat.Png)
Using bmp As New Bitmap(temp)
Dim decoded = reader.DecodeMultiple(bmp)
If decoded IsNot Nothing Then
collected.AddRange(decoded.Select(Function(d) d.Text))
End If
End Using
End Using
Finally
If File.Exists(temp) Then
File.Delete(temp)
End If
End Try
Next
End Using
Return collected
End Function
IronBarcode Yaklaşımı:
using IronBarCode;
public List<string> ExtractBarcodesFromPdf(string pdfPath)
{
return BarcodeReader.Read(pdfPath)
.Select(r => r.Value)
.ToList();
}
using IronBarCode;
public List<string> ExtractBarcodesFromPdf(string pdfPath)
{
return BarcodeReader.Read(pdfPath)
.Select(r => r.Value)
.ToList();
}
Imports IronBarCode
Public Function ExtractBarcodesFromPdf(pdfPath As String) As List(Of String)
Return BarcodeReader.Read(pdfPath) _
.Select(Function(r) r.Value) _
.ToList()
End Function
PdfiumViewer bağımlılığı, sayfa render döngüsü, DPI yapılandırması, geçici dosya oluşturma ve temizleme bloğu tamamen çıkarılır.IronBarcodePDF'lerden barkodları kendi başına okur, tüm sayfaları otomatik olarak işler.
Barkod Oluşturma
ZXing.Net yazarı, arayanların System.Drawing.Imaging kullanarak kaydetmesi gereken bir Bitmap döner. IronBarcode, yerleşik çıktı yöntemlerine sahip bir GeneratedBarcode döner.
ZXing.Net Yaklaşımı:
using ZXing;
using ZXing.Common;
using ZXing.Windows.Compatibility;
using System.Drawing;
using System.Drawing.Imaging;
public void WriteCode128(string content, string outputPath)
{
var writer = new BarcodeWriter
{
Format = BarcodeFormat.CODE_128,
Options = new EncodingOptions
{
Width = 400,
Height = 120,
Margin = 10
}
};
using var bitmap = writer.Write(content);
bitmap.Save(outputPath, ImageFormat.Png);
}
using ZXing;
using ZXing.Common;
using ZXing.Windows.Compatibility;
using System.Drawing;
using System.Drawing.Imaging;
public void WriteCode128(string content, string outputPath)
{
var writer = new BarcodeWriter
{
Format = BarcodeFormat.CODE_128,
Options = new EncodingOptions
{
Width = 400,
Height = 120,
Margin = 10
}
};
using var bitmap = writer.Write(content);
bitmap.Save(outputPath, ImageFormat.Png);
}
Imports ZXing
Imports ZXing.Common
Imports ZXing.Windows.Compatibility
Imports System.Drawing
Imports System.Drawing.Imaging
Public Sub WriteCode128(content As String, outputPath As String)
Dim writer = New BarcodeWriter With {
.Format = BarcodeFormat.CODE_128,
.Options = New EncodingOptions With {
.Width = 400,
.Height = 120,
.Margin = 10
}
}
Using bitmap = writer.Write(content)
bitmap.Save(outputPath, ImageFormat.Png)
End Using
End Sub
IronBarcode Yaklaşımı:
using IronBarCode;
public void WriteCode128(string content, string outputPath)
{
BarcodeWriter.CreateBarcode(content, BarcodeEncoding.Code128)
.ResizeTo(400, 120)
.SaveAsPng(outputPath);
}
using IronBarCode;
public void WriteCode128(string content, string outputPath)
{
BarcodeWriter.CreateBarcode(content, BarcodeEncoding.Code128)
.ResizeTo(400, 120)
.SaveAsPng(outputPath);
}
Imports IronBarCode
Public Sub WriteCode128(content As String, outputPath As String)
BarcodeWriter.CreateBarcode(content, BarcodeEncoding.Code128) _
.ResizeTo(400, 120) _
.SaveAsPng(outputPath)
End Sub
Dosyaya kaydetme yerine ikili çıktı gerekiyorsa, döndürülen GeneratedBarcode nesnesi üzerinde herhangi bir MemoryStream tesisat olmaksızın ToPngBinaryData() ve ToJpegBinaryData() mevcuttur.
ZXing.Net API'sinden IronBarcode'ye Harita Referansı
| ZXing.Net | IronBarcode | Notlar |
|---|---|---|
new BarcodeReader() |
Statik — örnek yok | BarcodeReader.Read(...) statik bir çağrıdır |
reader.Options.PossibleFormats = new List<BarcodeFormat> { ... } |
Gerekli değil | Otomatik tespit, tüm 50+ formatı kapsar |
reader.Options.TryHarder = true |
Speed = ReadingSpeed.Balanced |
BarcodeReaderOptions ile doğruluk ayarlama |
reader.Decode(bitmap) |
BarcodeReader.Read(imagePath).FirstOrDefault() |
Dosya yolu geç — Bitmap inşasına gerek yok |
reader.DecodeMultiple(bitmap) |
BarcodeReader.Read(imagePath) |
Her zaman bir koleksiyon döner; never null |
result.Text |
result.Value |
Özellik yeniden adlandırıldı |
result.BarcodeFormat |
result.Format |
Özellik yeniden adlandırıldı |
BarcodeFormat.QR_CODE |
BarcodeEncoding.QRCode |
Enum adlandırma kuralı değişikliği |
BarcodeFormat.CODE_128 |
BarcodeEncoding.Code128 |
Enum adlandırma kuralı değişikliği |
BarcodeFormat.EAN_13 |
BarcodeEncoding.EAN13 |
Enum adlandırma kuralı değişikliği |
BarcodeFormat.DATA_MATRIX |
BarcodeEncoding.DataMatrix |
Enum adlandırma kuralı değişikliği |
BarcodeFormat.PDF_417 |
BarcodeEncoding.PDF417 |
Enum adlandırma kuralı değişikliği |
new BarcodeWriter { Format = ..., Options = new EncodingOptions { ... } } |
BarcodeWriter.CreateBarcode(data, encoding) |
Statik fabrika, seçenekler nesnesi yok |
writer.Write(data) Bitmap döner |
.SaveAsPng(path) / .ToPngBinaryData() |
GeneratedBarcode üzerinde yerleşik çıktı |
EncodingOptions { Width, Height } |
.ResizeTo(width, height) |
Akıcı boyutlandırma yöntemi |
| PDF desteği yok | BarcodeReader.Read("file.pdf") |
Yerel PDF desteği, tüm sayfalar |
Yaygın Göç Sorunları ve Çözümleri
Sorun 1: BarcodeReader Başlatma Desenleri
ZXing.Net: Aramalar bir new BarcodeReader() oluşturur, reader.Options.PossibleFormats ayarlar, bir Bitmap yükler, reader.Decode(bitmap) veya reader.DecodeMultiple(bitmap) çağırır ve result.Text okur.
Çözüm: Başlatmayı tamamen kaldırın. Tam deseni bir statik çağrı ile değiştirin:
// Before: reader creation + format config + bitmap + decode + result.Text
// After:
var result = BarcodeReader.Read(imagePath).FirstOrDefault();
var value = result?.Value ?? string.Empty;
// Before: reader creation + format config + bitmap + decode + result.Text
// After:
var result = BarcodeReader.Read(imagePath).FirstOrDefault();
var value = result?.Value ?? string.Empty;
' Before: reader creation + format config + bitmap + decode + result.Text
' After:
Dim result = BarcodeReader.Read(imagePath).FirstOrDefault()
Dim value = If(result?.Value, String.Empty)
new BarcodeReader() kod tabanında arayın ve her bir örneği bulun. Her biri kaldırılır, yeniden düzenlenmez.
Sorun 2: PossibleFormats Bloğunun Kaldırılması
ZXing.Net: Her kod çözme çağrısı öncereader.Options.PossibleFormats = new List<BarcodeFormat> { ... }ataması. Bu listeler genellikle uzun ve projeye özeldir.
Çözüm: Her bir PossibleFormats atama bloğunu tamamen silin.IronBarcode otomatik format algılama yapar; hiçbir format listesi kabul edilmez veya gerekmez. TryHarder = true bayrağı, biçim listesiyle birlikte ayarlandıysa, doğruluk ayarlaması gerekiyorsa, onu BarcodeReaderOptions nesnesi üzerinde Speed = ReadingSpeed.Balanced ile değiştirin.
Sorun 3: Paket Temizliği Bağlama
ZXing.Net: ZXing.Net.Bindings.Windows.Compatibility kullanan projeler, giriş türü olarak System.Drawing.Bitmap referans alır. ZXing.Net.Bindings.ImageSharp kullanan projeler SixLabors.ImageSharp.Image<Rgba32> referans alır. Her iki desen de bağlama paketleri kaldırıldıktan sonra bozulur.
Çözüm: Her iki bağlama paketini de kaldırın ve tüm görüntü yükleme kodunu değiştirin. IronBarcode'ın BarcodeReader.Read bir dosya yolu dizesi, byte[], Stream veya Uri kabul eder — Bitmap veya Image<t> inşasına gerek yoktur. Sadece Bitmap yükleme için var olan kalan using System.Drawing; ithalatları da kaldırılabilir.
Sorun 4: result.Text to result.Value
ZXing.Net: Çözülen barkod değeri, result.Text aracılığıyla erişilir. Barkod formatına result.BarcodeFormat ile erişilir.
Çözüm: Kod tabanındaki result.Text yerine result.Value ve result.BarcodeFormat yerine result.Format kullanın. Her iki değişiklik de davranışsal bir fark olmaksızın basit birer özellik yeniden adlarıdır.
ZXing.Net Göç Kontrol Listesi
Geçiş Öncesi Görevler
ZXing.Net referanslarını aramaya başlamadan önce tüm kod tabanını inceleyin:
grep -r "using ZXing" --include="*.cs" .
grep -r "new BarcodeReader" --include="*.cs" .
grep -r "PossibleFormats" --include="*.cs" .
grep -r "BarcodeFormat\." --include="*.cs" .
grep -r "reader\.Decode\|reader\.DecodeMultiple" --include="*.cs" .
grep -r "result\.Text\|result\.BarcodeFormat" --include="*.cs" .
grep -r "new BarcodeWriter\|writer\.Write\|EncodingOptions" --include="*.cs" .
grep -r "PdfiumViewer\|PdfDocument\.Load" --include="*.cs" .
grep -r "using System\.Drawing" --include="*.cs" .
grep -r "using ZXing" --include="*.cs" .
grep -r "new BarcodeReader" --include="*.cs" .
grep -r "PossibleFormats" --include="*.cs" .
grep -r "BarcodeFormat\." --include="*.cs" .
grep -r "reader\.Decode\|reader\.DecodeMultiple" --include="*.cs" .
grep -r "result\.Text\|result\.BarcodeFormat" --include="*.cs" .
grep -r "new BarcodeWriter\|writer\.Write\|EncodingOptions" --include="*.cs" .
grep -r "PdfiumViewer\|PdfDocument\.Load" --include="*.cs" .
grep -r "using System\.Drawing" --include="*.cs" .
Hangi dosyaların ZXing bağlama paketlerini (Windows'a karşı ImageSharp'a karşı) referans aldığını ve burada sadece ZXing girişi için System.Drawing.Bitmap kullanıldığını belgeleyin. Dockerfile'ı (mevcutsa) libgdiplus kurulumu için inceleyin.
Kod Güncelleme Görevleri
ZXing.Net,ZXing.Net.Bindings.Windows.Compatibility,ZXing.Net.Bindings.ImageSharpvePdfiumViewerNuGet paketlerini kaldırınIronBarcodeNuGet paketini yükleyin- Başvuru başlatma kısmına
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";ekleyin - Tüm
using ZXing*veusing SixLabors.ImageSharp*ithalatlarınıusing IronBarCode;ile değiştirin - Her
new BarcodeReader()örneklemesini kaldırın - Her
reader.Options.PossibleFormats = ...bloğunu silin reader.Decode(bitmap)ileBarcodeReader.Read(imagePath).FirstOrDefault()değiştirinreader.DecodeMultiple(bitmap)ileBarcodeReader.Read(imagePath)değiştirinresult.Textileresult.Valuedeğiştirinresult.BarcodeFormatileresult.FormatdeğiştirinBarcodeFormat.Xenum referanslarını eşdeğerleri ile güncelleyin 12.new BarcodeWriter { Format = ..., Options = new EncodingOptions { ... } }withBarcodeWriter.CreateBarcode(data, encoding).ResizeTo(w, h)writer.Write(data)+bitmap.Save(...)ile.SaveAsPng(path)veya.ToPngBinaryData()değiştirin- Yalnızca ZXing.Net bitmap yüklemesi için var olan tüm
using System.Drawing;ithalatlarını kaldırın - PdfiumViewer sayfa oluşturma döngüsünü bir PDF çözümü olarak nerede uygulanmışsa kaldırın
- Dockerfile'dan
libgdiplus'i kaldırın eğer Linux'daSystem.Drawingdesteklemek için eklenmişse
Geçiş Sonrası Testler
- Uygulamanın daha önce algılamak üzere yapılandırıldığı tüm barkod formatlarının başarılı bir şekilde bulunduğunu doğrulayın
- Daha önce
PossibleFormatslistesinde hariç tutulan barkod formatlarını içeren görsellerle test edin, otomatik algılamanın onları aldığını doğrulamak için - Yük altında eşzamanlı işleme yollarını çalıştırın ve hiçbir yarış durumu veya null sonuç olmadığını doğrulayın
- Uygulama PdfiumViewer aracılığıyla PDF'leri işlerse, aynı PDF girişlerini sağlayın ve barkod değerlerinin eşleştiğini doğrulayın
- Üretilen barkodların (Kod 128, QR Kodu vb.) doğru çıkış formatı ve boyutlarını ürettiğini teyit edin
- Linux veya Docker dağıtımlarında, görsel okuma ve PDF okumanın
libgdiplusolmadan çalıştığını doğrulayın - Tam test paketi çalıştırın ve çıktıyı göç öncesi referansla karşılaştırın
IronBarcode'a Geçmenin Temel Faydaları
Ortam Güvenliği Yükü Kaldırıldı: IronBarcode'un statik API'si, her bir konu örneği modelini tamamen kaldırır. Hiçbir okuyucu örneklemeye gerek yoktur, thread başına yapılandırılacak bir format listesi yoktur ve yönetilecek bir ThreadLocal havuzu yoktur. Aynı çağrı, hem tek konu hem de yüksek dereceli eşzamanlı ortamlarda doğrudur ve eşzamanlılık doğruluğu, her bir arayıcıya devredilmek yerine kütüphaneye sağlanır.
Otomatik Format Algılama: PossibleFormats listesinin kaldırılması, geliştirme sırasında belgelerde öngörülemeyen barkod formatları içerdiğinde gerçekleşen sessiz kaçırma hatalarını ortadan kaldırır. Dış ortaklardan gelen belgeleri işleyen veya gelişen barkod standartları üzerinde çalışan uygulamaların artık güvenilir kalmak için format listesi bakımı gerektirmemesi gerekmiyor.
Yerel PDF İşleme: PdfiumViewer oluşturma döngüsü — sayfa numaralandırması, DPI yapılandırması, geçici dosya yaşam döngüsü ve temizleme kodu — tamamen kaldırılır. Daha önce bir PDF barkodunu işlemek için iki kütüphane (ZXing.Net ve bir PDF oluşturucu) gerektiren uygulamalar artık bir kullanıyor. Distribü edilen bağımlılıkların azaltılması, hem derleme hem de dağıtım yüzeylerini basitleştirir.
Tek Çapraz Platform Paketi: Windows ve Linux dağıtımları arasındaki bağlama paket farkı ortadan kaldırılır. Aynı BarcodeReader.Read(path) çağrısı tüm hedef platformlarda aynı şekilde derlenir ve davranır, görsel yükleme kodunda platform şartlarını ortadan kaldırır ve platformlar arası geliştirme ve konteynerleştirme iş akışlarını basitleştirir.
Ana Yapı Kodunun Azaltılması: Göçün en önemli sonucu, çevredeki altyapının kaldırılmasıdır — Bitmap yükleme blokları, format listeleri, PdfiumViewer oluşturma döngüleri, ThreadLocal havuzları — ZXing.Net entegrasyonlarındaki kütüphanenin mimari gereksinimlerini karşılamak için var olan. Göçten sonra kalan tek şey barkod mantığının kendisidir. Tespit oranları ve tarama senaryoları hakkında daha fazla bağlam için, ZXing.Net vs IronBarcode tarayıcı karşılaştırması daha geniş bir analiz sağlar.
Sıkça Sorulan Sorular
Neden ZXing.Net'den IronBarcode'a göç etmeliyim?
Yaygın nedenler arasında lisanslamanın basitleştirilmesi (SDK + runtime anahtar karmaşıklığının kaldırılması), veri geçiş limitlerinin ortadan kaldırılması, yerel PDF desteği kazanılması, Docker/CI/CD dağıtımının iyileştirilmesi ve üretim kodunda API tekrarlama azalması yer alır.
ZXing.Net API çağrılarını IronBarcode ile nasıl değiştirebilirim?
Örnek oluşturma ve lisanslama tekrarlamalarını IronBarCode.License.LicenseKey = "anahtar" ile değiştirin. Okuyucu çağrılarını BarcodeReader.Read(yol) ile ve yazıcı çağrılarını BarcodeWriter.CreateBarcode(veri, kodlama) ile değiştirin. Statik yöntemler örnek yönetimi gerektirmez.
ZXing.Net'den IronBarcode'a geçerken kodda ne kadar değişiklik oluyor?
Çoğu geçiş daha az kod satırıyla sonuçlanır. Lisanslama tekrarlamaları, örnek oluşturucular ve açık format yapılandırması kaldırılır. Temel okuma/yazma işlemleri, daha temiz sonuç nesneleriyle daha kısa IronBarcode eşdeğerlerine dönüştürülür.
Geçiş sırasında ZXing.Net ve IronBarcode'u bir arada tutmam gerekiyor mu?
Hayır. Çoğu geçiş doğrudan değişim yapılır, paralel bir işletim yerine geçer. Bir hizmet sınıfını bir seferde geçirin, NuGet referansını değiştirin ve sonraki sınıfa geçmeden önce başlatma ve API çağrı desenlerini güncelleyin.
IronBarcode için NuGet paketi adı nedir?
Paket 'IronBarCode' (büyük B ve C harfleriyle). 'Install-Package IronBarCode' veya 'dotnet add package IronBarCode' ile kurun. Kodda kullanılan yönerge 'using IronBarCode;' şeklindedir.
IronBarcode, Docker dağıtımını ZXing.Net'ye kıyasla nasıl kolaylaştırır?
IronBarcode, harici SDK dosyaları veya montajlı lisans yapılandırması olmayan bir NuGet paketidir. Docker'da, IRONBARCODE_LICENSE_KEY ortam değişkenini ayarlayın ve paket lisans doğrulamasını başlangıçta kendi kendine yapar.
ZXing.Net'den geçiş yaptıktan sonra IronBarcode tüm barkod formatlarını otomatik olarak algılar mı?
Evet. IronBarcode, desteklenen tüm formatlardaki sembolojiyi otomatik olarak algılar. Açık BarcodeTypes sayımı gerekli değildir. Format zaten biliniyorsa ve performans önemliyse, BarcodeReaderOptions arama alanını optimize etmek için sınırlamayı sağlar.
IronBarcode, ayrı bir kütüphane olmadan PDF'lerden barkod okuyabiliyor mu?
Evet. BarcodeReader.Read("document.pdf") PDF dosyalarını yerel olarak işlemler. Sonuçlar her barkod için SayfaNumarası, Format, Değer ve Güven içerir. Harici bir PDF render adımı gerekmez.
IronBarcode, paralel barkod işlemeyi nasıl yönetiyor?
IronBarcode'un statik yöntemleri durumsuz ve thread-safe'dir. Dağıtılmış dosya listeleri üzerinde per-thread örnek yönetimi olmadan doğrudan Parallel.ForEach kullanın. BarcodeReaderOptions.MaxParallelThreads, iç thread bütçesini kontrol eder.
ZXing.Net'den IronBarcode'a geçerken hangi sonuç özellikleri değişir?
Yaygın yeniden adlandırmalar: BarcodeValue, Value olur; BarcodeType, Format olur. IronBarcode sonuçları ayrıca Güven ve SayfaNumarası ekler. Çözüm çapında arama-değiştirme, mevcut sonuç işleme kodundaki yeniden adlandırmaları ele alır.
Bir CI/CD hattında IronBarcode lisanslamasını nasıl ayarlayabilirim?
IRONBARCODE_LICENSE_KEY'i bir boru hattı sırrı olarak saklayın ve uygulama başlangıç kodunda IronBarCode.License.LicenseKey olarak atayın. Bir sır, geliştirme, test, aşama ve üretim dahil olmak üzere tüm ortamları kapsar.
IronBarcode, özel biçimlendirmeye sahip QR kodu üretimini destekliyor mu?
Evet. QRCodeWriter.CreateQrCode() özelleştirilmiş renkler için ChangeBarCodeColor(), logo yerleştirme için AddBrandLogo(), yapılandırılabilir hata düzeltme seviyeleri ve PNG, JPG, PDF ve akış dahil birden çok çıktı formatını destekler.

