从JAVA中的图像中读取条形码

时间:2013-11-09 09:44:53

标签: java image

我有一个java应用程序,它需要从图像中读取条形码到java程序。我对能够检索条形码的zxing库印象非常深刻,但不是所有图像(我的意思是图像质量稍差)。

我的问题是,阅读条形码的最佳图像格式是什么? JPEG或PNG?我正在尝试JPEG图像。

另一个问题是,从图像中检索条形码的最可靠的Java API / SDK是什么。我已经尝试了AccusoftDataSymbolAtalaSoftj4l付费版本。并经历过Ron Cemer JavaBar之类的开源。 但我仍然在寻找一种JAVA API / SDK,它可以在条形码读取中提供准确的结果。

您对条形码阅读器JAVA API / SDK的信息对我非常有帮助。

5 个答案:

答案 0 :(得分:4)

@Tom Setzer的解决方案非常棒,如果您不介意为您的项目支付额外费用。但是,如果你没有预算来获得这样的软件,我仍然建议你听汤姆的回答。

  

改善结果的一个选择是在发送到引擎之前进行一些图像处理。尝试在从灰色/彩色变为黑白之前缩放图像。比引擎中提供的更好的二值化(灰色到b& w)也可以帮助。

他是对的,但我还在使用ZXing。只有当你在尝试读取条形码之前进行一些图像处理时才能很好地

我正在使用OpenCV进行图像处理。一个伟大的本机库,既适用于Linux和Windows,也可能适用于其他一些平台(尚未研究过)。

这就是我这样做的方式。

  1. 将图像转换为灰度。
  2. 调整条形码的高度最多为4倍,宽度为8倍。
  3. 应用尺寸为17x17像素的高斯模糊。
  4. 应用二进制阈值,阈值为225,最大值为255。
  5. 按照这些步骤后,您的效果会更好。

    资源:

答案 1 :(得分:1)

基于Apache Camel Barcode的Java zxing library很好用:

依赖性

<!-- https://mvnrepository.com/artifact/org.apache.camel/camel-barcode -->
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-barcode</artifactId>
    <version>2.21.1</version>
</dependency>

一些示例(如果需要,可以旋转)

import com.google.zxing.BinaryBitmap;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Reader;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import lombok.Getter;

import javax.imageio.ImageIO;
import java.io.IOException;
import java.io.InputStream;

public class BarcodeImageDecoder {

    public BarcodeInfo decodeImage(InputStream inputStream) throws BarcodeDecodingException {
        try {
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(
                    new BufferedImageLuminanceSource(ImageIO.read(inputStream))));
            if (bitmap.getWidth() < bitmap.getHeight()) {
                if (bitmap.isRotateSupported()) {
                    bitmap = bitmap.rotateCounterClockwise();
                }
            }
            return decode(bitmap);
        } catch (IOException e) {
            throw new BarcodeDecodingException(e);
        }
    }

    private BarcodeInfo decode(BinaryBitmap bitmap) throws BarcodeDecodingException {
        Reader reader = new MultiFormatReader();
        try {
            Result result = reader.decode(bitmap);
            return new BarcodeInfo(result.getText(), result.getBarcodeFormat().toString());
        } catch (Exception e) {
            throw new BarcodeDecodingException(e);
        }
    }

    public static class BarcodeInfo {
        @Getter
        private final String text;
        @Getter
        private final String format;

        BarcodeInfo(String text, String format) {
            this.text = text;
            this.format = format;
        }
    }

    public static class BarcodeDecodingException extends Exception {
        BarcodeDecodingException(Throwable cause) {
            super(cause);
        }
    }
}

答案 2 :(得分:0)

JavaBar还有一件事你可以认为它是开源的并且有很好的评论

答案 3 :(得分:0)

最近,我发现这个软件zbar在阅读条形码时给出了有希望的结果。 它可以选择从命令提示符解码条形码。因为,它不是SDK或API。所以,我做了一个技巧,通过java程序从图像中读取条形码。

import java.io.*;

public class BarCodeReader {
public static void main(String args[]) 
{ 
    try 
    { 
        Process p=Runtime.getRuntime().exec("C:/Program Files/ZBar/bin/zbarimg  D:/jpeg/006.jpg"); 
        p.waitFor(); 
        BufferedReader reader=new BufferedReader(
            new InputStreamReader(p.getInputStream())
        ); 
        String line=reader.readLine(); 
        while(line!=null) 
        { 
            System.out.println(line); 
            line=reader.readLine(); 
        } 

    }
    catch(IOException e1) {} 
    catch(InterruptedException e2) {} 

    System.out.println("Done");

}
}

希望,对于那些试图从JAVA中的图像中读取条形码的人来说,这可能会有所帮助。

注意:它也适用于Linux。我测试了它。 对于linux环境,您需要做的就是运行此命令。

sudo apt-get install zbar-tools

并在Java程序中,像这样更改代码,

Process p=Runtime.getRuntime().exec("zbarimg /opt/images/006.jpg");// your file path.

它非常好。

如果您遇到任何其他可以在命令行上运行的SDK或API或软件的条形码,请留下答案。

答案 4 :(得分:0)

我最近遇到了一个同样的问题:在Java应用程序中使用ZXing库时,我正在解码QR码,但是我们经常不得不处理低质量的打印扫描,并且需要提高QR码的识别率。我在这里添加我的发现,希望它能对遇到相同问题的人有所帮助。

我使用了ImageJ图像处理库。它相当广泛,实际上是一个带有GUI和许多插件的完整程序。 我只使用了api:

    <dependency>
        <groupId>net.imagej</groupId>
        <artifactId>ij</artifactId>
        <version>1.52g</version>
    </dependency>

documentation没什么用,these tutorials更有趣。

我不得不寻找API的javadocs,您可以找到它们here

因此,我尝试了一堆图像优化和增强功能,但是似乎没有什么真正起到积极作用。剪掉扫描时放置QR码的子图像可以大大加快该过程。

然后我在这里的另一条评论中尝试了@kevto用户的建议(谢谢!)

Convert to the image to grayscale.
Resize barcode up to 4 times in height and 8 times in width.
Apply gaussian blur with the size of 17x17 pixels.
Apply binary threshold with the threshold value of 225 and maximum value of 255.

图像已经是灰度的,因此不会影响QR码的识别率。最后的建议似乎也没有太大作用。第二个有点奇怪:使用不同的宽度和高度参数调整大小会拉长图像,并导致无法识别的QR码。第三个建议是我要寻找的建议:在处理低质量扫描时,添加高斯模糊会大大提高QR码的识别率。向高质量扫描的QR码添加模糊效果会降低识别率,因此请当心。

产生此代码:

  public BufferedImage preProcessBufferedImage (BufferedImage bufferedImage)throws IOException{
    //get subimage that cuts out the QR code, speeds up the QR recognition process
    BufferedImage subImage = bufferedImage.getSubimage(x, y,width,height);
    //gaussian blur the result , leads to better QR code recognition
    ImagePlus imagePlus = new ImagePlus("process-qr-code", subImage);
    imagePlus.getProcessor().blurGaussian(2);
    return imagePlus.getBufferedImage();
}

我为模糊函数的sigma尝试了很多值。介于1.5和2.5之间的值可获得最佳结果。

所以我执行两次识别QR码的操作:一次像以前一样(获取高质量的图像),然后一次经过额外的处理(对于质量较低的图像)