Scanners, câmeras digitais, e outros dispositivos de aquisição de
imagens estão constantemente presentes no panorama da computação.
Em que pese essa ubiquidade, Java ainda não possui uma especificação
ou uma API padrão para interagir com estes componentes.
Quando se faz necessário integrar uma aplicação Java a tais
dispositivos, o programador deve recorrer a bindings,
que usam métodos nativos fora da JVM.
Atualmente existem dois protocolos,
conhecidos como TWAIN e SANE, que especificam a comunicação entre
um software e um dispositivo de imagens.
TWAIN, além de um protocolo, também
representa uma organização formada pelas principais marcas da
indústria da imagem. SANE (Scanner Access Now Easy),
comumente usade em Linux, é
uma API que padroniza o acesso a dispositivos de imagens, e difere de
TWAIN a medida em que separa claramente o frontend
(programa do usuário) e o backend (driver),
o que torna mais fácil e transparente o acesso aos dispositivos
dentro de uma rede (como uma LAN cheia de máquinas, mas com scanners
conectados a apenas um ou duas máquinas, por exemplo).
Segue uma implementação simples que exibe uma janela e um botão que ativa o scanner local para digitalizar o documento contido bandeja. E necessário configurar seu classpath com as bibliotecas do projeto mm's computing, Scan_.jar e uk.co.mmscomputing.device.twain.jar, as quais podem ser baixadas aqui. Use JDK 7 32bit.
Segue uma implementação simples que exibe uma janela e um botão que ativa o scanner local para digitalizar o documento contido bandeja. E necessário configurar seu classpath com as bibliotecas do projeto mm's computing, Scan_.jar e uk.co.mmscomputing.device.twain.jar, as quais podem ser baixadas aqui. Use JDK 7 32bit.
public class ScannerImageTest extends JFrame implements ScannerListener{
Scanner scanner;
ImagePanel imagePanel;
JButton capturar;
public ScannerImageTest() {
setUpJFrame();
//busca um scanner conectado à máquina local
scanner = Scanner.getDevice();
//registra um objeto ScannerListener para capturar os eventos
scanner.addListener(this);
setVisible(true);
}
private void setUpJFrame() {
imagePanel = new ImagePanel();
capturar = new JButton("Capturar Imagem");
capturar.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
//inicia a digitalização da imagem
scanner.acquire();
} catch (ScannerIOException ex) {
ex.printStackTrace();
}
}
});
setSize(410, 510);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(capturar, BorderLayout.NORTH);
getContentPane().add(imagePanel, BorderLayout.CENTER);
setTitle("Hello Scanner!");
}
//chamado automaticamente pelo listener do scanner
@Override
public void update(ScannerIOMetadata.Type type, ScannerIOMetadata siom) {
if(type.equals(ScannerIOMetadata.ACQUIRED)){
//neste ponto o documento foi totalmente digitalizado
BufferedImage bufferedImage = siom.getImage();
imagePanel.setScannedImage(bufferedImage);
}
}
public static void main(String[] args) {
//inicia a aplicação
new ScannerImageTest();
}
}
class ImagePanel extends JPanel{
Image scannedImage;
public void setScannedImage(Image scannedImage) {
this.scannedImage = scannedImage;
if(scannedImage != null){
this.scannedImage = scannedImage.getScaledInstance(400, 500, 0);
}
super.repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if(scannedImage != null){
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(scannedImage, 0, 0, null);
g2d.dispose();
}
}
}
A aplicação captura a imagem e a exibe em um painel:
A biblioteca do projeto mm's computing permite que o programador utilize uma interface gráfica padrão, com mais recursos de digitalização, neste caso uma nova janela é exibida durante o processo; ou é possível acoplar uma interface mais simples no frame, chamando o método:
Scanner.getDevice().getScanGUI()