バーコードは、ドキュメントを飾る絵ではありません。それは測定値であり、スキャナーはそれを読み取るための機器です。その再構築により、PDFにどのように描画すべきかについてのほぼすべてが決定されます。バーはその黒さによって情報を伝達するわけではありません。情報はバーの幅とスペースの幅の比率に存在し、リーダーはレーザーやセンサーが通過する際の遷移をタイミング計測することでそれを回復します。そのジオメトリを絞ったり、ぼかしたり、マージンを詰め込んだりすると、バーコードのように見えるが、汚れのようにスキャンされるものが生成されます。HotPDFには、ページに配置するための2つの方法があり、その違いはまさにそのジオメトリを制御するか、放棄するかの違いです

HotPDFがエンコードできるもの
HotPDFは線形(1次元)シンボルを描画し、そのセットはほとんどのプロジェクトが必要とするよりも広範です。THPDFBarcodeType列挙型は、インターリーブ、インダストリアル、およびマトリックス形式のCode 2 of 5ファミリをカバーしています。Code 39とその拡張バリアント。3つのCode 128サブセットA、B、およびC。Code 93プレーンおよび拡張。MSI。PostNet。Codabar。小売用のUPCおよびEANグループ、すなわちEAN-8、EAN-13、UPC-A、圧縮されたUPC-E0およびUPC-E1、およびUPCの補足的な2桁および5桁のアドオン。およびGS1-128(EAN-128)サブセット。これは、サプライチェーンのラベル、小売のPOS、および倉庫でまだ生きている古い産業コードをカバーするのに十分です
描画しないのは2次元ファミリーです。ここにはQR、Data Matrix、またはPDF417はありません。これらは独自のエラー訂正計算を備えたグリッドでバイトをエンコードするものであり、要件でそれらのいずれかが指定されている場合、これは間違ったツールであり、それを中心に構築する前にそれを知っておくべきです。1次元コードの場合、実際的な質問はより狭くなります。エンコーディングは交換可能ではないため、実際に持っているデータを受け入れるシンボルはどれかということです
データの制約は現実のものであり、生成時に噛み付きます。Code 2 of 5バリアントとMSIは数字のみを受け付けます。Code 39は、大文字、数字、および一握りの句読点を伝達します。小文字または完全なASCII範囲が必要な場合は、Code 39 ExtendedまたはCode 128サブセットです。Code 128Cは密度のために各記号に2桁をパックするため、偶数長の数字列のみを必要とします。EAN-13は12桁を予期し、13桁目をチェックとして計算します。EAN-8は7桁を予期し、8桁目を計算します。UPC-Aは12桁を取ります。表現できないデータを持つシンボルを手渡すと、役立つ例外が得られるのではなく、ゴミをエンコードするバーコードが得られます。これは、誰かがレジでスキャンするまでは問題なく見えるため、さらに悪いです
2つの描画パス、2つのレベルの制御
本番環境で到達するメソッドは、ページオブジェクトのDrawBarcodeです。シンボル、位置、高さ、そして他のどれよりも重要な1つのパラメーターを受け取ります:MUnit、モジュール幅。モジュールは最も狭いバーの幅であり、コード内の他のすべてのメジャーはその倍数である原子であり、ここではポイントで表されます。印刷された結果がスキャンされるかどうかについてのすべては、その単一の整数に遡ります
var
Pdf: THotPDF;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'label.pdf';
Pdf.BeginDoc;
// BCType, X, Y, Height, MUnit (module width in points), angle,
// data, UseCheckSum, bar color, background color.
Pdf.CurrentPage.DrawBarcode(
bcCodeEAN13, // symbology
72, 680, // X, Y in points from the bottom-left
60, // bar height
1, // MUnit: 1pt narrowest bar
0, // no rotation
'123456789012', // 12 digits; the 13th is the check
True, // append the modulo-10 check digit
clBlack, clWhite); // bars black, background white
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
2つの引数を詳しく見てみる価値があります。UseCheckSumはシンボルが予期するモジュロ10のチェックディジットを追加し、小売コードの場合はほぼ常にTrueにする必要があります。データがすでに事前計算されたチェックを伝達している場合にのみオフにしてください。そうしないと、2倍の数字が得られます。バーと背景の色は最後の2つのパラメーターであり、そこで創造的になりたいという誘惑は、以下で説明する罠です。また、座標の原点にも注意してください。HotPDFの他のすべての描画呼び出しと同様に、XとYはページの左下隅からポイント単位で測定され、Yは上に向かって成長します。これはHello Worldの例で説明されているのと同じ規則です
2つ目のパスはDirectDrawBarcodeです。これはデータとバウンディングボックス(X, Y, Width, Height)を受け取り、その幅を埋めるようにバーのパターンをスケーリングします。フットプリントに名前を付けると、メソッドがそれにバーをフィットさせるため、グリッド上にコードをレイアウトするのに便利です。その便利さは同時にその危険でもあります。幅を指定すると、モジュールサイズを設定しなくなります。メソッドは、許可したスペースをデータが必要とする数のバーで分割し、最も狭いバーはその分割から外れたものになります。狭すぎるボックスの中に密集したCode 128の文字列を要求すると、モジュールはスキャナーが解決できる値よりも小さく、静かに縮小します。確実にスキャンする必要があるものについては、DrawBarcodeを優先し、MUnitを意図的に設定してください。DirectDrawBarcodeはプレビュー用、および結果として得られるバーが読みやすいままであることを測定した配置用に予約してください
モジュール幅は解像度の決定です
ラベルが機能するかどうかを決定する計算は次のとおりです。レーザースキャナーとカメラの両方には、区別できる最小の機能があり、印刷後、狭いバーはその機能の上に快適に着地する必要があります。汎用の線形コードとして広く引用されているフロアは、13ミルの狭いバー、約0.33 mmであり、多くの小売および産業ガイドはそれを目標ではなく最小値として扱っています。それをPDFの単位に変換します:1ポイントは1/72インチ、約0.353 mmであるため、モジュール幅の1ポイントはまさにそのフロアに位置します。そのため、MUnit := 1は実際のスキャナー向けのアドレスコードとして信頼すべき最小値であり、それを2に倍増させると、余裕のあるラベルではほとんどコストがかからないマージンが買える理由です
ここで、それを出力解像度に接続します。モジュールはプリンターでも生き残らなければならないからです。300 DPIのレーザープリンターでは、1つのデバイスドットは1/300インチなので、1ポイントのモジュールは約4ドットの幅になります。4ドットはきれいなエッジをレンダリングするのにかろうじて十分です。トナーの広がりとわずかな見当合わせの誤差がそれに食い込み、PDFで1ポイントと測定されたバーが、仕様が許容するよりも太くまたは細く印刷されます。モジュールを2ポイントに上げると、8ドットを扱うことができ、そのノイズを吸収します。内面化する価値のある規則:ポイント単位で設定したモジュール幅は、希望する解像度ではなく、実際の印刷解像度で全体的で快適なデバイスドット数にマップする必要があります。画面から完璧にスキャンされ、倉庫のプリンターから失敗するコードは、ほぼ常にこのチェックに失敗しています
クワイエットゾーンはシンボルの一部です
正しくエンコードされたバーコードがスキャンされない最も一般的な唯一の理由は、クワイエットゾーン、つまりバーの両側にある空白のマージンです。スキャナーはその空のスペースを使用して、コードの開始位置と終了位置を特定します。それがないと、リーダーは最初のバーとページ上でその隣にあるものを区別できません。標準は具体的です。ほとんどの線形シンボルは、両側に少なくともモジュール幅の10倍のクワイエットゾーンを必要とし、UPCおよびEANの小売コードは左に9モジュール、右に7モジュールを必要とします。1ポイントのモジュールでは、それは約10ポイント、約7分の1インチの保証された空白スペースがバーを挟むことになります
HotPDFはバーだけを描画し、他は何も描画しません。それはあなたのためにクワイエットゾーンを予約しません。つまり、その責任はあなたにあり、忘れるのは簡単です。失敗のモードは微妙です。バーコードをテーブルセルの境界線と同一平面上に配置したり、ページレイアウトでロゴをその横に押し込んだりすると、空白のページですべてのテストに合格したコードが、実際のドキュメント内で出荷された瞬間にスキャンされなくなります。マージンを明示的に予算化します。DrawBarcodeを呼び出す前に、両側に少なくとも10モジュール幅のクリアスペースを残し、その帯に侵入するグラフィック、罫線、またはテキストは、外観の選択ではなく、欠陥として扱います
色、コントラスト、および人間が読める行
バーと背景の色は、ブランドのパレットに合わせるために存在し、機能しているコードを壊す最も速い方法です。スキャナーは、古典的には赤い光でコントラストを読み取り、明るいフィールド上の暗いバーを期待します。白地に黒は、テストなしで到達すべき唯一の組み合わせです。白地にダークブルーまたはダークグリーンは合格できます。輝度コントラストが低いもの、特に赤信号のスキャナーが背景として見る赤いバーは機能しません。デザイナーが色付きのバーコードを求めてきた場合、正直な答えは、バーは黒いままで、色はラベルの他の場所にあるということです
DrawBarcodeパスは、バーの下に人間が読めるテキスト、スキャンが失敗したときに店員が入力する数字をレンダリングすることもできます。そのテキストは装飾ではなくフォールバックであるため、独自のキャプションを配置するときは、クワイエットゾーンに入らないようにしてください。サイドマージンに詰め込まれたシンボルのラベルは、スキャナーが依存しているのと同じ空白スペースを無効にします。ここでの例のフィールドは、周囲のラベル用のTextOutを含め、レポート出力ガイドでカバーされているのと同じ描画呼び出しです。これは、バーコードがより大きな構成されたページの1つの要素である場合に行くべき場所です
短い検証の習慣
ベクターバーは名前を付ける価値のある利点です。DrawBarcodeはコードをラスタライズされた画像としてではなくPDF描画オペレーターとして書き込むため、バーはどのズームでも鮮明なままであり、ファイル自体に解像度はありません。重要な唯一の解像度はプリンターの解像度です。だからといってテストが免除されるわけではなく、テストが紙の上で行われなければならないということを意味するだけです。サンプルを生成し、コードが実際に適合する最低解像度のデバイスで印刷し、机の上のハイエンドのイメージャーではなく、ユーザーが保持しているのと同じクラスのリーダーでスキャンします。プリントアウトの定規でクワイエットゾーンをチェックし、モジュール幅がポイントからドットへの移動を生き延びたことを確認し、デコードされた値がエンコードしたもの、チェックディジットおよびすべてと一致することを確認します。実際のスキャナーでの5分間は、上記のすべての障害を捉え、パレットのラベルが間違った在庫が行う前にそれらを捉えます
ここに示すDrawBarcodeおよびDirectDrawBarcodeメソッドは、DelphiおよびC++Builder用のHotPDF Componentの一部です