Criar código de barras é uma tarefa que exige entender a regra da criação das barras e seus significados.
Para um dos projetos em desenvolvimento, precisei da geração de códigos de barras para o formato Interleaved 2 of 5 (intercalado 2 de 5).
Como JAVA tem um universo aberto, fui ao encontro de API que fazem este serviço de geração do código de barras. Encontrei estes:
http://jbars.sourceforge.net/ - Open Source
http://java4less.com/barcodes_e.htm - Parece ser pago
Mas destes dois, nenhum foi possível gerar e validar na agência bancária... Nem no caixa eletronico...
Então como precisava gerar o código correto para o Interleaved 2 of 5, peguei a especificação para geração do código de barras e fiz minha implementação...
Ficou em duas classes, pensando numa futura evolução para outros modelos... Mas isto se precisar.
As classes ficaram assim:
Barcode.java/*
* Created on 28/12/2004
*
*/
package br.com.gadew.jbarcode;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
/**
* @author Adriano
*
*/
public abstract class Barcode {
public int ALTURA;
public int LARGURA;
public int MARGEM_SUPERIOR;
public int MARGEM_INFERIOR;
public int MARGEM_ESQUERDA;
public int MARGEM_DIREITA;
public Color COR_FUNDO;
public Color COR_BARRAS;
protected String codigo;
public BufferedImage render() {
BufferedImage bufferedImage = new BufferedImage(LARGURA,
ALTURA, java.awt.image.BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = (Graphics2D) bufferedImage.getGraphics();
validarCodigo();
graphics.setPaint(COR_FUNDO);
graphics.fillRect(0, 0, LARGURA, ALTURA);
graphics.setColor(COR_BARRAS);
int posicaoFinal = renderize(graphics);
graphics.setPaint(COR_FUNDO);
graphics.fillRect(posicaoFinal, 0, MARGEM_DIREITA, ALTURA);
if (posicaoFinal > LARGURA) {
System.err.println("Barras ultrapassam o tamanho da figura em "
+ (posicaoFinal - LARGURA));
}
return bufferedImage;
}
protected abstract int renderize(Graphics2D graphics);
protected abstract void validarCodigo();
}
e o arquivo
Interleaved2of5.java
/*
* Created on 28/12/2004
*
*/
package br.com.gadew.jbarcode;
import java.awt.Graphics2D;
import java.awt.Rectangle;
/**
* @author Adriano
*
*/
public class Interleaved2of5 extends Barcode {
private static final int LARGURA_N = 1;
private static final int LARGURA_W = 3;
private static final char[] padraoInicial =
new char[] { 'n', 'n', 'n', 'n' };
private static final char[] padraoFinal =
new char[] { 'w', 'n', 'n' };
private static char[][] padrao =
new char[][] { { 'n', 'n', 'w', 'w', 'n' },// 0
{ 'w', 'n', 'n', 'n', 'w' },// 1
{ 'n', 'w', 'n', 'n', 'w' },// 2
{ 'w', 'w', 'n', 'n', 'n' },// 3
{ 'n', 'n', 'w', 'n', 'w' },// 4
{ 'w', 'n', 'w', 'n', 'n' },// 5
{ 'n', 'w', 'w', 'n', 'n' },// 6
{ 'n', 'n', 'n', 'w', 'w' },// 7
{ 'w', 'n', 'n', 'w', 'n' },// 8
{ 'n', 'w', 'n', 'w', 'n' },// 9
};
public Interleaved2of5(String codigo) {
super.codigo = codigo;
}
private String padrao() {
StringBuffer buffer = new StringBuffer();
buffer.append(padraoInicial);
for (int i = 0; i < codigo.length(); i += 2) {
String primeiro = codigo.substring(i, i + 1);
String segundo = codigo.substring(i + 1, i + 2);
char[] valorPrimeiro = padrao[Integer.parseInt(primeiro)];
char[] valorSegundo = padrao[Integer.parseInt(segundo)];
buffer.append(concatena(valorPrimeiro, valorSegundo));
}
buffer.append(padraoFinal);
return buffer.toString();
}
private StringBuffer concatena(char[] valorPrimeiro,
char[] valorSegundo) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < valorSegundo.length; i++) {
buffer.append(valorPrimeiro[i]).append(valorSegundo[i]);
}
return buffer;
}
/*
* (non-Javadoc)
*
* @see br.com.gadew.jbarcode.Barcode#validarCodigo()
*/
protected void validarCodigo() {
if (codigo == null) {
throw new IllegalArgumentException("Valor do código é null");
}
String somenteNumeros = codigo.replaceAll("\\D", "");
if (somenteNumeros.length() % 2 != 0) {
throw new IllegalArgumentException("O tamanho do código deve "
+ "consistir de tamanho par e somente números.");
}
}
/*
* (non-Javadoc)
*
* @see br.com.gadew.jbarcode.Barcode#renderize(java.awt.Graphics2D)
*/
protected int renderize(Graphics2D graphics) {
int posicao = MARGEM_ESQUERDA;
boolean imprimir = true;
int alturaBarra = ALTURA - (MARGEM_SUPERIOR + MARGEM_INFERIOR);
String modelo = padrao();
for (int i = 0; i < modelo.length(); i++) {
char tipo = modelo.charAt(i);
posicao = imprimirQuadrado(tipo,
graphics,
posicao,
alturaBarra,
imprimir);
imprimir = !imprimir;
}
return posicao;
}
/**
* @param tipo
* @param graphics
* @param posicao
* @param alturaBarra
* @param imprimir
* @return
*/
private int imprimirQuadrado(char tipo,
Graphics2D graphics,
int posicao,
int alturaBarra,
boolean imprimir) {
Rectangle quadrado = new Rectangle();
quadrado.setLocation(posicao, MARGEM_SUPERIOR);
switch (tipo) {
case 'n':
quadrado.setSize(LARGURA_N, alturaBarra);
posicao += LARGURA_N;
break;
case 'w':
quadrado.setSize(LARGURA_W, alturaBarra);
posicao += LARGURA_W;
break;
}
if (imprimir) {
graphics.fill(quadrado);
}
return posicao;
}
}
E para a utilização do código é simples, eu fiz para utilizar em um Servlet:
Barcode bar = new Interleaved2of5(request.getParameter("codigo"));
bar.ALTURA = 50;
bar.LARGURA = 450;
bar.COR_FUNDO = Color.WHITE;
bar.COR_BARRAS = Color.BLACK;
bar.MARGEM_ESQUERDA = 15;
bar.MARGEM_DIREITA = 15;
BufferedImage BarImage = bar.render();
OutputStream os = response.getOutputStream();
JPEGImageEncoder coder = JPEGCodec.createJPEGEncoder(os);
coder.encode(BarImage);
os.flush();
os.close();
Agora só falta implementar os demais códigos de barras.!