バーコードは、ドキュメントを飾る絵ではありません。それは測定値であり、スキャナーはそれを読み取るための機器です。その再構築により、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、および倉庫でまだ生きている古い産業コードをカバーするのに十分です
このファミリーは設計上、線形です。QR、Data Matrix、PDF417といった2次元シンボルは、独自の誤り訂正計算を伴うグリッドでバイトをエンコードするため、このAPIの対象外です。その周りに構築を始める前に、要件がどちらのファミリーを指しているのかを確定してください。1次元コードについて現実的な問いは、より狭いものになります。エンコード方式には互換性がないため、手元のデータを受け入れられるシンボルはどれか、という点です
データの制約は現実のものであり、生成時に効いてきます。Code 2 of 5の各バリアントとMSIが受け付けるのは数字だけです。Code 39は大文字、数字、少数の記号を扱えます。小文字やASCII全域が必要なら、Code 39 ExtendedかCode 128のサブセットの出番です。Code 128Cは密度を稼ぐために1シンボルに2桁を詰め込むので、偶数長の数字列以外を受け付けません。EAN-13は12桁を受け取り、13桁目をチェックディジットとして計算します。EAN-8は7桁を受け取り、8桁目を計算します。UPC-Aは12桁です。DrawBarcodeを呼び出す前に、データをこれらのルールで検証してください。シンボルが表現できないデータから作られたバーは、画面上では正常に見え、レジでスキャンされた瞬間に初めて失敗します
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(point単位のmodule幅)、angle
// data, UseCheckSum, bar color, background color.
Pdf.CurrentPage.DrawBarcode(
bcCodeEAN13, // symbology
72, 72, // 左上隅のX、Y(ポイント)
60, // bar height
1, // MUnit: 1pt narrowest bar
0, // no rotation
'123456789012', // 12 digits; the 13th is the check
True, // 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は下向きに増加します。この2つの値が指定するのはバーの左上隅です。これは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 Delphi Componentの一部です