I decided to write a barcode generator in Java “for no apparent reason”, that can currently generator EAN13 barcodes. It’s available here in this post, but if you want the latest code then I suggest you check it out on github.
Github repo:
https://github.com/jra89/barcode
Usage:
java -jar barcode.jar numbers path barwidth barheight
Example:
java -jar barcode.jar 999990000020 /home/user/Desktop/EAN_IMG.png 2 60
Main.java
package barcode; public class Main { public static void main(String[] args) { String code; String path; int barWidth; int barHeight; if(args.length <= 1) { System.out.println("Not enough parameters"); } try { code = args[0]; } catch(NullPointerException e) { code = "9999900000207"; } try { path = args[1]; } catch(NullPointerException e) { path = "/tmp/barcode.png"; } try { barWidth = Integer.parseInt(args[2]); } catch(NullPointerException e) { barWidth = 1; } try { barHeight = Integer.parseInt(args[3]); } catch(NullPointerException e) { barHeight = 100; } Ean13 ean = new Ean13(code, path, barWidth, barHeight); ean.createBarcodePNG(); } }
Ean13.java
package barcode; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class Ean13 { /** * -=Structure=- * * Fist, First Six, Last Six * LGR = 012 * 0 LLLLLL RRRRRR * 1 LLGLGG RRRRRR * 2 LLGGLG RRRRRR * 3 LLGGGL RRRRRR * 4 LGLLGG RRRRRR * 5 LGGLLG RRRRRR * 6 LGGGLL RRRRRR * 7 LGLGLG RRRRRR * 8 LGLGGL RRRRRR * 9 LGGLGL RRRRRR * * -=Encodings=- * * Digit L-code G-code R-code * 0 0001101 0100111 1110010 * 1 0011001 0110011 1100110 * 2 0010011 0011011 1101100 * 3 0111101 0100001 1000010 * 4 0100011 0011101 1011100 * 5 0110001 0111001 1001110 * 6 0101111 0000101 1010000 * 7 0111011 0010001 1000100 * 8 0110111 0001001 1001000 * 9 0001011 0010111 1110100 **/ private String code; private String path; private BufferedImage bi; private Graphics2D ig2; private int barPos; private int barPosBin; private int imgPixelPos; private int barWidth; private int barHeight; private int imgWidth; private int imgHeight; private int[][] barcodeBinary; private int[][] firstSix = { {0,0,0,0,0,0}, //LLLLLL {0,0,1,0,1,1}, //LLGLGG {0,0,1,1,0,1}, //LLGGLG {0,0,1,1,1,0}, //LLGGGL {0,1,0,0,1,1}, //LGLLGG {0,1,1,0,0,1}, //LGGLLG {0,1,1,1,0,0}, //LGGGLL {0,1,0,1,0,1}, //LGLGLG {0,1,0,1,1,0}, //LGLGGL {0,1,1,0,1,0} //LGGLGL }; private int[] lastSix = {2, 2, 2, 2, 2, 2}; private int[][][] encodings = { { {0,0,0,1,1,0,1}, {0,1,0,0,1,1,1}, {1,1,1,0,0,1,0} }, { {0,0,1,1,0,0,1}, {0,1,1,0,0,1,1}, {1,1,0,0,1,1,0} }, { {0,0,1,0,0,1,1}, {0,0,1,1,0,1,1}, {1,1,0,1,1,0,0} }, { {0,1,1,1,1,0,1}, {0,1,0,0,0,0,1}, {1,0,0,0,0,1,0} }, { {0,1,0,0,0,1,1}, {0,0,1,1,1,0,1}, {1,0,1,1,1,0,0} }, { {0,1,1,0,0,0,1}, {0,1,1,1,0,0,1}, {1,0,0,1,1,1,0} }, { {0,1,0,1,1,1,1}, {0,0,0,0,1,0,1}, {1,0,1,0,0,0,0} }, { {0,1,1,1,0,1,1}, {0,0,1,0,0,0,1}, {1,0,0,0,1,0,0} }, { {0,1,1,0,1,1,1}, {0,0,0,1,0,0,1}, {1,0,0,1,0,0,0} }, { {0,0,0,1,0,1,1}, {0,0,1,0,1,1,1}, {1,1,1,0,1,0,0} } }; Ean13(String code, String path,int barWidth, int barHeight) { this.code = code; this.path = path; this.barPos = 12; this.barPosBin = 7; this.imgPixelPos = 0; this.barcodeBinary = new int[barPos][barPosBin]; this.barWidth = barWidth; this.barHeight = barHeight; this.imgWidth = ((12*7) + (2*9) + (2*3) + (1*5)) * this.barWidth; this.imgHeight = this.barHeight; } public void createBarcodePNG() { this.code += Integer.toString(calculateControlDigit(this.code)); generateBinaryMap(); generateBarcodePNG(); } private void generateBinaryMap() { int first = Integer.parseInt(String.valueOf(this.code.charAt(0))); //i = 1, first digit is not welcome to the bar for(int i = 1; i < 13; ++i) { int current = Integer.parseInt(String.valueOf(this.code.charAt(i))); if(i < 7) this.barcodeBinary[i-1] = this.encodings[current][this.firstSix[first][i-1]]; else this.barcodeBinary[i-1] = this.encodings[current][this.lastSix[i-7]]; } } private void generateBarcodePNG() { try { // TYPE_INT_ARGB specifies the image format: 8-bit RGBA packed // into integer pixels bi = new BufferedImage(this.imgWidth, this.imgHeight, BufferedImage.TYPE_INT_ARGB); ig2 = bi.createGraphics(); ig2.setPaint(Color.white); ig2.fillRect ( 0, 0, bi.getWidth(), bi.getHeight() ); //Draw quiet zone drawSpecial(0); //Draw lead drawSpecial(1); //Draw first group drawGroup(1); //Draw separator drawSpecial(2); //Draw second group drawGroup(2); //Draw lead drawSpecial(1); //Draw quiet zone drawSpecial(0); ImageIO.write(bi, "PNG", new File(path)); } catch (IOException ie) { ie.printStackTrace(); } } private void drawGroup(int groupPart) { int i = 0, length = 0; if(groupPart == 1) { i = 0; length = (this.barcodeBinary.length/2); } else if(groupPart == 2) { i = 6; length = this.barcodeBinary.length; } for(; i < length; ++i) { for(int n = 0; n < this.barcodeBinary[i].length; ++n) { if(this.barcodeBinary[i][n] == 0) { ig2.setPaint(Color.white); ig2.setStroke(new BasicStroke(this.barWidth)); } else { ig2.setPaint(Color.black); ig2.setStroke(new BasicStroke(this.barWidth)); } int pos = this.imgPixelPos; ig2.drawLine(pos,0,pos,this.barHeight); this.imgPixelPos += this.barWidth; } } } private void drawSpecial(int type) { /* Special Symbol Pattern Quite Zone 000000000 Lead / Trailer 101 Separator 01010 */ int[] quiteZone = {0,0,0,0,0,0,0,0,0}; int[] leadtrail = {1,0,1}; int[] separator = {0,1,0,1,0}; int binaryArrLength = 0; int[] arr; if(type == 0) { binaryArrLength = quiteZone.length; arr = quiteZone; } else if(type == 1) { binaryArrLength = leadtrail.length; arr = leadtrail; } else { binaryArrLength = separator.length; arr = separator; } for(int n = 0; n < binaryArrLength; ++n) { if(arr[n] == 0) ig2.setPaint(Color.white); else ig2.setPaint(Color.black); int pos = this.imgPixelPos; ig2.drawLine(pos,0,pos,this.barHeight); this.imgPixelPos += this.barWidth; } } public int calculateControlDigit(String ean) { int sum = 0; for(int i = 0; i < 12; ++i) { int val = charToInt(ean.charAt(i)); if((i+1)%2 == 0) sum += val*3; else sum += val*1; } return (10 - (sum % 10)); } private int charToInt(char c) { return Integer.parseInt(String.valueOf(c)); } }