Barcode pada label pengiriman atau faktur memiliki satu tugas, yaitu dibaca oleh pemindai (scanner) pada percobaan pertama. Apakah barcode tersebut berhasil melewati pemindaian itu diputuskan jauh sebelum paket mencapai dermaga. Ini ditentukan oleh bagaimana simbol tersebut diletakkan di halaman. Kesalahan paling umum dalam alur pelaporan Delphi adalah merender barcode sebagai bitmap di tempat lain dan menempatkan gambar tersebut ke dalam PDF. Ini terlihat baik-baik saja di layar pada satu tingkat zoom dan kemudian menurun kualitasnya di tempat lain.
Alternatifnya adalah menggambar simbol sebagai konten vektor, langsung ke halaman. PDFlibPas mengekspos keluarga pemanggilan gambar untuk hal ini, yang mencakup simbol matriks 2D QR, PDF417, dan DataMatrix, keluarga linier melalui Code128 dan GS1-128, serta USPS Intelligent Mail untuk otomatisasi pos. Argumen untuk vektor bukanlah soal estetika. Ini tentang apakah garis-garis (bars) mendarat di tempat yang diharapkan oleh pemindai.
Mengapa vektor lebih baik daripada gambar bitmap
Barcode adalah pola garis dan ruang, atau dalam dua dimensi berupa kisi-kisi modul gelap dan terang. Dekoder bekerja dengan mengukur rasio lebar tersebut. Apa pun yang mendistorsi rasio adalah noise yang mengurangi batas toleransi kesalahan (error budget) simbol. Gambar barcode yang dirasterisasi membawa piksel tetap. Ketika PDF dirender to a printer whose dots do not divide evenly into the image grid, the rasterizer has to resample, and module edges that should be sharp get spread across two device pixels. A narrow bar can fatten, an adjacent space can thin, and the width ratio the decoder relies on drifts.
Drawn as vector content, the same symbol is a set of filled rectangles described in PDF user-space coordinates. There is no fixed pixel grid to fight. At print time the device renders each rectangle at the resolution it actually has, so every module edge is as crisp as the hardware allows, at any scale and any print size. Scale a vector symbol up for a pallet label or shrink it for a parcel and the geometry stays exact. That precision is what keeps the first-pass read rate high, which is the whole point of putting a barcode on the page.
Kode QR dan empat tingkat koreksi kesalahan
QR adalah simbol matriks 2D yang dibaca di kedua sumbu sekaligus, itulah sebabnya ia mengemas banyak data ke dalam kotak kecil. Toleransi kerusakannya berasal dari koreksi kesalahan Reed-Solomon, yang ditawarkan dalam empat tingkat. Tingkat L memulihkan sekitar 7 percent of the codewords, M about 15 percent, Q about 25 percent, and H about 30 percent. Higher correction is not free. The recovery codewords occupy module capacity, so for a fixed amount of data a higher level forces a denser or physically larger symbol.
Pertukaran tersebut adalah pertanyaan tentang lingkungan tempat simbol tersebut akan berada. Dokumen digital bersih yang hanya akan dipindai dari layar dapat berada di tingkat L dan tetap ringkas. Label yang akan dicetak, dipegang, tergores, dan mungkin sebagian tertutup lakban memerlukan Q atau H, karena redundansi ekstra adalah apa yang memungkinkan dekoder merekonstruksi payload dari simbol yang tidak lagi murni. DrawQRCode mengambil posisi dan SymbolSize yang menetapkan lebar dan tinggi gambar, ditambah nilai EncodeOptions yang memilih mode data (0 untuk otomatis, atau varian numerik, alfanumerik, ISO-8859-1, dan UTF-8) serta nilai DrawOptions untuk orientasi.
var
Pdf: TPDFlib;
begin
Pdf := TPDFlib.Create(nil);
try
Pdf.NewDocument;
Pdf.SetPageSize('A4');
Pdf.SetMeasurementUnits(1); // 1 = millimetres
Pdf.NewPage;
// 30 mm square QR, automatic encoding, normal orientation
Pdf.DrawQRCode(20, 20, 30, 'https://www.loslab.com/', 0, 0);
Pdf.SaveToFile('Label_QR.pdf');
finally
Pdf.Free;
end;
end;
Tingkat koreksi itu sendiri dipilih oleh enkoder agar sesuai dengan data ke dalam simbol yang Anda minta. Jika Anda memerlukan jaminan tingkat tinggi untuk lingkungan yang keras, ukurlah simbol dengan longgar sehingga enkoder memiliki anggaran modul untuk dihabiskan pada redundansi daripada dipaksa turun agar muat.
PDF417 untuk ID dan label pengiriman
PDF417 adalah simbol linier bertumpuk. Setiap baris adalah barcode linier pendek, dan baris-baris tersebut menumpuk membentuk blok, itulah sebabnya ia muncul di SIM, kartu pas masuk pesawat (boarding pass), dan label pengiriman kurir di mana strip data yang lebih lebar harus berada dalam jejak persegi panjang. Koreksi kesalahannya berjalan pada skala 0 hingga 8. Setiap langkah kira-kira melipatgandakan jumlah codeword koreksi, sehingga tingkat 5 membawa redundansi yang jauh lebih banyak daripada tingkat 1, dengan konsekuensi lebih banyak codeword di halaman.
Bentuk blok PDF417 dapat disesuaikan, dan itu penting karena label memiliki area tetap untuk diisi. DrawPDF417SymbolEx mengekspos kontrol yang tidak dimiliki oleh pemanggilan dasar. FixedColumns dan FixedRows menyematkan jumlah kolom data dan jumlah baris, dengan 0 berarti membiarkan enkoder yang memutuskan. ErrorLevel mengambil nilai -1 untuk otomatis atau nilai eksplisit 0 hingga 8. ModuleSize adalah lebar elemen tersempit dalam unit pengukuran saat ini, dan HeightWidthRatio menetapkan seberapa tinggi setiap modul relatif terhadap lebarnya, yang merupakan cara Anda membuat blok menjadi pendek dan lebar atau tinggi dan sempit agar sesuai dengan ruang yang Anda miliki.
// Fixed 10 data columns, automatic rows, error level 5,
// module 0.30 mm wide, rows three times the module width tall
Pdf.DrawPDF417SymbolEx(20, 60, 'PDF417 PAYLOAD 0123456789',
0, // Options: 0 = normal orientation
10, // FixedColumns
0, // FixedRows: 0 = automatic
5, // ErrorLevel: 0 to 8
0.30, // ModuleSize, in the current measurement unit
3.0); // HeightWidthRatio
Menetapkan kolom adalah opsi umum pada templat label. Jumlah kolom yang konstan memberikan lebar blok yang dapat diprediksi, sehingga tata letak di sekitarnya tidak bergeser saat panjang payload terenkode berubah dari satu dokumen ke dokumen berikutnya, sementara enkoder menambahkan baris ke bawah untuk menyerap perbedaannya.
DataMatrix untuk tanda kecil
DataMatrix adalah simbol yang dicari ketika tanda harus berukuran kecil. Ini adalah kisi 2D kompak yang menggunakan ECC 200, skema Reed-Solomon modern, dan tetap dapat dibaca pada ukuran di mana simbol QR dari data yang sama akan terlihat canggung. Hal itu menjadikannya pilihan standar untuk penandaan komponen langsung (direct part marking), komponen elektronik kecil, dan label logistik yang padat.
DrawDataMatrixSymbol mengambil ModuleSize untuk pitch titik, Encoding bernilai 1 untuk ASCII, dan SymbolSize berupa 0 untuk otomatis atau salah satu dimensi persegi dan persegi panjang standar, dari 10x10 hingga 132x132. Parameter Options menggabungkan orientasi dengan lebar zona sunyi (quiet-zone), di mana penambahan 100 hingga 400 menetapkan batas putih modul satu hingga empat. Zona sunyi bukanlah hiasan. Dekoder memerlukan batas yang jelas tersebut untuk menemukan pola pencari (finder pattern) simbol, dan simbol yang berdesakan dengan tinta lain adalah simbol yang gagal diperoleh informasinya.
// Auto-sized ASCII DataMatrix, 0.5 mm module, normal orientation
// with a one-module quiet zone (Options 0 + 100)
Pdf.DrawDataMatrixSymbol(20, 110, 0.5, 'DMX-SN-4408812',
1, // Encoding: 1 = ASCII
0, // SymbolSize: 0 = automatic
100); // Options: normal + one-module quiet zone
Di mana barcode 1D masih berkuasa
Simbol dua dimensi menarik banyak perhatian, tetapi barcode linier masih menguasai sebagian besar bidang ritel dan logistik, dan alasannya adalah basis terpasang pemindai laser yang membaca satu sapuan saja. Code128 adalah pekerja keras untuk data alfanumerik, dan efisiensinya berasal dari tiga set karakter. Set A mencakup karakter kontrol dan huruf besar, set B mencakup rentang penuh ASCII yang dapat dicetak, dan set C adalah yang penting untuk angka. Subset C mengodekan sepasang digit dalam satu karakter simbol tunggal, sehingga rangkaian data numerik mengambil setengah dari karakter simbol yang dibutuhkannya pada set A or B. That is the most compact way to lay down a long numeric barcode, and the PDFlibPas Code128 implementation combines the B and C sets automatically to reach it.
GS1-128, standar yang sebelumnya bernama EAN-128, dibangun di atas Code128 dengan membawa Application Identifier, awalan dalam tanda kurung yang memberi tahu sistem penerima apakah digit berikutnya merupakan nomor seri, kode batch, atau tanggal kedaluwarsa. Strukturnya ditandai oleh FNC1, karakter non-data khusus yang menandai simbol sebagai terenkode-GS1 dan memisahkan kolom dengan panjang variabel. Di PDFlibPas Anda menggambar simbol GS1-128 dengan DrawBarcode menggunakan tipe Code128 dan penanda literal [FNC1] yang ditempatkan di string data di mana setiap pengidentifikasi aplikasi dimulai.
var
W: Double;
begin
// Code128, with FNC1 markers this becomes a GS1-128 symbol.
// AI 21 (serial) = ABC123, AI 20 (variant) = 13
Pdf.DrawBarcode(20, 150, 60, 18, '[FNC1]21ABC123[FNC1]2013',
3, // Barcode: 3 = Code128
0); // Options: 0 = default drawing
// Measure the rendered width for a 0.30 mm narrow bar before laying out
W := Pdf.GetBarcodeWidth(0.30, '[FNC1]21ABC123[FNC1]2013', 3);
end;
Untuk surat, USPS Intelligent Mail, juga disebut OneCode, mengodekan data rute dan pelacakan dalam satu barcode termodulasi-tinggi untuk otomatisasi pos. DrawIntelligentMailBarcode mengambil geometri eksplisit untuk lebar garis (bar width), tinggi garis penuh, tinggi pelacak (tracker height), dan lebar ruang, dengan data yang disediakan sebagai string 20, 25, 29, atau 31 digit saja. Tinggi garis dan pelacak yang eksplisit ada karena simbol membawa informasi tentang apakah setiap garis merupakan garis penuh, ascender, atau descender, dan pembaca pos bergantung pada tinggi tersebut yang harus sesuai spesifikasi.
Menggambar ke dalam halaman dan mengukur untuk tata letak
Setiap panggilan yang ditampilkan di sini menggambar ke dalam konten halaman yang saat ini dipilih, permukaan yang sama yang menerima teks dan gambar Anda, sehingga barcode diproduksi sebagai bagian dari pembuatan dokumen normal, bukan diimpor sebagai aset terpisah. Karena simbol adalah konten vektor, data yang mereka kodekan dan geometri yang mereka tempati sama-sama diketahui pada waktu penggambaran, yang memungkinkan Anda menempatkannya secara deterministik.
Tata letak untuk keluarga linier mendapat manfaat dari pengukuran terlebih dahulu. GetBarcodeWidth mengembalikan total lebar gambar barcode untuk lebar garis sempit (narrow-bar width) dan tipe barcode yang diberikan, sehingga Anda dapat memesan ruang horizontal yang tepat sebelum Anda melakukan penggambaran, daripada menebak-nebak dan menemukan tumpang tindih setelah halaman dibuat. Simbol 2D lebih mudah ditempatkan karena Anda menetapkan ukuran gambarnya secara langsung melalui SymbolSize atau ModuleSize, dan simbol tersebut mengisi jejak tersebut. Apa pun pilihannya, disiplinnya sama. Tentukan ukuran fisik dari lingkungan pemindaian, konfirmasikan bahwa simbol tersebut cocok dengan slot yang Anda miliki, dan biarkan geometri vektor menjaga setiap tepi tetap tajam dari pratinjau layar hingga cetakan akhir.
Untuk alur kerja pembuatan halaman yang lebih luas tempat barcode ini masuk, teknik dalam artikel kami tentang ekstraksi teks, gambar, dan font mencakup pembacaan konten kembali keluar dari PDF, dan panduan untuk penggabungan dan pemisahan PDF besar dengan akses langsung menunjukkan cara menyusun dokumen bervolume tinggi secara efisien. Keduanya berpasangan secara alami dengan API penggambaran yang dijelaskan di sini, yang dikirimkan sebagai bagian dari Delphi PDF Library for Delphi and C++Builder alongside the text, graphics, form, and signature APIs covered elsewhere on this blog.