terça-feira, janeiro 04, 2005

Criando código de Barras

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.!

4 comentários:

Anônimo disse...

Como ficaria o retorno do servlet para a página JSP? Como que eu mostro o código de barra na página JSP?

Abraço

Dadario disse...

É possível montar um servlet tradicional e colocar na sua chamada no JSP como uma entrada de imagem
.. img src='meu_servelet' ..

Arthur Gregório disse...

cara, se eu fosse adapta para uma app em desktop, como faria?

lifeweb disse...

como faço pra retornar uma imagem do código de barra pra minha jsp???

please, help-me.

Alexsandro