Jak używać Async i Multithread w kodach kreskowych używając C#
Migracja zQRCoderdo IronBarcode
Ten przewodnik jest przeznaczony dla zespołów programistów, których projekty rozpoczęły się odQRCoderi rozrosły się do tego stopnia, że wymagają funkcji wykraczających poza generowanie kodów QR.QRCoderto dobrze utrzymana biblioteka wysokiej jakości w swoim zakresie zastosowań, a migracja nie ma wpływu na jej jakość. Jest to odpowiedź na wymagania — rozszerzenie formatu, odczyt BARCODE, integracja z PDF — które wykraczają poza zakres funkcji, do których został zaprojektowany QRCoder. Niniejszy przewodnik obejmuje kompletną ścieżkę techniczną odQRCoderdo IronBarcode: wymianę pakietów, zmiany przestrzeni nazw, tłumaczenie kodu dla każdego popularnego wzorca, mapowanie odpowiedników API oraz rozwiązania problemów pojawiających się podczas przejścia.
Dlaczego warto przejść z QRCoder
Wymagania dotyczące formatu Beyond QR:QRCodergeneruje wyłącznie kody QR. Projekty, które rozwijają się do wymagań etykiet Code 128 dla logistyki, kodów EAN-13 do identyfikacji produktów w detalicznym handlu,DataMatrixdo serializacji farmaceutycznej lubPDF417do zgodności z dokumentami rządowymi, muszą wprowadzić oddzielną bibliotekę dla każdego dodatkowego formatu. Wraz ze wzrostem liczby wymaganych formatów rośnie również liczba niezależnych pakietów, interfejsów API i obowiązków związanych z utrzymaniem.
Wymagania dotyczące odczytu kodów kreskowych:QRCodernie posiada API do odczytu kodów kreskowych — z założenia jest to biblioteka służąca wyłącznie do generowania kodów. Każda aplikacja, która musi dekodować kody QR z przychodzących obrazów, weryfikować kody BarCode na zeskanowanych dokumentach lub przetwarzać etykiety wysyłkowe, musi opróczQRCoderdodać dedykowaną bibliotekę do odczytu. Ta druga biblioteka ma własny interfejs API, własny cykl aktualizacji i własne problemy z kompatybilnością przy każdej aktualizacji .NET.
Obsługa wielu bibliotek: Realistyczny schemat akumulacji dla projektu opartego na QRCoderze obejmujeQRCoderdo generowania kodów QR, bibliotekę BARCODE-ów 1D do etykiet wysyłkowych oraz bibliotekę odczytu do dekodowania. Zarządzanie trzema lub czterema niezależnymi pakietami oznacza śledzenie oddzielnych informacji o wydaniu, rozwiązywanie konfliktów wersji w przypadku aktualizacji któregokolwiek z nich oraz utrzymywanie znajomości wielu interfejsów API w całym zespole programistów. Obciążenie związane z utrzymaniem rośnie z czasem w sposób, który nie jest widoczny w początkowej wycenie integracji.
Obsługa plików PDF: Osadzanie barcode'ów w dokumentach PDF lub wyodrębnianie barcode'ów z przychodzących plików PDF wykracza poza zakres funkcji QRCoder. Procesy przetwarzania dokumentów — obsługa faktur, generowanie etykiet z szablonów PDF, raportowanie zgodności — napotykają tę barierę już na wczesnym etapie. Należy dodać dedykowaną bibliotekę PDF obokQRCoderlub architektura musi kierować generowanie BarCode'ów i generowanie plików PDF przez oddzielne podsystemy.
Podstawowy problem
QRCoder skutecznie rozwiązuje problem generowania kodów QR. W momencie, gdy jakiekolwiek wymaganie wykracza poza możliwości QR, kod źródłowy musi zacząć pobierać dodatkowe pakiety, aby wypełnić każdą lukę:
//QRCoderhandles QR generation well — but no further
using QRCoder;
using System.IO;
var generator = new QRCodeGenerator();
var qrCodeData = generator.CreateQrCode("SHIP-12345", QRCodeGenerator.ECCLevel.M);
var qrCode = new PngByteQRCode(qrCodeData);
File.WriteAllBytes("qr.png", qrCode.GetGraphic(10));
// Now the shipping team asks for Code 128 — add NetBarcode
// Now the warehouse needs to scan barcodes — add ZXing.Net
// Now a report needs a barcode in a PDF — add a PDF library
// Each addition: new namespace, new API, new maintenance cycle
//QRCoderhandles QR generation well — but no further
using QRCoder;
using System.IO;
var generator = new QRCodeGenerator();
var qrCodeData = generator.CreateQrCode("SHIP-12345", QRCodeGenerator.ECCLevel.M);
var qrCode = new PngByteQRCode(qrCodeData);
File.WriteAllBytes("qr.png", qrCode.GetGraphic(10));
// Now the shipping team asks for Code 128 — add NetBarcode
// Now the warehouse needs to scan barcodes — add ZXing.Net
// Now a report needs a barcode in a PDF — add a PDF library
// Each addition: new namespace, new API, new maintenance cycle
Imports QRCoder
Imports System.IO
Dim generator As New QRCodeGenerator()
Dim qrCodeData = generator.CreateQrCode("SHIP-12345", QRCodeGenerator.ECCLevel.M)
Dim qrCode As New PngByteQRCode(qrCodeData)
File.WriteAllBytes("qr.png", qrCode.GetGraphic(10))
' Now the shipping team asks for Code 128 — add NetBarcode
' Now the warehouse needs to scan barcodes — add ZXing.Net
' Now a report needs a barcode in a PDF — add a PDF library
' Each addition: new namespace, new API, new maintenance cycle
IronBarcode łączy generowanie, odczyt i integrację z PDF w ramach jednego API:
//IronBarcode— one library covers all of the above
using IronBarCode;
// Generate QR
BarcodeWriter.CreateBarcode("SHIP-12345", BarcodeEncoding.QRCode)
.SaveAsPng("qr.png");
// Generate Code 128 — same API
BarcodeWriter.CreateBarcode("SHIP-12345", BarcodeEncoding.Code128)
.SaveAsPng("label.png");
// Read a barcode from an image — built in
var results = BarcodeReader.Read("incoming.png");
//IronBarcode— one library covers all of the above
using IronBarCode;
// Generate QR
BarcodeWriter.CreateBarcode("SHIP-12345", BarcodeEncoding.QRCode)
.SaveAsPng("qr.png");
// Generate Code 128 — same API
BarcodeWriter.CreateBarcode("SHIP-12345", BarcodeEncoding.Code128)
.SaveAsPng("label.png");
// Read a barcode from an image — built in
var results = BarcodeReader.Read("incoming.png");
Imports IronBarCode
' Generate QR
BarcodeWriter.CreateBarcode("SHIP-12345", BarcodeEncoding.QRCode).SaveAsPng("qr.png")
' Generate Code 128 — same API
BarcodeWriter.CreateBarcode("SHIP-12345", BarcodeEncoding.Code128).SaveAsPng("label.png")
' Read a barcode from an image — built in
Dim results = BarcodeReader.Read("incoming.png")
IronBarcode a QRCoder: porównanie funkcji
| Funkcja | QRCoder | IronBarcode |
|---|---|---|
| Generowanie kodów QR | Tak — doskonałe | Tak |
| Micro QR | Tak | Nie |
| Kod 128 / Kod 39 | Nie | Tak |
| EAN-13 / UPC-A | Nie | Tak |
| DataMatrix | Nie | Tak |
| PDF417 | Nie | Tak |
| Aztec | Nie | Tak |
| Łączna liczba formatów | 1 | 50+ |
| Odczytywanie BarCode | Nie | Tak — automatyczne wykrywanie |
| Ekstrakcja BarCode z plików PDF | Nie | Tak |
| Wstawianie BarCode do plików PDF | Nie | Tak |
| Osadzanie logo | Tak | Tak |
| Dostosowanie kolorów | Tak | Tak |
| Wyjście SVG | Tak | Tak |
| Pomocniki PayloadGenerator | Tak | Nie — ręczne tworzenie ciągów znaków |
| Brak zależności zewnętrznych | Tak | Samodzielny |
| Licencja | MIT — bez ograniczeń | Komercyjny — poziom Lite obejmuje jednego programistę |
Szybki start: Migracja zQRCoderdo IronBarcode
Krok 1: Zastąp pakiet NuGet
UsuńQRCoderz projektu:
dotnet remove package QRCoder
dotnet remove package QRCoder
Zainstaluj IronBarcode:
dotnet add package IronBarcode
dotnet add package IronBarcode
Jeśli w projekcie używano ZXing.Net wraz zQRCoderdo odczytu BARCODE, ten pakiet również można usunąć na tym etapie:
dotnet remove package ZXing.Net
dotnet remove package ZXing.Net
Krok 2: Aktualizacja przestrzeni nazw
Zastąp import przestrzeni nazwQRCoderprzestrzenią nazw IronBarcode:
// Before (QRCoder)
using QRCoder;
// After (IronBarcode)
using IronBarCode;
// Before (QRCoder)
using QRCoder;
// After (IronBarcode)
using IronBarCode;
' Before (QRCoder)
Imports QRCoder
' After (IronBarcode)
Imports IronBarCode
Krok 3: Inicjalizacja licencji
Dodaj inicjalizację licencji przy starcie aplikacji — Program.cs, Startup.cs, lub konstruktora statycznego:
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Dostępny jest bezpłatny klucz próbny bez konieczności rejestracji. Wdrożenia produkcyjne wymagają zakupu licencji.
Przykłady migracji kodu
Podstawowe generowanie kodów QR
Najczęściej stosowany wzorzecQRCoderwymaga trzech obiektów: instancji QRCodeGenerator, obiektu pośredniego QRCodeData i klasy renderera, takiej jak PngByteQRCode. W IronBarcode ten łańcuch zastępuje pojedyncze wywołanie statyczne.
Podejście QRCoder:
using QRCoder;
public class BarcodeService
{
private readonly QRCodeGenerator _generator = new QRCodeGenerator();
public byte[] GenerateQR(string content)
{
var qrCodeData = _generator.CreateQrCode(content, QRCodeGenerator.ECCLevel.M);
var qrCode = new PngByteQRCode(qrCodeData);
return qrCode.GetGraphic(10); // 10px per module
}
}
using QRCoder;
public class BarcodeService
{
private readonly QRCodeGenerator _generator = new QRCodeGenerator();
public byte[] GenerateQR(string content)
{
var qrCodeData = _generator.CreateQrCode(content, QRCodeGenerator.ECCLevel.M);
var qrCode = new PngByteQRCode(qrCodeData);
return qrCode.GetGraphic(10); // 10px per module
}
}
Imports QRCoder
Public Class BarcodeService
Private ReadOnly _generator As New QRCodeGenerator()
Public Function GenerateQR(content As String) As Byte()
Dim qrCodeData = _generator.CreateQrCode(content, QRCodeGenerator.ECCLevel.M)
Dim qrCode = New PngByteQRCode(qrCodeData)
Return qrCode.GetGraphic(10) ' 10px per module
End Function
End Class
Podejście IronBarcode:
using IronBarCode;
public class BarcodeService
{
public byte[] GenerateQR(string content)
{
return BarcodeWriter.CreateBarcode(content, BarcodeEncoding.QRCode)
.ResizeTo(200, 200)
.ToPngBinaryData();
}
}
using IronBarCode;
public class BarcodeService
{
public byte[] GenerateQR(string content)
{
return BarcodeWriter.CreateBarcode(content, BarcodeEncoding.QRCode)
.ResizeTo(200, 200)
.ToPngBinaryData();
}
}
Imports IronBarCode
Public Class BarcodeService
Public Function GenerateQR(content As String) As Byte()
Return BarcodeWriter.CreateBarcode(content, BarcodeEncoding.QRCode) _
.ResizeTo(200, 200) _
.ToPngBinaryData()
End Function
End Class
BarcodeWriter to klasa statyczna — nie wymaga instancji i nie ma obiektu danych pośrednich. Metoda ResizeTo(width, height) zastępuje całość pixele-na-moduł integer, któreQRCoderakceptuje w GetGraphic. GdzieQRCoderokreśla rozmiar wyjścia poprzez liczbę modułów (np. GetGraphic(10) dla obrazu 10px na moduł),IronBarcode przyjmuje absolutne wymiary w pikselach.
Zapisywanie kodów QR do pliku
QRCoder oddziela bajty w pamięci od danych wyjściowych pliku dopiero na etapie końcowym — łańcuch renderowania pozostaje ten sam.IronBarcode wykorzystuje różne metody terminali w tym samym łańcuchu.
Podejście QRCoder:
using QRCoder;
using System.IO;
var generator = new QRCodeGenerator();
var qrCodeData = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.M);
var pngBytes = new PngByteQRCode(qrCodeData).GetGraphic(10);
File.WriteAllBytes("output.png", pngBytes);
using QRCoder;
using System.IO;
var generator = new QRCodeGenerator();
var qrCodeData = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.M);
var pngBytes = new PngByteQRCode(qrCodeData).GetGraphic(10);
File.WriteAllBytes("output.png", pngBytes);
Imports QRCoder
Imports System.IO
Dim generator As New QRCodeGenerator()
Dim qrCodeData = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.M)
Dim pngBytes = New PngByteQRCode(qrCodeData).GetGraphic(10)
File.WriteAllBytes("output.png", pngBytes)
Podejście IronBarcode:
using IronBarCode;
// Save directly — no intermediate byte array needed
BarcodeWriter.CreateBarcode("https://example.com", BarcodeEncoding.QRCode)
.ResizeTo(300, 300)
.SaveAsPng("output.png");
// Or obtain bytes for in-memory use
byte[] pngBytes = BarcodeWriter.CreateBarcode("https://example.com", BarcodeEncoding.QRCode)
.ResizeTo(300, 300)
.ToPngBinaryData();
using IronBarCode;
// Save directly — no intermediate byte array needed
BarcodeWriter.CreateBarcode("https://example.com", BarcodeEncoding.QRCode)
.ResizeTo(300, 300)
.SaveAsPng("output.png");
// Or obtain bytes for in-memory use
byte[] pngBytes = BarcodeWriter.CreateBarcode("https://example.com", BarcodeEncoding.QRCode)
.ResizeTo(300, 300)
.ToPngBinaryData();
Imports IronBarCode
' Save directly — no intermediate byte array needed
BarcodeWriter.CreateBarcode("https://example.com", BarcodeEncoding.QRCode) _
.ResizeTo(300, 300) _
.SaveAsPng("output.png")
' Or obtain bytes for in-memory use
Dim pngBytes As Byte() = BarcodeWriter.CreateBarcode("https://example.com", BarcodeEncoding.QRCode) _
.ResizeTo(300, 300) _
.ToPngBinaryData()
Metoda SaveAsPng jest terminalem, który zapisuje bezpośrednio na dysk. ToPngBinaryData zwraca byte[] do strumieniowania, odpowiedzi HTTP lub przechowywania w bazie danych.
Wyjście SVG
Podejście QRCoder:
using QRCoder;
using System.IO;
var generator = new QRCodeGenerator();
var qrCodeData = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.M);
string svgContent = new SvgQRCode(qrCodeData).GetGraphic(10);
File.WriteAllText("output.svg", svgContent);
using QRCoder;
using System.IO;
var generator = new QRCodeGenerator();
var qrCodeData = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.M);
string svgContent = new SvgQRCode(qrCodeData).GetGraphic(10);
File.WriteAllText("output.svg", svgContent);
Imports QRCoder
Imports System.IO
Dim generator As New QRCodeGenerator()
Dim qrCodeData = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.M)
Dim svgContent As String = New SvgQRCode(qrCodeData).GetGraphic(10)
File.WriteAllText("output.svg", svgContent)
Podejście IronBarcode:
using IronBarCode;
BarcodeWriter.CreateBarcode("https://example.com", BarcodeEncoding.QRCode)
.SaveAsImage("output.svg");
using IronBarCode;
BarcodeWriter.CreateBarcode("https://example.com", BarcodeEncoding.QRCode)
.SaveAsImage("output.svg");
Imports IronBarCode
BarcodeWriter.CreateBarcode("https://example.com", BarcodeEncoding.QRCode) _
.SaveAsImage("output.svg")
Klasa renderera SvgQRCode i jego wywołanie GetGraphic łączą się w jedną terminalną metodę SaveAsImage (przekazanie rozszerzenia .svg daje wyjście w formacie SVG).
Mapowanie poziomów korekty błędów
QRCoder wymaga jawnego wyboru ECC przy każdym wywołaniu CreateQrCode za pomocą wyliczenia QRCodeGenerator.ECCLevel.IronBarcode stosuje rozsądne domyślne ustawienia przy użyciu BarcodeWriter.CreateBarcode i daje możliwość jawnej kontroli przez QRCodeWriter.QrErrorCorrectionLevel.
Podejście QRCoder:
using QRCoder;
var generator = new QRCodeGenerator();
// Medium — suitable for most generation without logos
var dataMedium = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.M);
// High — required when a logo will occlude part of the code
var dataHigh = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.H);
using QRCoder;
var generator = new QRCodeGenerator();
// Medium — suitable for most generation without logos
var dataMedium = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.M);
// High — required when a logo will occlude part of the code
var dataHigh = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.H);
Imports QRCoder
Dim generator As New QRCodeGenerator()
' Medium — suitable for most generation without logos
Dim dataMedium = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.M)
' High — required when a logo will occlude part of the code
Dim dataHigh = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.H)
Podejście IronBarcode:
using IronBarCode;
// Default — equivalent to Medium, applied automatically
BarcodeWriter.CreateBarcode("https://example.com", BarcodeEncoding.QRCode)
.SaveAsPng("default-ecc.png");
// Explicit level via QRCodeWriter
var qr = QRCodeWriter.CreateQrCode(
"https://example.com",
500,
QRCodeWriter.QrErrorCorrectionLevel.Highest
);
qr.SaveAsPng("high-ecc.png");
using IronBarCode;
// Default — equivalent to Medium, applied automatically
BarcodeWriter.CreateBarcode("https://example.com", BarcodeEncoding.QRCode)
.SaveAsPng("default-ecc.png");
// Explicit level via QRCodeWriter
var qr = QRCodeWriter.CreateQrCode(
"https://example.com",
500,
QRCodeWriter.QrErrorCorrectionLevel.Highest
);
qr.SaveAsPng("high-ecc.png");
Imports IronBarCode
' Default — equivalent to Medium, applied automatically
BarcodeWriter.CreateBarcode("https://example.com", BarcodeEncoding.QRCode) _
.SaveAsPng("default-ecc.png")
' Explicit level via QRCodeWriter
Dim qr = QRCodeWriter.CreateQrCode( _
"https://example.com", _
500, _
QRCodeWriter.QrErrorCorrectionLevel.Highest _
)
qr.SaveAsPng("high-ecc.png")
Odwzorowanie poziomów jest następujące: ECCLevel.L → Low, ECCLevel.M → Medium, ECCLevel.Q → High, ECCLevel.H → Highest.
Osadzanie logo
Obie biblioteki obsługują osadzanie logo w kodach QR.QRCoderkieruje to poprzez klasę renderera QRCode (nie PngByteQRCode) z parametrami System.Drawing.Bitmap.IronBarcode dostarcza QRCodeWriter.CreateQrCodeWithLogo() jako dedykowaną metodę fabryczną akceptującą ścieżki do plików zarówno dla URL, jak i logo. Przewodnik po dostosowywaniu stylu kodów QR obejmuje opcje dotyczące rozmiaru logo, jego położenia oraz kombinacji kolorów.
Podejście QRCoder:
using QRCoder;
using System.Drawing;
using System.Drawing.Imaging;
var generator = new QRCodeGenerator();
// ECCLevel.H is required — the logo occludes part of the code
var qrCodeData = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.H);
var qrCode = new QRCode(qrCodeData);
var logoBitmap = new Bitmap("logo.png");
var qrBitmap = qrCode.GetGraphic(10, Color.Black, Color.White, logoBitmap);
qrBitmap.Save("qr-logo.png", ImageFormat.Png);
using QRCoder;
using System.Drawing;
using System.Drawing.Imaging;
var generator = new QRCodeGenerator();
// ECCLevel.H is required — the logo occludes part of the code
var qrCodeData = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.H);
var qrCode = new QRCode(qrCodeData);
var logoBitmap = new Bitmap("logo.png");
var qrBitmap = qrCode.GetGraphic(10, Color.Black, Color.White, logoBitmap);
qrBitmap.Save("qr-logo.png", ImageFormat.Png);
Imports QRCoder
Imports System.Drawing
Imports System.Drawing.Imaging
Dim generator As New QRCodeGenerator()
' ECCLevel.H is required — the logo occludes part of the code
Dim qrCodeData = generator.CreateQrCode("https://example.com", QRCodeGenerator.ECCLevel.H)
Dim qrCode As New QRCode(qrCodeData)
Dim logoBitmap As New Bitmap("logo.png")
Dim qrBitmap = qrCode.GetGraphic(10, Color.Black, Color.White, logoBitmap)
qrBitmap.Save("qr-logo.png", ImageFormat.Png)
Podejście IronBarcode:
using IronBarCode;
QRCodeWriter.CreateQrCodeWithLogo("https://example.com", "logo.png", 500)
.SaveAsPng("qr-logo.png");
using IronBarCode;
QRCodeWriter.CreateQrCodeWithLogo("https://example.com", "logo.png", 500)
.SaveAsPng("qr-logo.png");
Imports IronBarCode
QRCodeWriter.CreateQrCodeWithLogo("https://example.com", "logo.png", 500) _
.SaveAsPng("qr-logo.png")
Zależność System.Drawing.Bitmap została usunięta — CreateQrCodeWithLogo akceptuje ciągi ścieżek plików zarówno dla zawartości, jak i obrazu logo. Korekcja błędów jest automatycznie ustawiana na poziom wymagany do osadzania logo; nie jest potrzebna żadna konfiguracja ECC.
Migracja PayloadGenerator.WiFi
Formaty standardowe WiFi QR generowane przezQRCodersą tworzone przez PayloadGenerator.WiFi. Format wyjściowy jest publicznym standardem (WIFI:T:{auth};S:{ssid};P:{password};;) zdefiniowanym przez specyfikację kodów QR. Podczas migracji ciągi te można tworzyć bezpośrednio.
Podejście QRCoder:
using QRCoder;
var wifi = new PayloadGenerator.WiFi(
ssid: "OfficeNetwork",
password: "SecurePass123",
authenticationMode: PayloadGenerator.WiFi.Authentication.WPA
);
// wifi.ToString() produces: WIFI:T:WPA;S:OfficeNetwork;P:SecurePass123;;
var generator = new QRCodeGenerator();
var qrData = generator.CreateQrCode(wifi.ToString(), QRCodeGenerator.ECCLevel.M);
var qrCode = new PngByteQRCode(qrData);
System.IO.File.WriteAllBytes("wifi.png", qrCode.GetGraphic(10));
using QRCoder;
var wifi = new PayloadGenerator.WiFi(
ssid: "OfficeNetwork",
password: "SecurePass123",
authenticationMode: PayloadGenerator.WiFi.Authentication.WPA
);
// wifi.ToString() produces: WIFI:T:WPA;S:OfficeNetwork;P:SecurePass123;;
var generator = new QRCodeGenerator();
var qrData = generator.CreateQrCode(wifi.ToString(), QRCodeGenerator.ECCLevel.M);
var qrCode = new PngByteQRCode(qrData);
System.IO.File.WriteAllBytes("wifi.png", qrCode.GetGraphic(10));
Imports QRCoder
Dim wifi = New PayloadGenerator.WiFi(
ssid:="OfficeNetwork",
password:="SecurePass123",
authenticationMode:=PayloadGenerator.WiFi.Authentication.WPA
)
' wifi.ToString() produces: WIFI:T:WPA;S:OfficeNetwork;P:SecurePass123;;
Dim generator = New QRCodeGenerator()
Dim qrData = generator.CreateQrCode(wifi.ToString(), QRCodeGenerator.ECCLevel.M)
Dim qrCode = New PngByteQRCode(qrData)
System.IO.File.WriteAllBytes("wifi.png", qrCode.GetGraphic(10))
Podejście IronBarcode:
using IronBarCode;
// Construct the standard WiFi QR string directly
string wifiPayload = "WIFI:T:WPA;S:OfficeNetwork;P:SecurePass123;;";
BarcodeWriter.CreateBarcode(wifiPayload, BarcodeEncoding.QRCode)
.ResizeTo(300, 300)
.SaveAsPng("wifi.png");
using IronBarCode;
// Construct the standard WiFi QR string directly
string wifiPayload = "WIFI:T:WPA;S:OfficeNetwork;P:SecurePass123;;";
BarcodeWriter.CreateBarcode(wifiPayload, BarcodeEncoding.QRCode)
.ResizeTo(300, 300)
.SaveAsPng("wifi.png");
Imports IronBarCode
' Construct the standard WiFi QR string directly
Dim wifiPayload As String = "WIFI:T:WPA;S:OfficeNetwork;P:SecurePass123;;"
BarcodeWriter.CreateBarcode(wifiPayload, BarcodeEncoding.QRCode) _
.ResizeTo(300, 300) _
.SaveAsPng("wifi.png")
Dla zespołów używających wielu typów PayloadGenerator (vCard, CalendarEvent, Geo, SMS), podejście jest takie samo: zidentyfikuj sformatowany ciąg, który każdy generator produkcji przy użyciu wyniku .ToString(), a następnie skonstruuj ten ciąg bezpośrednio lub za pomocą małej statycznej metody pomocniczej.
Odnośnik do dokumentacji APIQRCoderdla IronBarcode
| QRCoder | IronBarcode | Uwagi |
|---|---|---|
new QRCodeGenerator() |
Klasa statyczna — brak instancji | BarcodeWriter nie wymaga instancji |
qrGenerator.CreateQrCode(data, ECCLevel.M) |
BarcodeWriter.CreateBarcode(data, BarcodeEncoding.QRCode) |
Bezpośrednie zastąpienie |
new PngByteQRCode(qrCodeData) |
Nie jest potrzebne | Renderowanie jest częścią łańcucha płynnego |
qrCode.GetGraphic(20) zwracanie byte[] |
.ToPngBinaryData() |
Rozmiar za pomocą .ResizeTo(w, h) |
Wzorzec File.WriteAllBytes(path, bytes) |
.SaveAsPng(path) |
Metoda terminalna na GeneratedBarcode |
new SvgQRCode(qrCodeData).GetGraphic(10) |
.SaveAsImage(path) |
Przekaż rozszerzenie .svg dla wyjścia SVG |
new QRCode(qrCodeData).GetGraphic(...) |
QRCodeWriter.CreateQrCode(data, size, level) |
Służy do dostosowywania logo i kolorów |
QRCodeGenerator.ECCLevel.L |
QRCodeWriter.QrErrorCorrectionLevel.Low |
|
QRCodeGenerator.ECCLevel.M |
QRCodeWriter.QrErrorCorrectionLevel.Medium |
Domyślnie, jeśli nie określono inaczej |
QRCodeGenerator.ECCLevel.Q |
QRCodeWriter.QrErrorCorrectionLevel.High |
|
QRCodeGenerator.ECCLevel.H |
QRCodeWriter.QrErrorCorrectionLevel.Highest |
Wymagane do osadzenia logo |
PayloadGenerator.WiFi(...).ToString() |
"WIFI:T:WPA;S:{ssid};P:{pass};;" |
Tworzenie standardowego ciągu znaków bezpośrednio |
PayloadGenerator.ContactData(...).ToString() |
"BEGIN:VCARD\n..." |
vCard to standard publiczny |
| Brak API do odczytu | BarcodeReader.Read(path) |
Nowa funkcja — brak oddzielnej biblioteki |
| Tylko format QR | Ponad 50 formatów za pomocą BarcodeEncoding.* |
Nowa funkcja |
Typowe problemy związane z migracją i ich rozwiązania
Problem 1: Zmiana formatu ciągu znaków w PayloadGenerator
QRCoder: PayloadGenerator.WiFi, PayloadGenerator.ContactData i inne pomocnicze automatycznie tworzą sformatowane ciągi. Kod przekazuje wynik .ToString() obiektu pomocniczego do CreateQrCode.
Rozwiązanie: Zidentyfikuj ciąg, jaki generuje każdy rodzaj PayloadGenerator — jego format jest udokumentowany w specyfikacji kodów QR i łatwy do odtworzenia. Dla WiFi: WIFI:T:WPA;S:{ssid};P:{password};;. Dla vCard: standardowe bloki BEGIN:VCARD / END:VCARD. Napisz statyczne metody pomocnicze, jeśli wiele miejsc wywołania używa tego samego typu ładunku:
public static string WifiPayload(string ssid, string password, string auth = "WPA")
=> $"WIFI:T:{auth};S:{ssid};P:{password};;";
public static string WifiPayload(string ssid, string password, string auth = "WPA")
=> $"WIFI:T:{auth};S:{ssid};P:{password};;";
Public Shared Function WifiPayload(ssid As String, password As String, Optional auth As String = "WPA") As String
Return $"WIFI:T:{auth};S:{ssid};P:{password};;"
End Function
Problem 2: Mapowanie enum ECCLevel
QRCoder: QRCodeGenerator.ECCLevel to zagnieżdżona enum z wartościami L, M, Q, H. Jest to wymagany parametr przy każdym wywołaniu CreateQrCode.
Rozwiązanie: Przypisz każdą wartość do jej odpowiednika QRCodeWriter.QrErrorCorrectionLevel podczas korzystania z trasy QRCodeWriter. Podczas korzystania z BarcodeWriter.CreateBarcode, poziom ECC domyślnie ustawiony jest na Średni i nie wymaga parametru. Zaktualizuj każde miejsce wywołania:
//QRCoderECCLevel.H →IronBarcode QrErrorCorrectionLevel.Highest
var qr = QRCodeWriter.CreateQrCode(data, 500, QRCodeWriter.QrErrorCorrectionLevel.Highest);
//QRCoderECCLevel.M →IronBarcode default (no parameter needed)
BarcodeWriter.CreateBarcode(data, BarcodeEncoding.QRCode);
//QRCoderECCLevel.H →IronBarcode QrErrorCorrectionLevel.Highest
var qr = QRCodeWriter.CreateQrCode(data, 500, QRCodeWriter.QrErrorCorrectionLevel.Highest);
//QRCoderECCLevel.M →IronBarcode default (no parameter needed)
BarcodeWriter.CreateBarcode(data, BarcodeEncoding.QRCode);
'QRCoderECCLevel.H →IronBarcode QrErrorCorrectionLevel.Highest
Dim qr = QRCodeWriter.CreateQrCode(data, 500, QRCodeWriter.QrErrorCorrectionLevel.Highest)
'QRCoderECCLevel.M →IronBarcode default (no parameter needed)
BarcodeWriter.CreateBarcode(data, BarcodeEncoding.QRCode)
Problem 3: Usunięcie klasy Renderer
QRCoder: Każdy format wyjściowy wymaga własnej instancji klasy renderera — PngByteQRCode, SvgQRCode, AsciiQRCode, Base64QRCode, QRCode. Te klasy akceptują QRCodeData i udostępniają GetGraphic z różnymi typami zwrotów.
Rozwiązanie: Usuń wszystkie instancje klasy renderera.IronBarcode wbudowuje formatowanie wyjścia w metody terminala łańcucha fluent. Zastąp new PngByteQRCode(data).GetGraphic(n) przez .ToPngBinaryData() po .ResizeTo(). Zastąp new SvgQRCode(data).GetGraphic(n) przez .SaveAsImage(path) (przekazując rozszerzenie .svg). Obiekt pośredni QRCodeData również znika — nie jest potrzebny w IronBarcode.
Problem 4: Usunięcie PngByteQRCode i skalowanie oparte na modułach
QRCoder: PngByteQRCode.GetGraphic(int pixelsPerModule) określa rozmiar wyjścia przez liczbę pikseli na moduł QR. Wymiary gotowego obrazu zależą od liczby modułów, która zmienia się w zależności od długości treści i poziomu ECC.
Rozwiązanie: Zastąp rozmiarowanie oparte na modułach przez ResizeTo(int width, int height) dla absolutnych wymiarów pikseli. Jeśli kod obliczał oczekiwany rozmiar wyjściowy dynamicznie na podstawie liczby modułów, należy przejść na stały rozmiar docelowy, który spełnia wymagania dotyczące wyjścia:
// Before: GetGraphic(20) — output size varies with content
var bytes = new PngByteQRCode(qrData).GetGraphic(20);
// After: fixed 400×400 regardless of content
byte[] bytes = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.QRCode)
.ResizeTo(400, 400)
.ToPngBinaryData();
// Before: GetGraphic(20) — output size varies with content
var bytes = new PngByteQRCode(qrData).GetGraphic(20);
// After: fixed 400×400 regardless of content
byte[] bytes = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.QRCode)
.ResizeTo(400, 400)
.ToPngBinaryData();
Imports System
' Before: GetGraphic(20) — output size varies with content
Dim bytes = New PngByteQRCode(qrData).GetGraphic(20)
' After: fixed 400×400 regardless of content
Dim bytes As Byte() = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.QRCode) _
.ResizeTo(400, 400) _
.ToPngBinaryData()
Lista kontrolna migracji QRCoder
Zadania przed migracją
Przed wprowadzeniem jakichkolwiek zmian należy sprawdzić kod źródłowy pod kątem wszystkich zastosowań QRCoder:
# Find allQRCodernamespace imports
grep -r "using QRCoder" --include="*.cs" .
# Find all generator and renderer instantiations
grep -r "QRCodeGenerator\|PngByteQRCode\|SvgQRCode\|AsciiQRCode\|QRCode\b" --include="*.cs" .
# Find all PayloadGenerator usages
grep -r "PayloadGenerator\." --include="*.cs" .
# Find ECCLevel references
grep -r "ECCLevel\." --include="*.cs" .
# Find ZXing.Net usage to remove at the same time
grep -r "using ZXing" --include="*.cs" .
# Find allQRCodernamespace imports
grep -r "using QRCoder" --include="*.cs" .
# Find all generator and renderer instantiations
grep -r "QRCodeGenerator\|PngByteQRCode\|SvgQRCode\|AsciiQRCode\|QRCode\b" --include="*.cs" .
# Find all PayloadGenerator usages
grep -r "PayloadGenerator\." --include="*.cs" .
# Find ECCLevel references
grep -r "ECCLevel\." --include="*.cs" .
# Find ZXing.Net usage to remove at the same time
grep -r "using ZXing" --include="*.cs" .
- Udokumentuj wszystkie rodzaje
PayloadGeneratorużywane i zanotuj ich formaty wyjściowe. - Odnotuj wszystkie używane wartości poziomu ECC oraz miejsca ich wywołania
- Zidentyfikuj wszelki kod odczytu ZXing.Net, który był sparowany z QRCoderem w celu dekodowania — można go jednocześnie zastąpić
- Uzyskaj klucz licencyjny IronBarcode(klucze próbne są dostępne bez rejestracji)
Zadania związane z aktualizacją kodu
- Uruchom
dotnet remove package QRCoder - Uruchom
dotnet remove package ZXing.Net, jeśli był używany tylko do odczytu wraz z QRCoder - Uruchom
dotnet add package IronBarcode - Dodaj
IronBarCode.License.LicenseKey = "YOUR-KEY";do startu aplikacji - Zastąp wszystkie importy
using QRCoder;przezusing IronBarCode; - Usuń wszystkie deklaracje instancji
new QRCodeGenerator()—BarcodeWriterjest statyczne - Zastąp wszystkie wzorce
generator.CreateQrCode(data, ECCLevel.X)+ łańcuch renderer przez łańcuchyBarcodeWriter.CreateBarcode(data, BarcodeEncoding.QRCode) - Zastąp wywołania
.GetGraphic(n)przez.ToPngBinaryData()i dodaj.ResizeTo(w, h)przed terminalem - Zastąp wzorce zapisywania
File.WriteAllBytes(path, bytes)metodami terminalnymi.SaveAsPng(path) - Zastąp
new SvgQRCode(data).GetGraphic(n)przez.SaveAsImage(path)(przekaż rozszerzenie.svg) - Zastąp
PayloadGenerator.WiFi(...)i inne instancje pomocnicze sformatowanymi ciągami bezpośrednimi - Przypisz każdą wartość
QRCodeGenerator.ECCLeveldo jej odpowiednikaQRCodeWriter.QrErrorCorrectionLevel - Zastąp dowolne wywołania
BarcodeReaderGeneric.Decode(bitmap)w ZXing.Net przezBarcodeReader.Read(path) - Dla osadzania logo zastąp
new QRCode(data).GetGraphic(n, ..., logoBitmap)przezQRCodeWriter.CreateQrCodeWithLogo(data, logoPath, size)
Testy po migracji
- Zeskanuj wszystkie wygenerowane kody QR przy użyciu co najmniej dwóch niezależnych aplikacji do skanowania kodów QR, aby sprawdzić ich czytelność
- Zweryfikuj, czy kody QR z osadzonym logo są poprawnie skanowane — potwierdź, że poziom korekcji błędów to
Highest - Porównaj wygląd wygenerowanego kodu z przykładami sprzed migracji, gdzie wymagana jest spójność wyglądu
- Przetestuj wszystkie zamiany
PayloadGenerator— potwierdź, że WiFi, vCard i inne ciągi ładunku są prawidłowo dekodowane na urządzeniach docelowych - Jeśli ZXing.Net został również usunięty, zweryfikuj wszystkie ścieżki odczytu kodów kreskowych działające przez
BarcodeReader.Read - Uruchom aplikację w czystym środowisku, aby upewnić się, że żadne pozostałości odwołań doQRCoderlub ZXing.Net nie powodują błędów wiązania
- Sprawdź, czy klucz licencyjny IronBarcode został poprawnie załadowany w środowiskach produkcyjnych i testowych
Kluczowe korzyści wynikające z migracji do IronBarcode
Pojedyncze API dla wszystkich operacji na kodach kreskowych: Po migracji każde zadanie związane z kodami kreskowymi — generowanie, odczyt, stemplowanie PDF — używa tej samej przestrzeni nazw IronBarCode i tych samych punktów początkowych. Programiści dołączający do projektu uczą się obsługi jednego interfejsu API zamiast trzech. Sprawdzanie kodu w całym podsystemie BarCode staje się spójne. Wyszukiwanie dokumentacji jest scentralizowane.
Odczyt kodów kreskowych bez drugiej biblioteki: BarcodeReader.Read obsługuje pliki obrazów, strony PDF, strumienie oraz bitmapy w pamięci, z automatycznym wykrywaniem formatu. Funkcja odczytu, która wcześniej wymagała użycia ZXing.Net — wraz z wymaganiami dotyczącymi specyfikacji formatu i kwestiami bezpieczeństwa wątków — jest teraz dostępna natychmiast poprzez jedno wywołanie metody. Przewodnik dotyczący odczytu kodów kreskowych z obrazów obejmuje wykrywanie wielu kodów kreskowych, wstępne przetwarzanie obrazów oraz skanowanie stron PDF.
Rozbudowa formatów bez nowych zależności: Dodanie kodu 128, EAN-13, DataMatrix,PDF417lub innego obsługiwanego formatu po migracji wymaga tylko innej wartości parametru BarcodeEncoding. Nie ma żadnych nowych pakietów do zainstalowania, żadnych nowych interfejsów API do opanowania ani żadnych problemów z kompatybilnością wersji, którymi trzeba by się zajmować. Nowe wymagania dotyczące formatu sprowadzają się do zmiany w jednym wierszu, a nie do integracji nowej biblioteki.
Uproszczone dostosowywanie kodu QR: Osadzanie logo, zmiany kolorów i kontrola strefy spokojnej są dostępne jako nazwane metody na wyniku QRCodeWriter. Zależność System.Drawing.Bitmap, którąQRCoderwymaga do osadzania logo, jest zastąpiona przez prosty ciąg ścieżki pliku. Przewodnik po dostosowywaniu stylu kodów QR zawiera wszystkie dostępne opcje dostosowywania.
Wbudowana integracja z plikami PDF: BarCodes mogą być odczytywane z przychodzących dokumentów PDF i umieszczane w istniejących plikach PDF bez konieczności dodawania biblioteki PDF. W procesach przetwarzania dokumentów, które wcześniej wymagały oddzielnej zależności od formatu PDF, obecnie zintegrowano funkcje BarCode i plików PDF.
Zmniejszone długoterminowe koszty utrzymania: Przejście z trzech lub czterech niezależnych pakietów na jeden eliminuje narastające koszty związane ze śledzeniem wielu cykli wydawniczych, rozwiązywaniem konfliktów między wersjami bibliotek oraz aktualizowaniem wielu zestawów testowych w miarę rozwoju wersji .NET. Koszt utrzymania podsystemu BARCODE sprowadza się do zależności od jednego pakietu.
Często Zadawane Pytania
Dlaczego warto przejść z QRCoder.NET na IronBarcode?
Typowe powody to uproszczenie licencjonowania (eliminacja złożoności związanej z SDK i kluczem uruchomieniowym), zniesienie limitów przepustowości, uzyskanie natywnej obsługi plików PDF, usprawnienie wdrażania w środowisku Docker/CI/CD oraz ograniczenie powtarzalnego kodu API w kodzie produkcyjnym.
Jak zastąpić wywołania API QRCoder za pomocą IronBarcode?
Zastąp standardowe fragmenty kodu dotyczące tworzenia instancji i licencjonowania wyrażeniem IronBarCode.License.LicenseKey = "key". Zastąp wywołania czytnika wyrażeniem BarcodeReader.Read(path), a wywołania zapisu wyrażeniem BarcodeWriter.CreateBarcode(data, encoding). Metody statyczne nie wymagają zarządzania instancjami.
Jak bardzo zmienia się kod podczas migracji z QRCoder.NET do IronBarcode?
Większość migracji skutkuje zmniejszeniem liczby linii kodu. Usuwane są standardowe fragmenty dotyczące licencji, konstruktory instancji oraz jawna konfiguracja formatów. Podstawowe operacje odczytu/zapisu są mapowane na krótsze odpowiedniki w IronBarcode z bardziej przejrzystymi obiektami wynikowymi.
Czy podczas migracji muszę mieć zainstalowane zarówno QRCoder.NET, jak i IronBarcode?
Nie. Większość migracji polega na bezpośredniej wymianie, a nie na równoległym działaniu. Należy migrować po jednej klasie usługowej na raz, zastąpić odwołanie do NuGet oraz zaktualizować wzorce instancjonowania i wywoływania API przed przejściem do kolejnej klasy.
Jaka jest nazwa pakietu NuGet dla IronBarcode?
Pakiet nosi nazwę „IronBarcode” (z wielkimi literami B i C). Zainstaluj go za pomocą polecenia „Install-Package IronBarcode” lub „dotnet add package IronBarcode”. Dyrektywa using w kodzie to „using IronBarcode;”.
W jaki sposób IronBarcode upraszcza wdrażanie Docker w porównaniu z QRCoder.NET?
IronBarcode to pakiet NuGet bez zewnętrznych plików SDK ani konfiguracji licencji. W Dockerze należy ustawić zmienną środowiskową IRONBARCODE_LICENSE_KEY, a pakiet zajmie się weryfikacją licencji podczas uruchamiania.
Czy IronBarcode automatycznie wykrywa wszystkie formaty kodów kreskowych po migracji z QRCoder?
Tak. IronBarcode automatycznie wykrywa symbole we wszystkich obsługiwanych formatach. Wyraźne wyliczenie typów kodów kreskowych nie jest wymagane. Jeśli format jest już znany, a wydajność ma znaczenie, BarcodeReaderOptions pozwala ograniczyć obszar wyszukiwania w celu optymalizacji.
Czy IronBarcode może odczytywać BarCodes z plików PDF bez oddzielnej biblioteki?
Tak. BarCodeReader.Read("document.pdf") przetwarza pliki PDF natywnie. Wyniki obejmują PageNumber, Format, Value i Confidence dla każdego znalezionego kodu kreskowego. Nie jest wymagany żaden zewnętrzny etap renderowania pliku PDF.
W jaki sposób IronBarcode obsługuje równoległe przetwarzanie kodów kreskowych?
Metody statyczne IronBarcode są bezstanowe i bezpieczne dla wątków. Użyj Parallel.ForEach bezpośrednio na listach plików bez zarządzania instancjami dla poszczególnych wątków. BarcodeReaderOptions.MaxParallelThreads kontroluje wewnętrzny limit wątków.
Jakie właściwości wyników ulegają zmianie podczas migracji z QRCoder.NET do IronBarcode?
Typowe zmiany nazw: BarcodeValue staje się Value, BarcodeType staje się Format. Wyniki IronBarcode zawierają również Confidence i PageNumber. Funkcja wyszukiwania i zamiany w całym rozwiązaniu obsługuje zmiany nazw w istniejącym kodzie przetwarzania wyników.
Jak skonfigurować licencjonowanie IronBarcode w potoku CI/CD?
Zapisz IronBarcode_LICENSE_KEY jako sekret potoku i przypisz IronBarCode.License.LicenseKey w kodzie uruchamiającym aplikację. Jeden sekret obejmuje wszystkie środowiska, w tym środowisko programistyczne, testowe, przejściowe i produkcyjne.
Czy IronBarcode obsługuje generowanie kodów QR z niestandardowym stylem?
Tak. Funkcja QRCodeWriter.CreateQrCode() obsługuje niestandardowe kolory za pomocą ChangeBarCodeColor(), osadzanie logo za pomocą AddBrandLogo(), konfigurowalne poziomy korekcji błędów oraz wiele formatów wyjściowych, w tym PNG, JPG, PDF i strumień.

