2011-05-09 67 views
4

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

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

我切和过去的斑马线MatrixToImageWriter代码到我的代码,并设置颜色,而不是使用INT BLACK = 0xFF000000;和INT WHITE = 0xFFFFFFFF;我发现通过用0x00000000代替BLACK变量,我在图像上变黑了,但是我一直无法找到白色变量的值。

附件是奇彩色QR条码。 哎呀,我太新了一个用户附加图像。希望此链接imgur.com工作:http://imgur.com/QnNXO

下面是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 

回答

3

我已经得到答案时偶然发现。在ZXing类MatrixToImageWriter中,使用BufferedImage.TYPE_INT_ARGB作为第三个参数创建一个BufferedImage对象。通过将其更改为BufferedImage.TYPE_INT_RGB,jpeg的颜色如预期的那样变成黑色和白色。

+0

开发人员在这里。很高兴你找到了答案,但是,这对我没有意义。四字节值是一个ARGB值。这就是为什么第一个字节,即alpha(不透明度)必须是FF。这在我见过的任何其他平台上都不会发生,所以我想知道您的Java实现有什么奇怪的地方吗?不知道... – 2011-05-11 17:04:57

+0

感谢您的评论肖恩。我对此很少有经验,所以我不确定要怎么看待才能更好地理解问题。现在我的解决方案正在为我工​​作。 如果你不在乎我在Windows XP上使用NetBeans 6.9.1。与Java 1.6.0_24。对于ZXing,我使用了core-1.6-SNAPSHOT.jar和javase-1.6-SNAPSHOT.jar。我在Firefox 3.6.17,Gimp和Windows图片和传真浏览器中查看了JPG。 – Pengo 2011-05-27 20:51:00

0

而是黑客斑马线类,您还可以通过编程将图像的像素转换为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; 
    } 
0

或者你可以从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的颜色...是不透明acording到Android colors。这些颜色已用于呼叫

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

作为默认配置。