Last active
March 27, 2023 19:46
-
-
Save denkspuren/c68b69624d57547a5bfa to your computer and use it in GitHub Desktop.
Barcode generator in Processing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Barcode Generator (EAN-13) by @denkspuren, 2014-08-27, 14:22 | |
Minor update for Processing 3, 2015-11-19, 00:44 | |
New BSD License: http://opensource.org/licenses/BSD-3-Clause | |
http://en.wikipedia.org/wiki/International_Article_Number_(EAN) | |
http://de.wikipedia.org/wiki/European_Article_Number | |
Use: Press number keys to input a sequence of digits or use | |
right/left arrow for navigation. | |
Note: Rightmost digit is checksum digit. | |
*/ | |
final int START_X = 30; | |
final int START_Y = 20; | |
final int LINE_LENGTH = 100; | |
final int LINE_EXTRA = 20; | |
final int LINE_WEIGHT = 3; | |
final int TEXT_PT = 20; | |
int pos = 0; // ranges from 0..11 | |
Digit[] digits = new Digit[13]; | |
final int ASCII_NULL = 48; | |
final int ASCII_NINE = 57; | |
final color WHITE = color(255,255,255); | |
final color RED = color(255,0,0); | |
final color BLUE = color(0,0,255); | |
String[] encoding = // encoding for digits 0..9 on right side | |
{ | |
"1110010", "1100110", "1101100", "1000010", "1011100", | |
"1001110", "1010000", "1000100", "1001000", "1110100" | |
}; | |
String[] pattern = // 1st digit is encoded via pattern for digits on left side | |
{ | |
"OOOOOO", "OOEOEE", "OOEEOE", "OOEEEO", "OEOOEE", // 'O' means "odd" | |
"OEEOOE", "OEEEOO", "OEOEOE", "OEOEEO", "OEEOEO" // 'E' means "even" | |
}; | |
String reverseEncoding(String s) { // required for digits on left side (even) | |
if ((s == null) || s.isEmpty()) return s; | |
return reverseEncoding(s.substring(1)) + s.charAt(0); | |
} | |
String inverseEncoding(String s) { // required for digits on left side (odd) | |
if ((s == null) || s.isEmpty()) return s; | |
return ((s.charAt(0) == '1') ? '0' : '1') + inverseEncoding(s.substring(1)); | |
} | |
int calc_checksumDigit(int[] digits) { | |
int sum = 0; | |
int multiplier = 3; | |
for (int i=digits.length-1; i>=0; i--) { | |
sum += digits[i] * multiplier; | |
multiplier = (multiplier == 3) ? 1 : 3; | |
} | |
return (10 - sum % 10) % 10; | |
} | |
int draw_encoding(int x, int y, int length, String encoding) { | |
for (int i=0; i<encoding.length (); i++) { | |
if (encoding.charAt(i) == '1') line(x, y, x, y+length); | |
x += LINE_WEIGHT; | |
} | |
return x; | |
} | |
void draw_barcode(int x, int y, int[] digits) { | |
String code; | |
String schema = pattern[digits[0]]; | |
x = draw_encoding(x, y, LINE_LENGTH+LINE_EXTRA, "101"); | |
for (int i=1; i<=6; i++) { | |
code = (schema.charAt(i-1) == 'O') ? | |
inverseEncoding(encoding[digits[i]]) : | |
reverseEncoding(encoding[digits[i]]); | |
x = draw_encoding(x, y, LINE_LENGTH, code); | |
} | |
x = draw_encoding(x, y, LINE_LENGTH+LINE_EXTRA, "01010"); | |
for (int i=7; i<=12; i++) { | |
code = encoding[digits[i]]; | |
x = draw_encoding(x, y, LINE_LENGTH, code); | |
} | |
x = draw_encoding(x, y, LINE_LENGTH+LINE_EXTRA, "101"); | |
} | |
class Digit { | |
int x, y, value; | |
Digit(int x, int y, int value) { | |
this.x = x; | |
this.y = y; | |
this.value = value; | |
draw(false); | |
} | |
void draw(boolean active) { | |
fill(active ? RED : BLUE); | |
text(value, x, y); | |
} | |
} | |
void draw_digits(Digit[] digits) { | |
for (Digit d: digits) d.draw(false); | |
} | |
Digit[] initDigits() { | |
int x = START_X - TEXT_PT/2; | |
int y = START_Y + LINE_LENGTH + LINE_EXTRA; | |
Digit[] digits = new Digit[13]; | |
digits[0] = new Digit(x, y, 0); | |
x += 3 * LINE_WEIGHT + 2 * TEXT_PT/2; | |
for (int i=1; i<=6; i++) { | |
digits[i] = new Digit(x, y, 0); | |
x += 7 * LINE_WEIGHT; | |
} | |
x += 4 * LINE_WEIGHT; // + TEXT_PT/2; | |
for (int i=7; i<=12; i++) { | |
digits[i] = new Digit(x, y, 0); | |
x += 7 * LINE_WEIGHT; | |
} | |
return digits; | |
} | |
void set_ChecksumDigit(Digit[] digits) { | |
int[] values = new int[12]; | |
for (int i=0; i<=11; i++) values[i] = digits[i].value; | |
digits[12].value = calc_checksumDigit(values); | |
} | |
int[] get_DigitValues(Digit[] digits) { | |
int[] values = new int[13]; | |
for (int i=0; i<=12; i++) values[i] = digits[i].value; | |
return values; | |
} | |
void setup() { | |
// Formerly defined at top of the file; incompatible with Processing 3 | |
// final int SIZE_X = 2*START_X + (3 + 6*7 + 5 + 6*7 + 3) * LINE_WEIGHT; | |
// final int SIZE_Y = 2*START_Y + LINE_LENGTH + LINE_EXTRA; | |
// size(SIZE_X, SIZE_Y); // if used, must be first line of code in setup | |
size(345, 160); | |
textSize(TEXT_PT); | |
textAlign(CENTER); | |
strokeWeight(LINE_WEIGHT); | |
strokeCap(SQUARE); | |
draw_barcode(START_X, START_Y, new int[] {0,0,0,0,0,0,0,0,0,0,0,0,0}); | |
digits = initDigits(); | |
digits[pos].draw(true); | |
} | |
void keyPressed() { | |
if (key >= ASCII_NULL && key <= ASCII_NINE) { | |
background(WHITE); | |
digits[pos].value = key - ASCII_NULL; | |
set_ChecksumDigit(digits); | |
draw_barcode(START_X, START_Y, get_DigitValues(digits)); | |
draw_digits(digits); | |
pos = (pos + 1) % 12; | |
digits[pos].draw(true); | |
} | |
else if (key == CODED) { | |
if (keyCode == RIGHT) { | |
digits[pos].draw(false); | |
pos = (pos + 1) % 12; | |
digits[pos].draw(true); | |
} | |
else if (keyCode == LEFT) { | |
digits[pos].draw(false); | |
pos = (pos + 11) % 12; | |
digits[pos].draw(true); | |
} | |
} | |
} | |
void draw() { | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment