Encodeing QRCode

1,277 views
Skip to first unread message

Nicolai

unread,
Mar 12, 2009, 4:26:10 AM3/12/09
to zxing
Hey

I'm trying to use the lib for encoding. The resulting image "looks"
correct, but isn't.

When I try to decode the resulting img, no QRcode can be found in the
image. I have try using Zxing and a lot of different other tools for
the decode, none can find a QRCode in the image...

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import com.google.zxing.WriterException;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.google.zxing.qrcode.encoder.Encoder;
import com.google.zxing.qrcode.encoder.QRCode;

public class TestEncode {

public static void main(String[] args) {

//Encode the text
QRCode qrcode = new QRCode();
try {
Encoder.encode("test", ErrorCorrectionLevel.H, qrcode);
} catch (WriterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int magnify = 100; //The resolution of the QRCode
byte[][] matrix = qrcode.getMatrix().getArray();
int size = qrcode.getMatrixWidth()*magnify;

//Make the BufferedImage that are to hold the QRCode
BufferedImage im = new BufferedImage
(size,size,BufferedImage.TYPE_INT_RGB);
im.createGraphics();
Graphics2D g = (Graphics2D)im.getGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, size*magnify, size*magnify);

//paint the image using the ByteMatrik
for(int h = 0;h<qrcode.getMatrixWidth();h++){
for(int w = 0;w<qrcode.getMatrixWidth();w++){
//Find the colour of the dot
if(matrix[h][w] == 0)
g.setColor(Color.WHITE);
else
g.setColor(Color.BLACK);

//Paint the dot
g.fillRect(h*magnify, w*magnify, magnify, magnify);
}
}

//Write the image to a file
try {
ImageIO.write(im, "png", new File("testimg.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

Nicolai

unread,
Mar 12, 2009, 6:49:16 AM3/12/09
to zxing
I've add the building of a BitMatrix, that I try to decode. The
decoding of the bitmatrix is success full, this indicate that, it is
the image it self that have errors? But how can this be, as the image
is a one2one representation of the BitMatrix when magnify is set to 1

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import com.google.zxing.ReaderException;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.DecoderResult;
import com.google.zxing.qrcode.decoder.Decoder;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.google.zxing.qrcode.encoder.Encoder;
import com.google.zxing.qrcode.encoder.QRCode;

public class TestEncode {

public static void main(String[] args) throws Exception {
String str = "test";
//Encode the text
QRCode qrcode = new QRCode();
try {
Encoder.encode(str, ErrorCorrectionLevel.H, qrcode);
} catch (WriterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int magnify = 1; //The resolution of the QRCode
byte[][] matrix = qrcode.getMatrix().getArray();
int size = qrcode.getMatrixWidth()*magnify;

//Make the BufferedImage that are to hold the QRCode
BufferedImage im = new BufferedImage
(size,size,BufferedImage.TYPE_INT_RGB);
im.createGraphics();
Graphics2D g = (Graphics2D)im.getGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, size, size);

//BitMatrix for validation
BitMatrix bm = new BitMatrix(qrcode.getMatrixWidth());

//paint the image using the ByteMatrik
for(int h = 0;h<qrcode.getMatrixWidth();h++){
for(int w = 0;w<qrcode.getMatrixWidth();w++){
//Find the colour of the dot
if(matrix[h][w] == 0)
g.setColor(Color.WHITE);
else{
g.setColor(Color.BLACK);
bm.set(h, w);//build the BitMatrix
}

//Paint the dot
g.fillRect(h*magnify, w*magnify, magnify, magnify);
}
}

//Try to decode the BitMatrix
Decoder decoder = new Decoder();
DecoderResult result = null;
try {
result = decoder.decode(bm);
} catch (ReaderException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

//Compare the decoded BitMatrix with the input string
if(!result.getText().equals(str))
throw new Exception("Error encodeing the QRCode");

Nicolai

unread,
Mar 12, 2009, 9:52:22 AM3/12/09
to zxing
fixed, I switched around the coordinates of the matrix

Tung Tran

unread,
Mar 19, 2009, 11:05:15 PM3/19/09
to zxing
I didn't know Zxing has an encoding module, which is great news. I
used to have to call Google Chart api for this purpose. I took the
liberty of enhancing Nicolai's code to create a more complete encoding
function. For those who are interested the function is below. Feel
free to use, modify and/or give feedback.

The generated code contains "the quiet zone" as described in QR code
spec (at least 4 modules on each size)

-------------------------------------------------
private static void generateQRCodeImage(OutputStream outputStream,
String code, int width, int height) throws Exception {

if (code == null || code.length() == 0)
throw new Exception("Code unspecified");

if (width <= 0 || height <= 0)
throw new Exception("Invalid width: " + width + " or height " +
height);

if (width != height)
throw new BarcodeException("width " + width + " and height " +
height + " are not the same");

QRCode qrcode = new QRCode();
Encoder.encode(code, ErrorCorrectionLevel.L, qrcode);
int qrSize = qrcode.getMatrixWidth();

int margin = 4;
int imageSize = qrSize + 2 * margin; // includes quiet zone
if (width < imageSize) width = imageSize;
int magnify = width / imageSize;
int remaining = width % imageSize;
int topLeftPosition = ((remaining > 0) ? remaining / 2 : magnify) +
margin * magnify;
int size = width;

// Make the BufferedImage that are to hold the QRCode
BufferedImage image = new BufferedImage(size, size,
BufferedImage.TYPE_INT_RGB);
image.createGraphics();
Graphics2D graphics = (Graphics2D) image.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, size, size);

// paint the image using the ByteMatrix
graphics.setColor(Color.BLACK);
for (int i = 0; i < qrSize; i ++) {
for (int j = 0; j < qrSize; j ++) {
if (qrcode.at(i, j) == 1)
graphics.fillRect(topLeftPosition + i * magnify, topLeftPosition
+ j * magnify, magnify, magnify);
}
}

ImageIO.write(image, "png", outputStream);
}

gianl.g...@gmail.com

unread,
Apr 18, 2009, 5:24:28 AM4/18/09
to zxing
sorry could you rewrite the code with the fixed coordinates?? thanks
Reply all
Reply to author
Forward
0 new messages