Browse Source

Refactoring in most code generators, adding more customization options.

Matt Clark 6 months ago
parent
commit
0fc7c5e30f

+ 23 - 0
.project

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>BarcodeAPI</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>

+ 1 - 1
pom.xml

@@ -5,7 +5,7 @@
 
 	<groupId>org.barcodeapi</groupId>
 	<artifactId>server</artifactId>
-	<version>0.0.1-SNAPSHOT</version>
+	<version>0.0.3</version>
 
 	<name>server</name>
 	<packaging>jar</packaging>

+ 0 - 4
resources/static/index.js

@@ -251,10 +251,8 @@ function checkIfFileSelected() {
 
 	document.getElementById('csvFile').addEventListener('change', function () {
 		if(this.value.length > 0) {
-			console.log("file selected");
 			submitButton.removeAttribute("disabled");
 		} else {
-			console.log("no file");
 			submitButton.addAttribute("disabled");
 		}
 	});
@@ -298,7 +296,6 @@ function addTooltips() {
 
           var init_tooltip = function()
           {
-            console.log(getOffset(target));
             // set width of tooltip to half of window width
             if(window.innerWidth < tooltip.offsetWidth * 1.5)
             tooltip.style.maxWidth = window.innerWidth / 2;
@@ -307,7 +304,6 @@ function addTooltips() {
 
             var pos_left = getOffset(target).left + (target.offsetWidth / 2) - (tooltip.offsetWidth / 2),
             pos_top  = getOffset(target).top - tooltip.offsetHeight - 10;
-            console.log("top is", pos_top);
             if( pos_left < 0 )
             {
               pos_left = getOffset(target).left + target.offsetWidth / 2 - 20;

+ 1 - 1
src/main/java/org/barcodeapi/core/ServerRuntime.java

@@ -28,7 +28,7 @@ public class ServerRuntime {
 		StatsCollector.getInstance()//
 				.setValue(_RUNTIME_TIMESTART, "system", "time", "start");
 
-		_RUNTIME_VERSION = "2";
+		_RUNTIME_VERSION = "3";
 		StatsCollector.getInstance()//
 				.setValue(_RUNTIME_VERSION, "system", "version");
 

+ 15 - 12
src/main/java/org/barcodeapi/server/gen/types/AztecGenerator.java

@@ -18,32 +18,35 @@ import com.google.zxing.common.BitMatrix;
 
 public class AztecGenerator extends CodeGenerator {
 
-	private AztecWriter codeWriter;
+	private AztecWriter generator;
 
 	public AztecGenerator() {
 		super(CodeType.Aztec);
 
-		codeWriter = new AztecWriter();
+		generator = new AztecWriter();
 	}
 
 	@Override
-	public synchronized byte[] onRender(String data, JSONObject options) throws WriterException, IOException {
+	public byte[] onRender(String data, JSONObject options) throws WriterException, IOException {
 
-		int mWidth = 300;
-		int mHeight = 300;
+		int size = options.optInt("size", 300);
+		int correction = options.optInt("correction", 4);
+		int qz = options.optInt("qz", 2);
 
 		Map<EncodeHintType, Object> hintsMap = new HashMap<>();
 		hintsMap.put(EncodeHintType.CHARACTER_SET, "utf-8");
-		hintsMap.put(EncodeHintType.ERROR_CORRECTION, 10);
-		hintsMap.put(EncodeHintType.MARGIN, 2);
+		hintsMap.put(EncodeHintType.ERROR_CORRECTION, correction);
+		hintsMap.put(EncodeHintType.MARGIN, qz);
 
-		BitMatrix bitMatrix = codeWriter.encode(//
-				data, BarcodeFormat.AZTEC, mWidth, mHeight, hintsMap);
+		synchronized (generator) {
 
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
+			BitMatrix bitMatrix = generator.encode(//
+					data, BarcodeFormat.AZTEC, size, size, hintsMap);
 
-		MatrixToImageWriter.writeToStream(bitMatrix, "png", out);
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			MatrixToImageWriter.writeToStream(bitMatrix, "png", out);
 
-		return out.toByteArray();
+			return out.toByteArray();
+		}
 	}
 }

+ 37 - 38
src/main/java/org/barcodeapi/server/gen/types/CodabarGenerator.java

@@ -16,8 +16,6 @@ public class CodabarGenerator extends CodeGenerator {
 
 	private CodabarBean generator;
 
-	private final int dpi = 150;
-
 	/**
 	 * Constructor for the Codabar generator.
 	 */
@@ -26,50 +24,51 @@ public class CodabarGenerator extends CodeGenerator {
 
 		// Setup Codabar generator
 		generator = new CodabarBean();
-
-		// barcode128Bean.setBarHeight(height);
-		double moduleWidth = UnitConv.in2mm(2.5f / dpi);
-		generator.setModuleWidth(moduleWidth);
-
-		/**
-		 * The minimum width of the Quiet Zone to the left and right of the 128 Bar Code
-		 * is 10x, where x is the minimum width of a module. It is mandatory at the left
-		 * and right side of the barcode.
-		 * 
-		 * https://en.wikipedia.org/wiki/Code_128#Quiet_zone
-		 * 
-		 */
-		generator.doQuietZone(true);
-		generator.setQuietZone(10 * moduleWidth);
-		// generator.setVerticalQuietZone(2 * moduleWidth);
-
-		generator.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);
-
-		generator.setHeight(UnitConv.in2mm(1));
 	}
 
-	/**
-	 * Called when an image was not found in cache and must be rendered;
-	 * 
-	 * Return a PNG image as bytes.
-	 * 
-	 * @throws IOException
-	 */
 	@Override
-	public synchronized byte[] onRender(String data, JSONObject options) throws IOException {
+	public byte[] onRender(String data, JSONObject options) throws IOException {
+
+		int dpi = options.optInt("dpi", 150);
+		double moduleWidth = UnitConv.in2mm(2.5f / dpi);
+
+		int qz = options.optInt("qz", (int) (10 * moduleWidth));
+		int height = options.optInt("height", 25);
+
+		String text = options.optString("text", "bottom");
+
+		synchronized (generator) {
+
+			switch (text) {
+
+			case "bottom":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);
+				break;
 
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
+			case "top":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_TOP);
+				break;
 
-		BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
-				out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
+			case "none":
+			default:
+				generator.setMsgPosition(HumanReadablePlacement.HRP_NONE);
+				break;
+			}
 
-		generator.generateBarcode(canvasProvider, data);
+			generator.doQuietZone(true);
+			generator.setQuietZone(qz);
+			generator.setHeight(height);
+			generator.setModuleWidth(moduleWidth);
 
-		canvasProvider.getBufferedImage();
-		canvasProvider.finish();
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
+					out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
 
-		out.close();
+			generator.generateBarcode(canvasProvider, data);
+			canvasProvider.finish();
+			out.close();
 
-		return out.toByteArray();
+			return out.toByteArray();
+		}
 	}
 }

+ 37 - 30
src/main/java/org/barcodeapi/server/gen/types/Code128Generator.java

@@ -17,32 +17,11 @@ public class Code128Generator extends CodeGenerator {
 
 	private Code128Bean generator;
 
-	private final int dpi = 150;
-
 	public Code128Generator() {
 		super(CodeType.Code128);
 
 		// Setup Code128 generator
 		generator = new Code128Bean();
-
-		// barcode128Bean.setBarHeight(height);
-		double moduleWidth = UnitConv.in2mm(2.5f / dpi);
-		generator.setModuleWidth(moduleWidth);
-
-		/**
-		 * The minimum width of the Quiet Zone to the left and right of the 128 Bar Code
-		 * is 10x, where x is the minimum width of a module. It is mandatory at the left
-		 * and right side of the barcode.
-		 * 
-		 * https://en.wikipedia.org/wiki/Code_128#Quiet_zone
-		 * 
-		 */
-		generator.doQuietZone(true);
-		generator.setQuietZone(10 * moduleWidth);
-
-		generator.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);
-
-		generator.setHeight(UnitConv.in2mm(1));
 	}
 
 	@Override
@@ -52,20 +31,48 @@ public class Code128Generator extends CodeGenerator {
 	}
 
 	@Override
-	public synchronized byte[] onRender(String data, JSONObject options) throws IOException {
+	public byte[] onRender(String data, JSONObject options) throws IOException {
+
+		int dpi = options.optInt("dpi", 150);
+		double moduleWidth = UnitConv.in2mm(2.5f / dpi);
+
+		int qz = options.optInt("qz", (int) (10 * moduleWidth));
+		int height = options.optInt("height", 25);
+
+		String text = options.optString("text", "bottom");
+
+		synchronized (generator) {
+
+			switch (text) {
+
+			case "bottom":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);
+				break;
 
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
+			case "top":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_TOP);
+				break;
 
-		BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
-				out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
+			case "none":
+			default:
+				generator.setMsgPosition(HumanReadablePlacement.HRP_NONE);
+				break;
+			}
 
-		generator.generateBarcode(canvasProvider, data);
+			generator.doQuietZone(true);
+			generator.setQuietZone(qz);
+			generator.setHeight(height);
+			generator.setModuleWidth(moduleWidth);
 
-		canvasProvider.getBufferedImage();
-		canvasProvider.finish();
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
+					out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
 
-		out.close();
+			generator.generateBarcode(canvasProvider, data);
+			canvasProvider.finish();
+			out.close();
 
-		return out.toByteArray();
+			return out.toByteArray();
+		}
 	}
 }

+ 34 - 25
src/main/java/org/barcodeapi/server/gen/types/Code39Generator.java

@@ -16,47 +16,56 @@ public class Code39Generator extends CodeGenerator {
 
 	private Code39Bean generator;
 
-	private final int dpi = 150;
-
 	public Code39Generator() {
 		super(CodeType.Code39);
 
 		// Setup Code39 generator
 		generator = new Code39Bean();
+	}
+
+	@Override
+	public byte[] onRender(String data, JSONObject options) throws IOException {
 
+		int dpi = options.optInt("dpi", 150);
 		double moduleWidth = UnitConv.in2mm(2.5f / dpi);
-		generator.setModuleWidth(moduleWidth);
 
-		/**
-		 * Set quiet zone
-		 */
-		generator.doQuietZone(true);
-		generator.setQuietZone(10 * moduleWidth);
-		generator.setVerticalQuietZone(2 * moduleWidth);
+		int qz = options.optInt("qz", (int) (10 * moduleWidth));
+		int height = options.optInt("height", 25);
 
-		generator.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);
+		String text = options.optString("text", "bottom");
 
-		generator.setHeight(UnitConv.in2mm(1));
-		// barcode39Bean.setBarHeight(UnitConv.in2mm(.5));
+		synchronized (generator) {
 
-		// barcode39Bean.setFontName(name);
-		// barcode39Bean.setFontSize(size);
-	}
+			switch (text) {
 
-	@Override
-	public synchronized byte[] onRender(String data, JSONObject options) throws IOException {
+			case "bottom":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);
+				break;
+
+			case "top":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_TOP);
+				break;
 
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
+			case "none":
+			default:
+				generator.setMsgPosition(HumanReadablePlacement.HRP_NONE);
+				break;
+			}
 
-		BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
-				out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
+			generator.doQuietZone(true);
+			generator.setQuietZone(qz);
+			generator.setHeight(height);
+			generator.setModuleWidth(moduleWidth);
 
-		generator.generateBarcode(canvasProvider, data);
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
+					out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
 
-		canvasProvider.getBufferedImage();
-		canvasProvider.finish();
-		out.close();
+			generator.generateBarcode(canvasProvider, data);
+			canvasProvider.finish();
+			out.close();
 
-		return out.toByteArray();
+			return out.toByteArray();
+		}
 	}
 }

+ 25 - 18
src/main/java/org/barcodeapi/server/gen/types/DataMatrixGenerator.java

@@ -23,10 +23,6 @@ public class DataMatrixGenerator extends CodeGenerator {
 		super(CodeType.DataMatrix);
 
 		generator = new DataMatrixBean();
-
-		// configure barcode generator
-		generator.doQuietZone(true);
-		generator.setShape(SymbolShapeHint.FORCE_SQUARE);
 	}
 
 	@Override
@@ -36,25 +32,36 @@ public class DataMatrixGenerator extends CodeGenerator {
 	}
 
 	@Override
-	public synchronized byte[] onRender(String data, JSONObject options) throws IOException {
-
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
+	public byte[] onRender(String data, JSONObject options) throws IOException {
 
 		int dpi = options.optInt("dpi", 200);
-		double size = options.optDouble("size", 1.5);
-		int quiet = options.optInt("qz", (int) (size * 2));
+		double scale = options.optDouble("scale", 1.5);
+		int qz = options.optInt("qz", (int) (scale * 2));
+
+		boolean square = options.optBoolean("square", true);
+
+		synchronized (generator) {
+
+			if (square) {
+				generator.setShape(SymbolShapeHint.FORCE_SQUARE);
+			} else {
+				generator.setShape(SymbolShapeHint.FORCE_NONE);
+			}
+
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
 
-		BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
-				out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
+			BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
+					out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
 
-		generator.setQuietZone(quiet);
-		generator.setModuleWidth(size);
-		generator.generateBarcode(canvasProvider, data);
+			generator.doQuietZone(true);
+			generator.setQuietZone(qz);
+			generator.setModuleWidth(scale);
 
-		canvasProvider.getBufferedImage();
-		canvasProvider.finish();
-		out.close();
+			generator.generateBarcode(canvasProvider, data);
+			canvasProvider.finish();
+			out.close();
 
-		return out.toByteArray();
+			return out.toByteArray();
+		}
 	}
 }

+ 39 - 16
src/main/java/org/barcodeapi/server/gen/types/Ean13Generator.java

@@ -10,6 +10,7 @@ import org.barcodeapi.server.core.GenerationException.ExceptionType;
 import org.barcodeapi.server.gen.CodeGenerator;
 import org.barcodeapi.server.gen.CodeType;
 import org.json.JSONObject;
+import org.krysalis.barcode4j.HumanReadablePlacement;
 import org.krysalis.barcode4j.impl.upcean.EAN13Bean;
 import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
 import org.krysalis.barcode4j.tools.UnitConv;
@@ -18,17 +19,10 @@ public class Ean13Generator extends CodeGenerator {
 
 	private EAN13Bean generator;
 
-	private final int dpi = 150;
-
 	public Ean13Generator() {
 		super(CodeType.EAN13);
 
 		generator = new EAN13Bean();
-
-		// configure barcode generator
-		generator.setModuleWidth(UnitConv.in2mm(2.5f / dpi));
-		generator.doQuietZone(true);
-		generator.setQuietZone(4);
 	}
 
 	@Override
@@ -52,19 +46,48 @@ public class Ean13Generator extends CodeGenerator {
 	}
 
 	@Override
-	public synchronized byte[] onRender(String data, JSONObject options) throws IOException {
+	public byte[] onRender(String data, JSONObject options) throws IOException {
+
+		int dpi = options.optInt("dpi", 150);
+		double moduleWidth = UnitConv.in2mm(2.5f / dpi);
+
+		int qz = options.optInt("qz", 4);
+		int height = options.optInt("height", 25);
+
+		String text = options.optString("text", "bottom");
 
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		synchronized (generator) {
 
-		BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
-				out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
+			switch (text) {
 
-		generator.generateBarcode(canvasProvider, data);
+			case "bottom":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);
+				break;
 
-		canvasProvider.getBufferedImage();
-		canvasProvider.finish();
-		out.close();
+			case "top":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_TOP);
+				break;
 
-		return out.toByteArray();
+			case "none":
+			default:
+				generator.setMsgPosition(HumanReadablePlacement.HRP_NONE);
+				break;
+			}
+
+			generator.doQuietZone(true);
+			generator.setQuietZone(qz);
+			generator.setHeight(height);
+			generator.setModuleWidth(moduleWidth);
+
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
+					out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
+
+			generator.generateBarcode(canvasProvider, data);
+			canvasProvider.finish();
+			out.close();
+
+			return out.toByteArray();
+		}
 	}
 }

+ 39 - 16
src/main/java/org/barcodeapi/server/gen/types/Ean8Generator.java

@@ -10,6 +10,7 @@ import org.barcodeapi.server.core.GenerationException.ExceptionType;
 import org.barcodeapi.server.gen.CodeGenerator;
 import org.barcodeapi.server.gen.CodeType;
 import org.json.JSONObject;
+import org.krysalis.barcode4j.HumanReadablePlacement;
 import org.krysalis.barcode4j.impl.upcean.EAN8Bean;
 import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
 import org.krysalis.barcode4j.tools.UnitConv;
@@ -18,17 +19,10 @@ public class Ean8Generator extends CodeGenerator {
 
 	private EAN8Bean generator;
 
-	private final int dpi = 150;
-
 	public Ean8Generator() {
 		super(CodeType.EAN8);
 
 		generator = new EAN8Bean();
-
-		// configure barcode generator
-		generator.setModuleWidth(UnitConv.in2mm(2.5f / dpi));
-		generator.doQuietZone(true);
-		generator.setQuietZone(4);
 	}
 
 	@Override
@@ -52,19 +46,48 @@ public class Ean8Generator extends CodeGenerator {
 	}
 
 	@Override
-	public synchronized byte[] onRender(String data, JSONObject options) throws IOException {
+	public byte[] onRender(String data, JSONObject options) throws IOException {
+
+		int dpi = options.optInt("dpi", 150);
+		double moduleWidth = UnitConv.in2mm(2.5f / dpi);
+
+		int qz = options.optInt("qz", 4);
+		int height = options.optInt("height", 25);
+
+		String text = options.optString("text", "bottom");
 
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		synchronized (generator) {
 
-		BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
-				out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
+			switch (text) {
 
-		generator.generateBarcode(canvasProvider, data);
+			case "bottom":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);
+				break;
 
-		canvasProvider.getBufferedImage();
-		canvasProvider.finish();
-		out.close();
+			case "top":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_TOP);
+				break;
 
-		return out.toByteArray();
+			case "none":
+			default:
+				generator.setMsgPosition(HumanReadablePlacement.HRP_NONE);
+				break;
+			}
+
+			generator.doQuietZone(true);
+			generator.setQuietZone(qz);
+			generator.setHeight(height);
+			generator.setModuleWidth(moduleWidth);
+
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
+					out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
+
+			generator.generateBarcode(canvasProvider, data);
+			canvasProvider.finish();
+			out.close();
+
+			return out.toByteArray();
+		}
 	}
 }

+ 16 - 20
src/main/java/org/barcodeapi/server/gen/types/PDF417Generator.java

@@ -15,8 +15,6 @@ public class PDF417Generator extends CodeGenerator {
 
 	private PDF417Bean generator;
 
-	private final int dpi = 200;
-
 	/**
 	 * https://en.wikipedia.org/wiki/Data_Matrix
 	 */
@@ -24,33 +22,31 @@ public class PDF417Generator extends CodeGenerator {
 		super(CodeType.PDF417);
 
 		generator = new PDF417Bean();
-
-		// configure barcode generator
-		generator.setQuietZone(2);
-		generator.doQuietZone(true);
-		generator.setModuleWidth(UnitConv.in2mm(5.0f / dpi));
 	}
 
 	@Override
-	public String onValidateRequest(String data) {
+	public byte[] onRender(String data, JSONObject options) throws IOException {
 
-		return data;
-	}
+		int dpi = options.optInt("dpi", 150);
+		double moduleWidth = UnitConv.in2mm(5.0f / dpi);
 
-	@Override
-	public synchronized byte[] onRender(String data, JSONObject options) throws IOException {
+		int qz = options.optInt("qz", 2);
 
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		synchronized (generator) {
 
-		BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
-				out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
+			generator.doQuietZone(true);
+			generator.setQuietZone(qz);
+			generator.setModuleWidth(moduleWidth);
 
-		generator.generateBarcode(canvasProvider, data);
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
+					out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
 
-		canvasProvider.getBufferedImage();
-		canvasProvider.finish();
-		out.close();
+			generator.generateBarcode(canvasProvider, data);
+			canvasProvider.finish();
+			out.close();
 
-		return out.toByteArray();
+			return out.toByteArray();
+		}
 	}
 }

+ 11 - 10
src/main/java/org/barcodeapi/server/gen/types/QRCodeGenerator.java

@@ -20,12 +20,12 @@ import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
 
 public class QRCodeGenerator extends CodeGenerator {
 
-	private QRCodeWriter codeWriter;
+	private QRCodeWriter generator;
 
 	public QRCodeGenerator() {
 		super(CodeType.QRCode);
 
-		codeWriter = new QRCodeWriter();
+		generator = new QRCodeWriter();
 	}
 
 	@Override
@@ -35,23 +35,24 @@ public class QRCodeGenerator extends CodeGenerator {
 	}
 
 	@Override
-	public synchronized byte[] onRender(String data, JSONObject options) throws WriterException, IOException {
+	public byte[] onRender(String data, JSONObject options) throws WriterException, IOException {
 
-		int mWidth = 300;
-		int mHeight = 300;
+		int size = options.optInt("size", 300);
 
 		Map<EncodeHintType, Object> hintsMap = new HashMap<>();
 		hintsMap.put(EncodeHintType.CHARACTER_SET, "utf-8");
 		hintsMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
 		hintsMap.put(EncodeHintType.MARGIN, 2);
 
-		BitMatrix bitMatrix = codeWriter.encode(//
-				data, BarcodeFormat.QR_CODE, mWidth, mHeight, hintsMap);
+		synchronized (generator) {
 
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
+			BitMatrix bitMatrix = generator.encode(//
+					data, BarcodeFormat.QR_CODE, size, size, hintsMap);
 
-		MatrixToImageWriter.writeToStream(bitMatrix, "png", out);
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			MatrixToImageWriter.writeToStream(bitMatrix, "png", out);
 
-		return out.toByteArray();
+			return out.toByteArray();
+		}
 	}
 }

+ 36 - 25
src/main/java/org/barcodeapi/server/gen/types/UPCAGenerator.java

@@ -16,46 +16,57 @@ public class UPCAGenerator extends CodeGenerator {
 
 	private UPCABean generator;
 
-	private final int dpi = 150;
-
-	/**
-	 * 
-	 */
 	public UPCAGenerator() {
 		super(CodeType.UPC_A);
 
 		// Setup Code39 generator
 		generator = new UPCABean();
+	}
+
+	@Override
+	public byte[] onRender(String data, JSONObject options) throws IOException {
 
+		int dpi = options.optInt("dpi", 150);
 		double moduleWidth = UnitConv.in2mm(2.5f / dpi);
-		generator.setModuleWidth(moduleWidth);
 
-		/**
-		 * Set quiet zone
-		 */
-		generator.doQuietZone(true);
-		generator.setQuietZone(10 * moduleWidth);
-		generator.setVerticalQuietZone(2 * moduleWidth);
+		int qz = options.optInt("qz", 4);
+		int height = options.optInt("height", 25);
 
-		generator.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);
+		String text = options.optString("text", "bottom");
 
-		generator.setHeight(UnitConv.in2mm(1));
-	}
+		synchronized (generator) {
 
-	@Override
-	public synchronized byte[] onRender(String data, JSONObject options) throws IOException {
+			switch (text) {
+
+			case "bottom":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);
+				break;
+
+			case "top":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_TOP);
+				break;
 
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
+			case "none":
+			default:
+				generator.setMsgPosition(HumanReadablePlacement.HRP_NONE);
+				break;
+			}
 
-		BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
-				out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
+			generator.doQuietZone(true);
+			generator.setQuietZone(qz);
+			generator.setVerticalQuietZone(2 * moduleWidth);
+			generator.setHeight(height);
+			generator.setModuleWidth(moduleWidth);
 
-		generator.generateBarcode(canvasProvider, data);
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
+					out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
 
-		canvasProvider.getBufferedImage();
-		canvasProvider.finish();
-		out.close();
+			generator.generateBarcode(canvasProvider, data);
+			canvasProvider.finish();
+			out.close();
 
-		return out.toByteArray();
+			return out.toByteArray();
+		}
 	}
 }

+ 36 - 18
src/main/java/org/barcodeapi/server/gen/types/UPCEGenerator.java

@@ -24,33 +24,51 @@ public class UPCEGenerator extends CodeGenerator {
 
 		// Setup Code39 generator
 		generator = new UPCEBean();
-
-		generator.doQuietZone(true);
-		generator.setHeight(UnitConv.in2mm(1));
-		generator.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);
 	}
 
 	@Override
-	public synchronized byte[] onRender(String data, JSONObject options) throws IOException {
+	public byte[] onRender(String data, JSONObject options) throws IOException {
 
 		int dpi = options.optInt("dpi", 150);
+		double moduleWidth = UnitConv.in2mm(2.5f / dpi);
 
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
-				out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
+		int qz = options.optInt("qz", (int) (10 * moduleWidth));
+		int height = options.optInt("height", 25);
 
-		double moduleWidth = UnitConv.in2mm(2.5f / dpi);
+		String text = options.optString("text", "bottom");
+
+		synchronized (generator) {
+
+			switch (text) {
+
+			case "bottom":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_BOTTOM);
+				break;
+
+			case "top":
+				generator.setMsgPosition(HumanReadablePlacement.HRP_TOP);
+				break;
+
+			case "none":
+			default:
+				generator.setMsgPosition(HumanReadablePlacement.HRP_NONE);
+				break;
+			}
+
+			generator.doQuietZone(true);
+			generator.setQuietZone(qz);
+			generator.setHeight(height);
+			generator.setModuleWidth(moduleWidth);
 
-		// set options and generate
-		generator.setModuleWidth(moduleWidth);
-		generator.setQuietZone(10 * moduleWidth);
-		generator.setVerticalQuietZone(2 * moduleWidth);
-		generator.generateBarcode(canvasProvider, data);
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(//
+					out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
 
-		canvasProvider.getBufferedImage();
-		canvasProvider.finish();
-		out.close();
+			generator.generateBarcode(canvasProvider, data);
+			canvasProvider.finish();
+			out.close();
 
-		return out.toByteArray();
+			return out.toByteArray();
+		}
 	}
 }