Java中使用ZXing库解码彩色图像 [英] Decoding colored image using ZXing library in Java

查看:52
本文介绍了Java中使用ZXing库解码彩色图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 ZXing 库解码 Java 中的彩色二维码.通过一些研究,我知道ZXing已经有能力做到这一点.但是我已经这样做了 2 天,我所做的是尝试从文件中读取 QR 图像并计算图像中最暗和最亮的颜色.然后将每个前景像素更改为黑色,将其他像素更改为白色.在此之后,我将获得一个与标准代码一样的二维码.然后使用函数读取二维码:

I am trying to decode a colored QR code in Java with ZXing library. From some research, I know that ZXing already has the ability to do this. But i have been doing this for 2 days and what i have done is trying to read a QR image from a file and calculating the darkest and brightest color in the image. Then change every foreground pixel to black and others to white. After this I will get a QR code just like the standard ones. Then use a function to read the QR code:

然而,这只适用于两种不同颜色的二维码,如果变成三种颜色,那么在大多数情况下它不会起作用.除非,从彩色图像转换为灰色图像的新图像不会超过纠错百分比.

However, this only works for QR code with two different colors, if it gets to three colors, then it won't work in the most case. Unless, the new image, which converted from color to gray image, wouldn't exceed the error correction percentage.

我也尝试过其他方法,但每种方法仅适用于特定类型的 QR 码(带有徽标、多色、异形 Finder 图案等).

And I had tried other methods but each method is working only for a specific kind of QR code (with logo, multi-colored, shaped Finder Patterns, etc.).

而我正在寻找的是一种解码各种二维码的方法.至少对于多色和形状的 Finder 图案.

And what I am looking for is a way to decode all kinds of QR code. At least for multi-colored and shaped Finder Patterns.

欲知更多详情:

1) 这是我用来解码 this 页面(第二个 QR),也用于解码在同一网站上发现的第三个 QR(在对齐模式上方带有某种标志的东西),这绝对不起作用:

1) This is the code I'm using to decode the Green QR on this page (second QR) and also used to decode the third QR (with a kind of logo thing above the alignment pattern) found on the same website which is definitely not working:

public class Decoder
{
  public static void main(String[] args)
  {
    // input image file
    File imageFile = new File("/Users/User/Desktop/QR/green.png");
    BufferedImage image = null;
    try
    {
      image = ImageIO.read(imageFile);
    }
    catch (IOException e)
    {
      System.out.println("io outch");
    }
    int imageWidth = image.getWidth();
    int imageHeight = image.getHeight();
    int total = 0;
    int dark = image.getRGB(0, 0);
    int light = image.getRGB(0, 0);
    int backgroundColor = 0;
    int foregroundColor = 0;
    FinderPattern topLeftFinder;
    for (int x = 0; x < imageWidth; x ++)
    {
      for (int y = 0; y <imageHeight; y ++)
      {
        total = total + image.getRGB(x, y);
      }
    }
    //int average = total / (imageWidth * imageHeight);
    //System.out.println("total" + total + " average " + average);
    for (int x = 0; x < imageWidth; x ++)
    {
      for (int y = 0; y <imageHeight; y ++)
      {
        if (image.getRGB(x, y) < dark)
        {
          dark = image.getRGB(x, y);
        }
        if (image.getRGB(x, y) > light)
        {
          light = image.getRGB(x, y);
        }
      }
    }
    for (int x = 0; x < imageWidth; x ++)
    {
      for (int y = 0; y <imageHeight; y ++)
      {
        if (image.getRGB(x, y) >= (dark - light) / 4)
        {
          image.setRGB(x, y, -1);
        }
        else if (image.getRGB(x, y) <= (dark - light) * 3 / 4)
        {
          image.setRGB(x, y, -16777216);
        }
        else
        {
          image.setRGB(x, y, -1);
        }
      }
    }
    System.out.println("total" + dark + " average " + light);
    File outputFile = new File("/Users/Desktop/QR/outputQR.png");
    //ImageIO.write(image, "png", file);
    try
    {
      ImageIO.write(image, "png", outputFile);
    }
    catch (IOException e)
    {
      System.out.println(e.getMessage());
    }
    // creating binary bitmap from source image
    LuminanceSource lumSource = new BufferedImageLuminanceSource(image);
    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(lumSource));
    Hashtable<DecodeHintType, Object> hint = new Hashtable<DecodeHintType, Object>();
    hint.put(DecodeHintType.TRY_HARDER, BarcodeFormat.QR_CODE);
    // decoding
    QRCodeReader QRreader = new QRCodeReader();
    Result result = null;
    try
    {
      result = QRreader.decode(bitmap, hint);
    }
    catch (ReaderException e)
    {
      System.out.println("error during reading");
    }
    // getting output text
    String decodedText = result.getText();
    System.out.println(decodedText);
  }
}

2) 这是用于解码这个二维码 最初工作正常,但不知道为什么现在不工作.而且这个代码不会解码上面提到的二维码.

2) And this is the code used for decoding this QR which is working fine originally but don't know why it's not working right now. And this code won't decode the QRs mentioned above.

public class Decoder
{
    public static void main(String[] args)
    {
        // input image file
        File imageFile = new File("/Users/User/Desktop/QR/bigfinderQR.png");
        BufferedImage image = null;
        try
        {
            image = ImageIO.read(imageFile);
        }
        catch (IOException e)
        {
            System.out.println("io outch");
        }
        // creating binary bitmap from source image
        LuminanceSource lumSource = new BufferedImageLuminanceSource(image);
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(lumSource));
        Hashtable<DecodeHintType, Object> hint = new Hashtable<DecodeHintType, Object>();
        hint.put(DecodeHintType.TRY_HARDER, BarcodeFormat.QR_CODE);
        // decoding
        QRCodeReader QRreader = new QRCodeReader();
        Result result = null;
        try
        {
            result = QRreader.decode(bitmap, hint);
        }
        catch (ReaderException e)
        {
            System.out.println("error during reading");
        }
        // getting output text
        String decodedText = result.getText();
        System.out.println(decodedText);
    }
}

推荐答案

它只是根据每个像素的计算亮度进行二值化.任何像暗对光这样合理的东西都应该没问题.一千种颜色就好了.如果它是明暗(反转),那么您确实需要反转图像或修改代码以反转图像.这几乎肯定不是问题.

It just binarizes based on the computed luminance of each pixel. Anything reasonably like dark-on-light should be fine. A thousand colors are fine. If it's light-on-dark (inverted), then you do need to invert the image or modify the code to invert the image. This is almost surely not the issue.

扭曲查找器模式是一件棘手的事情,因为这样更容易使其无效.您将需要保留几乎 1:1:3:1:1 的暗-明-暗-明-暗比率在水平和垂直方向上扫描图案.稍微圆润一下角落就可以了.例如,您不能在黑色模块之间放置空白.

Distorting finder patterns is a trickier business since it's easier to make it invalid this way. You will need to preserve pretty nearly the 1:1:3:1:1 dark-light-dark-light-dark ratios scanning across the pattern horizontally and vertically. Rounding the corners a bit is fine. You couldn't for example put white space between black modules.

您可以发布您要解码的原始图像吗?我可以很快告诉你什么是对什么是错.

Can you post the original image you're trying to decode? I could tell you very quickly what's right and wrong.

这篇关于Java中使用ZXing库解码彩色图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆