HotPDF, yüklü bir PDF sayfasındaki döndürülmüş QR sembollerini, örneklenen modül matrisini decoder'ın içinde sekiz D4 yöneliminin tamamından geçirerek normalize eder. Doğrusal symbology'lerde işleyen dış döndürme denemesi QR için çalışamaz ve nedenini anlamak, bozuk görünen ama bozuk olmayan bir decoder'ın peşinde bir gün kaybetmenizi önler
Senaryo son derece sıradandır. Taranmış teslim pusulaları PDF olarak gelir, her sayfada bir QR etiketi vardır ve tarayıcı operatörü, desteyi tepsinin kabul ettiği yönde beslemiştir. Bazı etiketler dik durur, bazıları çeyrek tur kaymıştır, birkaçı tepetaklaktır. Barkod decoder'ını çağırırsınız; sayfaların yarısı çözülür, öbür yarısı hiçbir hata vermeden boş döner
Tarama maskesini döndürmek döndürülmüş bir QR'yi neden hiç düzeltmez?
Çünkü bir QR finder pattern yerleşimi kasıtlı olarak asimetriktir ve bütün imgeyi döndürmek o asimetriyi ortadan kaldırmak yerine korur. QR Code, üç finder karesini sol üst, sağ üst ve sol alt köşelere yerleştirir, sağ alt köşeyi boş bırakır (ISO/IEC 18004:2015 §6.3.3). Eksik o köşe, yönelim ipucudur. Sayfa bitmap'ini doksan derece döndürün ve boşluk yalnızca başka bir köşeye taşınır. Üç köşeli bir yerleşimi kendisiyle eşleyen önemsiz olmayan hiçbir düzlem döndürmesi yoktur; bu yüzden yalnızca kanonik düzeni kabul eden bir decoder, her denemeyi sırayla reddeder
Bu önemli çünkü bariz çözüm yanlış olandır. Doğal içgüdü, denemeyi dışarıya asmaktır: sayfayı render edin, maskeleri decoder'a verin ve bu başarısız olursa maski döndürüp 90, 180 ve 270 derece için yeniden deneyin. Code 39 için bu politika tam da doğrudur; çünkü doğrusal bir symbology, çubuklar yatay aktığında tarayıcının bulabileceği bir start/stop deseni taşır. QR içinse politika, dört garantili başarısızlık ve ardından "bulunamadı" raporudur
Modül matrisine uygulanan D4 grubu
Normalizasyonun doğru yeri, örnekleme sonrasıdır: piksel maskesi üzerinde değil, boolean modül ızgarası üzerinde. Decoder, sembolü koyu ve açık modüllerden oluşan bir n çarpı n matrisine çözdükten sonra karenin dihedral grubunu sıralayabilir: dört döndürme çarpı iki yansıma, toplam sekiz aday yönelim. Her aday için finder üçlüsünü kontrol eder ve üç finder'ı sol üst, sağ üst ve sol alt konumlarına düşen ilk aday, gerçek yönelimdir. Oradan itibaren mevcut işlem hattı değişmeden akar; çünkü format information bitleri, zikzak veri yerleşimi ve Reed-Solomon düzeltmesi kanonik bir matris varsayar ve artık bir tane alır
İki özellik bunu ucuz kılar. Matris, render edilen bitmap'e göre küçüktür; sekiz transpoze, sekiz sayfa render'ından çok daha ucuzdur. Ve matris, örnekleyicinin kurduğu temiz bir boolean dizisidir; böylece aradaki hiçbir dönüşüm, hiç örneklenmemiş değerler üretemez
Sürüm tespiti bir bölme değil, bölünebilirlik aramasıdır
Modül sayısı, örneklenen genişliğin varsayımsal bir modül boyutuna bölünmesiyle türetilemez ve bunu yanlış yapmak, yüksek çözünürlüklü render'larda sinsi bir decode başarısızlığı kaynağıdır. v sürümünde bir QR sembolü enlemesine 4v + 17 modüldür; sürüm 1 21 modül, sürüm 40 ise 177 modüldür. 126 piksel genişliğinde bir maske, modül başına altı pikseldeki sürüm 1 ile de, daha küçük modül boyutlarındaki birkaç yüksek sürümle de tutarlıdır. Doğrusal bölme birini seçer ve genellikle yanılır
İşleyen yöntem, aday sürümler üzerinde bir bölünebilirlik aramasıdır. Sürüm 40'tan sürüm 1'e yürüyün; modül sayısı örneklenen genişliği kalansız bölen ve modül başına en az üç piksel bırakan adayları tutun ve hayatta kalan en küçük sürümü alın. Üç piksellik taban, aramanın kaba bir sembolün absürt derecede yoğun bir okumasını kabul etmesini önleyen şeydir; en küçük sürüm kuralı ise kalan belirsizliği, bir tarayıcının gerçekten üreteceği okuma lehine çözer
var
Pdf: THotPDF;
Options: THPDFBarcodeDecodeOptions;
Codes: THPDFDecodedBarcodes;
Info: THPDFBarcodeDecodeInfo;
I: Integer;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.LoadFromFile('delivery-notes.pdf');
Options := THPDFBarcodeDecodeOptions.Default;
Options.DPI := 300;
Options.RotationPolicy := bdrpFallback;
Options.MinimumConfidence := 0.5;
Options.MaxResults := 16;
if Pdf.DecodeLoadedPageBarcodes(0, Options, Codes, Info) then
for I := 0 to High(Codes) do
if Codes[I].Symbology = bsyQRCode then
Writeln(Codes[I].Text, ' at ',
Format('%.0f', [Codes[I].OrientationDegrees]), ' degrees');
finally
Pdf.Free;
end;
end;
THPDFBarcodeDecodeOptions.Default, sıfırlanmış bir kayıt değil dolu bir kayıt döndürür; DPI sıfır ya da sonuç sınırı sıfır, hiçbir şey dönmemenin makul görünen bir yolu olduğundan bu önemlidir. RotationPolicy yalnızca dış denemeyi yönetir: bdrpNone bir kez render eder, bdrpFallback ilk geçiş başarısız olduktan sonra öteki yönelimleri yeniden dener, bdrpAll her yönelimi koşulsuz render eder. QR normalizasyonu decoder'ın içinde gerçekleştiği için QR sayfaları, üç politikanın herhangi birinde ilk denemede çözülür. Politika, gerçekten ihtiyaç duyan doğrusal symbology'ler için oradadır
Bir bitmap dönüşümünün piksel uydurmadığını nasıl kanıtlarsınız?
Her iki tarafın mürekkebini sayın ve toplamların eşleşmesini isteyin. Döndürme, piksellerin bir permütasyonundan ibarettir; bu yüzden çıktıdaki sıfırdan farklı hücre sayısı girdiyle aynı olmalıdır. Dış deneme yolundaki bir maske döndürmesi giderken 4800 dolu hücre, dönerken 7439 bildirdiğinde o tek karşılaştırma, geometrisinin tek satırını okumadan dönüşümü mahkûm etmeye yetti
Nedeni sıradandı ve kural olarak aklıda tutmaya değer. SetLength ile boyutlanan dinamik bir dizi, runtime'ın temizlemediği bir yoldan giden işlev sonucu olduğunda sıfırlanmış gelmek zorunda değildir; döndürmenin hiç yazmadığı hücreler daha önce orada olan baytları taşır. O bayat baytların bazıları sıfırdan farklıdır ve sıfırdan farklılık mürekkep demektir. Çözüm tek satırdır: permütasyon döngüsü başlamadan FillChar(Result[0], N, 0); ima ettiği disiplin ise daha geniştir: maske ya da bitmap tamponu döndüren her işlev, tahsis semantiğine güvenmek yerine çıktısını açıkça temizlemelidir
Kusurun üç sürüm hayatta kalmasını sağlayan şey, kusurun kendisinden daha ilginçtir. QR yönelim işleyişini decoder'a taşıdığında QR, dış maske döndürmesini tamamen kullanmayı bıraktı ve o kod yolunun tek tüketicisi Code 39 kaldı. Paylaşılan altyapı bu tür böcekleri hep saklar: bir özellikten gelen kapsam, yola test edilmiş görünümü verirken ona gerçekten bağımlı özelliğin kendi kapsamı yoktur. Yeni bir özelliğin kullanmayı bıraktığı her yol, onu hâlâ kullanan bir teste ihtiyaç duyar
Sonuçları sayfa koordinatlarında geri okuma
Decoder'ın ürettiği her geometrik değer, deneme bitmap'inin koordinat çerçevesinde ifade edilir ve çağıranın bunu PDF kullanıcı uzayında alması gerekir. Dönüşüm iki aşamada akar: önce denemenin uyguladığı çeyrek tur geri alınır, sonra kullanıcı uzayını bitmap'e eşleyen render dönüşümü geri alınır. THPDFDecodedBarcode içinde gelen şey, kullanıcı uzayında eksen hizalı bir sınırlayıcı kutudur; Left, Bottom, Right ve Top, Y'nin yukarı doğru büyüdüğü PDF konvansiyonunu izler ve saat yönünün tersine bir OrientationDegrees eşlik eder
İkinci dönüşümün yönünü yanlış kurarsanız belirti çirkindir: metin kusursuz çözülür ama inceleme katmanı için çizdiğiniz kutu, doğru konumun aynadaki görüntüsüne düşer. Decoder üzerine inceleme arayüzü kuran herkes, bilinen bir sabit veriye karşı doğrulama koymalı; bir sembolü kasıtlı olarak bir sayfa köşesinin yakınına koyun ki çevrilmiş bir Y ekseni bir bakışta görülsün. Aynı akıl, render sınırını geçen her koordinata uygulanır; bu yüzden decoder üzerine inşa etmeden önce Delphi'de bir PDF sayfasını bit eşleme render etme makalesini anlamak değer
Yerleşik decoder'ın yapacakları ve yapmayacakları
Yerleşik decoder, sınırları belli ve bağımsızlıksız bir uygulamadır; sessizce kalitesizleşmek yerine sınırları konusunda dürüsttür. Code 39 ile QR tanır, herhangi bir veri yayınlamadan önce BCH ile korunan format bitlerini ve maske desenini doğrular ve hasarlı sembollerde hata kurtarmaya kalkışmaz. Girdiniz, dengesiz ışık altında kıvrımlı bir etiketin fotoğrafıysa o başka bir sorun sınıfıdır ve özel bir motor ister
// Kendi motorunuzu takın: IHPDFBarcodeDecoder'ı uygulayıp decoder
// farkında olan overload'a geçin. Sayfa render'ı, bütçeler, koordinat
// eşlemesi ve tekilleştirme HotPDF'te kalmaya devam eder
if not Pdf.DecodeLoadedPageBarcodes(PageIndex, MyDecoder, Options,
Codes, Info) then
case Info.Status of
bdsBudgetExceeded:
Log('raise MaxPixels or lower DPI: ' + string(Info.Diagnostic));
bdsRenderError:
Log('page did not render: ' + string(Info.Diagnostic));
bdsDecoderError:
Log(string(Info.DecoderName) + ' failed: ' + string(Info.Diagnostic));
end;
THPDFBarcodeDecodeInfo, üretim işlem hattının karne aldığı yerdir. RotationAttemptCount ile DecoderCallCount, dış denemenin hiç çalışıp çalışmadığını söyler; ReceivedResultCount ile AcceptedResultCount karşılaştırması, hiçbir şey bulmayan bir decoder'ı bulduğu her şeyi reddeden bir güven eşiğinden ayırır; RenderedPixels ile PeakWorkingBytes, bir toplu iş sınırları zorlamaya başladığında grafiğini çizeceğiniz değerlerdir. Boş bir sonuç kümesi artı bdsSucceeded, sayfada gerçekten okunabilir bir sembol olmadığı anlamına gelir; bu, bdsBudgetExceeded'tan farklı bir operasyonel gerçektir
Bütçe alanları varsayılan değil, bilinçli bir karar hak eder. MaxPixels ile MaxWorkingBytes vardır; çünkü DPI kuadratik çarpar: bir A4 sayfasında 300'den 600 DPI'a geçmek hem render maliyetini hem tepe tahsisi dörde katlar ve devasa bir sayfa kutusu beyan eden güvenilir olmayan bir girdi, tarama işini bir out-of-memory olayına çevirebilir. Sınırları, en zorlu meşru belgenizin ihtiyacına göre ayarlayın; sonra bdsBudgetExceeded, uç değerleri daha yavaş, izole bir yola yönlendirsin
Belgeleriniz, indekslemeyi planladığınız basılı metinle makine okunur etiketleri karıştırıyorsa barkod decoder'ı, HotPDF içinde şablon eşleştirmeli OCR makalesinde ele alınan tanıma motoruyla doğal biçimde eşleşir; aynı hikayenin üretim tarafı ise HotPDF ile PDF'e barkod çizme makalesindedir. Her ikisi de aynı render ve bütçe altyapısı üzerinde çalışır; birine akıllı sınırlar ayarlamış bir işlem hattı, ötekini neredeyse bedavaya alır
Döndürme toleransı, işlediğinde görünmez, işlemeyesinde sinir bozucu olan özelliklerdendir ve mühendislik dersi QR'nin ötesine geneller: normalleştirmeyi, verinin hâlâ nasıl yakalandığına dair her kazarı taşıdığı piksel katmanında değil, ulaşabildiğiniz en anlamsal temsile yakın yerde yapın. HotPDF bunu, HotPDF Delphi PDF bileşeni kapsamında, aynı girdi işlem hatlarının genellikle ihtiyaç duyduğu render, OCR ve sayfa çözümleme parçalarıyla birlikte sunar