为什么我的 ZXing 的 jpeg 二维码不是黑白的?

发布于 11-05 21:22 字数 2117 浏览 2 评论 0原文

我正在使用 ZXing 代码创建 QR 条形码。我从这里得到了示例代码: http://www.vineetmanohar.com /2010/09/java-barcode-api/ 并且 PNG 图像看起来不错,黑白如预期。

在示例代码注释中,它提到我可以使用 tiff 或 jpeg 格式,因此我将 imgeFormat 变量更改为 jpeg。创建了看起来正确的 QR 码图像,但不是黑白的,“白色”部分是桃色,“黑色”部分是蓝色。

我将 ZXing MatrixToImageWriter 代码剪切并粘贴到我的代码中并设置颜色,而不是使用 int BLACK = 0xFF000000;和 int WHITE = 0xFFFFFFFF;我发现通过用 0x00000000 替换 BLACK 变量,我的图像上出现黑色,但我一直无法找到 WHITE 变量的值来给我一个白色。

附件是奇怪的彩色 QR 条形码。 哎呀,我是个新手,无法附加图像。希望 imgur.com 的链接有效:https://i.sstatic.net/Rp3ii.jpg

这是Java代码:

package zxing_qr;

import java.io.File;
import java.io.FileOutputStream;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

// by passing MatrixToImageWriter call
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.Graphics2D;


public class Main {


public static void main(String[] args) {
    //String text = "98376373783"; // this is the text that we want to encode
    String text = "blahblahblah"; // this is the text that we want to encode

    int width = 400;
    int height = 300; // change the height and width as per your requirement

    // (ImageIO.getWriterFormatNames() returns a list of supported formats)
    String imageFormat = "jpg"; // could be "gif", "tiff", "jpeg"

    try {
        BitMatrix bitMatrix = new QRCodeWriter().encode(text, BarcodeFormat.QR_CODE,     width, height);
        MatrixToImageWriter.writeToStream(bitMatrix, imageFormat, new FileOutputStream(new File("qrcode_97802017507991.jpg")));             
    } catch (WriterException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
} // end main function
} // end main class

I'm using ZXing code to create QR bar codes. I got the example code from here working: http://www.vineetmanohar.com/2010/09/java-barcode-api/ and the PNG image looks good, black and white as expected.

In the example codes comments it mentions I could use tiff or jpeg format so I changed the imgeFormat variable to jpeg. A correct looking QR code image is created but instead of being black and white the "white" part is a peach color and the "black" part is a blue color.

I cut and past the ZXing MatrixToImageWriter code into my code and set the colors instead of using the int BLACK = 0xFF000000; and int WHITE = 0xFFFFFFFF; I found that by replacing the BLACK variable with with 0x00000000 I got black on my image, but I have been unable to find a value for the WHITE variable that give me a white.

Attached is the odd colored QR barcode. Oops, I'm too new of a user to attach an image. Hopefully this link to imgur.com works: https://i.sstatic.net/Rp3ii.jpg

Here is the Java code:

package zxing_qr;

import java.io.File;
import java.io.FileOutputStream;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

// by passing MatrixToImageWriter call
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.Graphics2D;


public class Main {


public static void main(String[] args) {
    //String text = "98376373783"; // this is the text that we want to encode
    String text = "blahblahblah"; // this is the text that we want to encode

    int width = 400;
    int height = 300; // change the height and width as per your requirement

    // (ImageIO.getWriterFormatNames() returns a list of supported formats)
    String imageFormat = "jpg"; // could be "gif", "tiff", "jpeg"

    try {
        BitMatrix bitMatrix = new QRCodeWriter().encode(text, BarcodeFormat.QR_CODE,     width, height);
        MatrixToImageWriter.writeToStream(bitMatrix, imageFormat, new FileOutputStream(new File("qrcode_97802017507991.jpg")));             
    } catch (WriterException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
} // end main function
} // end main class

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凉城已无爱2024-11-12 21:22:01

我偶然发现了答案。在 ZXing 类 MatrixToImageWriter 中,使用 BufferedImage.TYPE_INT_ARGB 作为第三个参数创建 BufferedImage 对象。通过将其更改为 BufferedImage.TYPE_INT_RGB,jpeg 的颜色将按预期变为黑色和白色。

I have stumbled upon the answer. Inside the ZXing class MatrixToImageWriter a BufferedImage object is created with BufferedImage.TYPE_INT_ARGB as the 3rd argument. By changing this to BufferedImage.TYPE_INT_RGB the colors for jpeg are turning out black and white as expected.

霞映澄塘2024-11-12 21:22:01

您还可以以编程方式将图像像素转换为 RGB,而不是破解 ZXing 类:

      ...
        final BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(matrix);
        final BufferedImage rgbImage = convertARGBtoRGB(bufferedImage);
      ...

  private static BufferedImage convertARGBtoRGB(final BufferedImage argb) {
    assert argb.getType() == BufferedImage.TYPE_INT_ARGB;
    final int width = argb.getWidth();
    final int height = argb.getHeight();
    final BufferedImage rgbImage= new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    for (int x = 0; x < width; x++) {
      for (int y = 0; y < height; y++) {
        rgbImage.setRGB(x, y, argb.getRGB(x, y));
      }
    }
    return rgbImage;
  }

Instead of hacking ZXing classes you may also programmatically convert the image pixels to RGB:

      ...
        final BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(matrix);
        final BufferedImage rgbImage = convertARGBtoRGB(bufferedImage);
      ...

  private static BufferedImage convertARGBtoRGB(final BufferedImage argb) {
    assert argb.getType() == BufferedImage.TYPE_INT_ARGB;
    final int width = argb.getWidth();
    final int height = argb.getHeight();
    final BufferedImage rgbImage= new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    for (int x = 0; x < width; x++) {
      for (int y = 0; y < height; y++) {
        rgbImage.setRGB(x, y, argb.getRGB(x, y));
      }
    }
    return rgbImage;
  }
山有枢2024-11-12 21:22:01

或者您可以自己进行从 BitMatrix 到缓冲图像的转换,

private static BufferedImage drawCodeOnImage(BitMatrix bitMatrix) {

    if (bitMatrix == null) {
        throw new IllegalArgumentException("BitMatrix cannot be null");
    }

    int width = bitMatrix.getWidth();
    int height = bitMatrix.getHeight();

    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED);
    image.createGraphics();

    Graphics2D graphics = (Graphics2D) image.getGraphics();
    graphics.setColor(Color.WHITE);
    graphics.fillRect(0, 0, width, height);
    graphics.setColor(Color.BLACK);

    for (int i = 0; i < width; i++) {
        for (int j = 0; j < height; j++) {
            if (bitMatrix.get(i, j)) {
                graphics.fillRect(i, j, 1, 1);
            }
        }
    }

    return image;
}

我使用了 BufferedImage.TYPE_BYTE_INDEXED ,因为使用 GIF 格式,写入 OutputStream 的速度更快。

定义为 0x00.. 的颜色是透明的,定义为 0xFF... 的颜色是不透明的,根据 Android 颜色。这些颜色已在通话中用作

MatrixToImageWriter.writeToStream(bitMatrix, imageFormat, new FileOutputStream(new File("qrcode_97802017507991.jpg")));

默认配置。

Or you can make your own conversion from BitMatrix to buffered image

private static BufferedImage drawCodeOnImage(BitMatrix bitMatrix) {

    if (bitMatrix == null) {
        throw new IllegalArgumentException("BitMatrix cannot be null");
    }

    int width = bitMatrix.getWidth();
    int height = bitMatrix.getHeight();

    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED);
    image.createGraphics();

    Graphics2D graphics = (Graphics2D) image.getGraphics();
    graphics.setColor(Color.WHITE);
    graphics.fillRect(0, 0, width, height);
    graphics.setColor(Color.BLACK);

    for (int i = 0; i < width; i++) {
        for (int j = 0; j < height; j++) {
            if (bitMatrix.get(i, j)) {
                graphics.fillRect(i, j, 1, 1);
            }
        }
    }

    return image;
}

I used BufferedImage.TYPE_BYTE_INDEXED because with GIF format it is faster to write to OutputStream.

The color defined as 0x00.. is transparent, the color defined as 0xFF... is opaque acording to Android colors. These colors are used already in the call

MatrixToImageWriter.writeToStream(bitMatrix, imageFormat, new FileOutputStream(new File("qrcode_97802017507991.jpg")));

as the default configuration.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文