印刷しているのは、商品だけじゃありません

はじめに

こんにちは、イメージ・マジックの矢野です。入社から2か月が経過し、順調に机の上がゴチャゴチャしてきました。カメラが2台、バーコードプリンターが2台、小さなスピーカーが1台、さらにカードリーダーが1台、デスクの上に転がっています。

印刷しているもの

当社が印刷しているのは、Tシャツやパーカー、マグカップ、カーペットなどの製品そのものももちろんですが、それだけではお客様のお手元に製品を届けることはできません。生産工程でそれらを管理するためのラベルシールや、納品書、配送業者さんにお願いする送り状なども自社のシステムで印刷しています。当然といえば当然なのですが。

ラベルシールの印刷には、専用のプリンターを使用しています。私は転職してきて初めて触りました。ずんぐりむっくりでかわいい形ですが、言うことを聞かせるのはなかなか難しいです。プリンター専用のツールやライブラリを使ってバーコードや文字列や画像を出力するように指示することもできますが、プリンターの制御用コマンドを直接(「直接」とは言っても、通り抜けなければならないレイヤーは多数あります)送信することもできます。

ところで、「プリンターで何かを印刷する」というのはどういうことなのでしょう? それは文字列や画像、バーコードを印刷しなさいというコマンドの積み重ねです。ラベルシールにバーコードを印刷する場合には、最終的にたくさんのしましまが紙面に出力されるようなコマンドをアプリケーションで生成して、それをプリンターに送信する必要があるわけです。

たくさんのしましまを、どうやってプリンターに送信しましょうか?

  1. しましまを1本1本引くコマンドを生成して、順番に実行する
  2. バーコード全体の画像をPNGなどのラスター画像で生成して、画像を印刷するコマンドを実行する
  3. 「このデータ(ID)に対応するバーコードを、このバーコード規格を使ってイイ感じに生成してよ」とプリンターに任せるコマンドを実行する
  4. その他

1も2も3も正解ですが、1は特に厳しい。バーコードの仕様に従って、1本1本のしましまの太さと間隔をどうにかこうにかしなければなりません。2は割とよくあると思います。バーコード画像を生成するライブラリを使用すれば、割とサクっとできるでしょう。でも、せっかく専用のプリンターを使っているのですから、彼(彼女?)に任せてしまってみましょう。

イイ感じにやってもらう

Windowsで、Win32 APIを使って実装してみます。プリンターによろしくやってもらう代わりに、プリンター固有のお作法に従わなくてはなりません。ここでは、Zebra Technologies社のプリンタ向け言語、ZPL(Zebra Programming Language)のコマンドを実行しています。

int PrintRawCommand()
{
	HANDLE hPrinter;

	if (!OpenPrinter((LPSTR)"Printer Name", &hPrinter, NULL))
	{
		// エラー処理

		return FALSE;
	}

	DOC_INFO_1 docInfo;
	docInfo.pDocName = (LPSTR)"Barcode sample";
	docInfo.pOutputFile = NULL;
	docInfo.pDatatype = (LPSTR)"RAW";

	LPSTR command = (LPSTR)"^XA^FO40,40^BY3^BEN,40,Y,N^FD123456789012^FS^XZ";

	if (StartDocPrinter(hPrinter, 1, (LPBYTE)&docInfo))
	{
		if (StartPagePrinter(hPrinter))
		{
			DWORD writtenBytes;
			if (WritePrinter(hPrinter, command, strlen(command), &writtenBytes))
			{
				// 印刷成功時の処理
			}
			else
			{
				// エラー処理

				return FALSE;
			}
		}
		else
		{
			// エラー処理

			return FALSE;
		}
	}
	else
	{
		// エラー処理

		return FALSE;
	}

	EndPagePrinter(hPrinter);
	EndDocPrinter(hPrinter);
	ClosePrinter(hPrinter);

	return TRUE;
}

15行目で、プリンタへ送信するデータの形式をRAW(生=Zebraのプリンターが解するコマンドを直接送信する)に指定します。17行目の文字列が実際にプリンタへ送信されるZPLのコマンドです。レイアウト、フィールド、バーコードの表現形式(EAN-13)、バーコード化したいデータ(123456789012)などを、 ^ で始まるコマンドで指定します。

これの出力結果がこうなります。

EAN-13の詳細な仕様を隅々まで探らなくても、難しい画像操作系のAPIを駆使しなくても、美しいバーコードを得ることができました。