zint/docs/appxd.html
2009-03-02 08:52:57 +00:00

170 lines
6.0 KiB
HTML
Executable File

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
<TITLE>Making colourful barcodes</TITLE>
</HEAD>
<BODY LANG="en-GB" DIR="LTR">
<TABLE WIDTH=100% BORDER=0 CELLPADDING=0 CELLSPACING=0 STYLE="page-break-before: always">
<TR>
<TH COLSPAN=3>
<P ALIGN=CENTER>Zint Barcode Generator</P>
</TH>
</TR>
<TR VALIGN=BOTTOM>
<TD WIDTH=10%>
<P ALIGN=LEFT><A HREF="appxc.html">Prev</A></P>
</TD>
<TD WIDTH=80%></TD>
<TD WIDTH=10%>
</TD>
</TR>
</TABLE>
<H1>Appendix D: Making colourful barcodes</H1>
<P>An obvious next step in the development of barcodes is to use
colour instead of boring old black and white to encode data. This
technique is not currently used by any barcode encoding standards in
the wild but an indication of how it might be achieved can be gained
with a little data processing and the Zint library.</P>
<P>This example takes an input string and splits it into
three roughly equal length strings each of which is encoded and then
combined to make a colour version of the symbol. This can then be
decoded by applying red, green and blue filters to the resulting
image and then decoding them using the same algorithm used to decode
normal black and white symbols as shown below.</P>
<P ALIGN=CENTER><IMG SRC="3dprinciple.png" NAME="3dprinciple" ALIGN=CENTER WIDTH=475 HEIGHT=406 BORDER=0></P>
<P>One advantage of this system is that finder patterns in the symbol
show up clearly as black-on-white and so can be found using the
methods already established for standard 2D barcodes. This can be
clearly seen in the examples below.</P>
<P ALIGN=CENTER><IMG SRC="3dsample.png" NAME="3dexample" ALIGN=CENTER WIDTH=416 HEIGHT=148 BORDER=0></P>
<P>Another advantage of this system is that it fits three times as
much data into a symbol of a given size. Disadvantages are likely to
become apparent when trying to decode these symbols in real-world
applications: decoding will require larger processor overheads and
more sophisticated algorithms. Telling white from yellow may be a
particular problem.</P>
<P>The code below performs the encoding as done on the images above
and outputs an array of elements as characters representing colours.
Putting this together as an image requires additional code.</P>
<PRE>#include &lt;stdio.h&gt;
#include &lt;zint.h&gt;
#include &lt;string.h&gt;
int main(int argc, char **argv)
{
struct zint_symbol *red_symbol;
struct zint_symbol *green_symbol;
struct zint_symbol *blue_symbol;
struct zint_symbol *colour_symbol;
int error = 0;
int i, j;
int input_len = strlen(argv[1]);
int snippet = input_len / 3;
char full_string[input_len + 5];
char red_string[(input_len / 3) + 2];
char green_string[(input_len / 3) + 2];
char blue_string[(input_len / 3) + 2];
int symbol_type = BARCODE_QRCODE;
if(input_len % 3 != 0) { snippet++; }
strcpy(full_string, argv[1]);
for(i = 0; i &lt; snippet; i++) {
red_string[i] = full_string[i];
green_string[i] = full_string[i + snippet];
blue_string[i] = full_string[i + snippet + snippet];
}
red_string[i] = '\0';
green_string[i] = '\0';
blue_string[i] = '\0';
red_symbol = ZBarcode_Create();
green_symbol = ZBarcode_Create();
blue_symbol = ZBarcode_Create();
colour_symbol = ZBarcode_Create();
red_symbol-&gt;symbology = symbol_type;
green_symbol-&gt;symbology = symbol_type;
blue_symbol-&gt;symbology = symbol_type;
colour_symbol-&gt;symbology = symbol_type;
error = ZBarcode_Encode(red_symbol, (unsigned char *)red_string);
error += ZBarcode_Encode(green_symbol, (unsigned char *)green_string);
error += ZBarcode_Encode(blue_symbol, (unsigned char *)blue_string);
if(error != 0) {
printf(&quot;Some error occurred!\n&quot;);
ZBarcode_Delete(red_symbol);
ZBarcode_Delete(green_symbol);
ZBarcode_Delete(blue_symbol);
ZBarcode_Delete(colour_symbol);
return 1;
}
colour_symbol-&gt;width = red_symbol-&gt;width;
if(green_symbol-&gt;width &gt; colour_symbol-&gt;width) { colour_symbol-&gt;width = green_symbol-&gt;width; }
if(blue_symbol-&gt;width &gt; colour_symbol-&gt;width) { colour_symbol-&gt;width = blue_symbol-&gt;width; }
colour_symbol-&gt;rows = red_symbol-&gt;rows;
if(green_symbol-&gt;rows &gt; colour_symbol-&gt;rows) { colour_symbol-&gt;rows = green_symbol-&gt;rows; }
if(blue_symbol-&gt;rows &gt; colour_symbol-&gt;rows) { colour_symbol-&gt;rows = blue_symbol-&gt;rows; }
for(i = 0; i &lt; colour_symbol-&gt;rows; i++) {
colour_symbol-&gt;row_height[i] = 1;
for(j = 0; j &lt; colour_symbol-&gt;width; j++) {
int colourval;
colourval = 0;
if(red_symbol-&gt;encoded_data[i][j] == '1') { colourval += 4; }
if(green_symbol-&gt;encoded_data[i][j] == '1') { colourval += 2; }
if(blue_symbol-&gt;encoded_data[i][j] == '1') { colourval += 1; }
switch(colourval) {
case 0: colour_symbol-&gt;encoded_data[i][j] = '0'; break; /* white */
case 1: colour_symbol-&gt;encoded_data[i][j] = 'Y'; break; /* yellow */
case 2: colour_symbol-&gt;encoded_data[i][j] = 'M'; break; /* magenta */
case 3: colour_symbol-&gt;encoded_data[i][j] = 'R'; break; /* red */
case 4: colour_symbol-&gt;encoded_data[i][j] = 'C'; break; /* cyan */
case 5: colour_symbol-&gt;encoded_data[i][j] = 'G'; break; /* green */
case 6: colour_symbol-&gt;encoded_data[i][j] = 'B'; break; /* blue */
case 7: colour_symbol-&gt;encoded_data[i][j] = '1'; break; /* black */
}
printf(&quot;%c&quot;,colour_symbol-&gt;encoded_data[i][j]);
}
printf(&quot;\n&quot;);
}
ZBarcode_Delete(red_symbol);
ZBarcode_Delete(green_symbol);
ZBarcode_Delete(blue_symbol);
ZBarcode_Delete(colour_symbol);
return 0;
}</PRE><P>
<HR>
<TABLE WIDTH=100% BORDER=0 CELLPADDING=0 CELLSPACING=0>
<TR VALIGN=TOP>
<TD WIDTH=33% HEIGHT=5>
<P ALIGN=LEFT><A HREF="appxc.html">Prev</A></P>
</TD>
<TD WIDTH=34%>
<P ALIGN=CENTER><A HREF="index.html">Home</A></P>
</TD>
<TD WIDTH=33%>
</TD>
</TR>
<TR VALIGN=TOP>
<TD WIDTH=33%>
<P ALIGN=LEFT>Appendix C</P>
</TD>
<TD WIDTH=34%>
<P ALIGN=CENTER>&nbsp;</P>
</TD>
<TD WIDTH=33%>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>