QRコードは、コードとzxingを用いて復号化
質問
さて、私はここで誰かが前にzxing使用されたことをオフのチャンスを取るつもりですので。私は、Javaアプリケーションを開発していて、それを行うために必要なものの一つは、QRコードへのデータのバイト配列エンコードされ、その後、後でそれをデコードします。
はここで何を私のエンコーダルックスのような例です
byte[] b = {0x48, 0x45, 0x4C, 0x4C, 0x4F};
//convert the byte array into a UTF-8 string
String data;
try {
data = new String(b, "UTF8");
}
catch (UnsupportedEncodingException e) {
//the program shouldn't be able to get here
return;
}
//get a byte matrix for the data
ByteMatrix matrix;
com.google.zxing.Writer writer = new QRCodeWriter();
try {
matrix = writer.encode(data, com.google.zxing.BarcodeFormat.QR_CODE, width, height);
}
catch (com.google.zxing.WriterException e) {
//exit the method
return;
}
//generate an image from the byte matrix
int width = matrix.getWidth();
int height = matrix.getHeight();
byte[][] array = matrix.getArray();
//create buffered image to draw to
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//iterate through the matrix and draw the pixels to the image
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int grayValue = array[y][x] & 0xff;
image.setRGB(x, y, (grayValue == 0 ? 0 : 0xFFFFFF));
}
}
//write the image to the output stream
ImageIO.write(image, "png", outputStream);
このコードで始まるバイト配列はちょうどそれをテストするために使用されます。実際のバイトデータを変化させることになります。
ここに何のように私のデコーダルックスます:
//get the data from the input stream
BufferedImage image = ImageIO.read(inputStream);
//convert the image to a binary bitmap source
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
//decode the barcode
QRCodeReader reader = new QRCodeReader();
Result result;
try {
result = reader.decode(bitmap, hints);
} catch (ReaderException e) {
//the data is improperly formatted
throw new MCCDatabaseMismatchException();
}
byte[] b = result.getRawBytes();
System.out.println(ByteHelper.convertUnsignedBytesToHexString(result.getText().getBytes("UTF8")));
System.out.println(ByteHelper.convertUnsignedBytesToHexString(b));
convertUnsignedBytesToHexString(byte)
16進文字列のバイト配列を変換する方法である。
は、これが出力されます:
48454c4c4f
202b0b78cc00ec11ec11ec11ec11ec11ec11ec
は明らかに、テキストは、符号化されているが、データの実際のバイトが完全にオフです。すべてのヘルプはここでいただければ幸いです。
解決
ですから、あなたはQRコードにバイト配列をエンコードする際に、このアウトを理解するためにインターネットを検索する2日間過ごすことを望んでいない誰のための将来の参考のために、あなたはISO-8859-1
characterセット、ないUTF-8
を使用する必要があります。
他のヒント
これはエンコードQRコードにJavaコード私の実施例であるUTF-8エンコーディングでZXing使用して、してください注記:あなたのパスと言語の文字にパスし、UTF8のデータを変更する必要があります。
package com.mypackage.qr;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Hashtable;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.*;
public class CreateQR {
public static void main(String[] args)
{
Charset charset = Charset.forName("UTF-8");
CharsetEncoder encoder = charset.newEncoder();
byte[] b = null;
try {
// Convert a string to UTF-8 bytes in a ByteBuffer
ByteBuffer bbuf = encoder.encode(CharBuffer.wrap("utf 8 characters - i used hebrew, but you should write some of your own language characters"));
b = bbuf.array();
} catch (CharacterCodingException e) {
System.out.println(e.getMessage());
}
String data;
try {
data = new String(b, "UTF-8");
// get a byte matrix for the data
BitMatrix matrix = null;
int h = 100;
int w = 100;
com.google.zxing.Writer writer = new MultiFormatWriter();
try {
Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>(2);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
matrix = writer.encode(data,
com.google.zxing.BarcodeFormat.QR_CODE, w, h, hints);
} catch (com.google.zxing.WriterException e) {
System.out.println(e.getMessage());
}
// change this path to match yours (this is my mac home folder, you can use: c:\\qr_png.png if you are on windows)
String filePath = "/Users/shaybc/Desktop/OutlookQR/qr_png.png";
File file = new File(filePath);
try {
MatrixToImageWriter.writeToFile(matrix, "PNG", file);
System.out.println("printing to " + file.getAbsolutePath());
} catch (IOException e) {
System.out.println(e.getMessage());
}
} catch (UnsupportedEncodingException e) {
System.out.println(e.getMessage());
}
}
}
何それの価値については、私のグルーヴィーなスパイクは、UTF-8とISO-8859-1文字エンコーディングの両方で動作するようです。わからない非zxingデコーダはかかわらUTF-8エンコードされた画像をデコードしようとすると何が起こるのだろう...おそらく、デバイスによって異なります。
// ------------------------------------------------------------------------------------
// Requires: groovy-1.7.6, jdk1.6.0_03, ./lib with zxing core-1.7.jar, javase-1.7.jar
// Javadocs: http://zxing.org/w/docs/javadoc/overview-summary.html
// Run with: groovy -cp "./lib/*" zxing.groovy
// ------------------------------------------------------------------------------------
import com.google.zxing.*
import com.google.zxing.common.*
import com.google.zxing.client.j2se.*
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
def class zxing {
def static main(def args) {
def filename = "./qrcode.png"
def data = "This is a test to see if I can encode and decode this data..."
def charset = "UTF-8" //"ISO-8859-1"
def hints = new Hashtable<EncodeHintType, String>([(EncodeHintType.CHARACTER_SET): charset])
writeQrCode(filename, data, charset, hints, 100, 100)
assert data == readQrCode(filename, charset, hints)
}
def static writeQrCode(def filename, def data, def charset, def hints, def width, def height) {
BitMatrix matrix = new MultiFormatWriter().encode(new String(data.getBytes(charset), charset), BarcodeFormat.QR_CODE, width, height, hints)
MatrixToImageWriter.writeToFile(matrix, filename.substring(filename.lastIndexOf('.')+1), new File(filename))
}
def static readQrCode(def filename, def charset, def hints) {
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(ImageIO.read(new FileInputStream(filename)))))
Result result = new MultiFormatReader().decode(binaryBitmap, hints)
result.getText()
}
}
、構文の種類:
// if using special characters don't forget to supply the encoding
VCard johnSpecial = new VCard("Jöhn Dɵe")
.setAdress("ëåäöƞ Sträät 1, 1234 Döestüwn");
QRCode.from(johnSpecial).withCharset("UTF-8").file();
あなたが本当にエンコードUTF-8に必要がある場合は、Unicodeのバイト順マークを付加してみてください。私は、このメソッドのサポートがどれほど広範囲にないアイデアを持っていませんが、ZXingは、少なくともそれをサポートするために表示されます。 http://code.google.com/p/zxing/issues/詳細?ID = 103 の
私は最近、QRモード上に読んでいる、と私のだと思う。の私は、同じ練習は別の場所で述べたように、私いませんでしたfoggiestところます。
を見てきました私は、ISO-8859-1を使用してみました。すべてのエンコーディングで[OK]を行ってきましたが、私は[]デコードに結果の文字列を使用してバイトを取得しようとしたとき、すべての負のバイトが文字63(疑問符)となりました。次のコードは動作しません。
// Encoding works great
byte[] contents = new byte[]{-1};
QRCodeWriter codeWriter = new QRCodeWriter();
BitMatrix bitMatrix = codeWriter.encode(new String(contents, Charset.forName("ISO-8859-1")), BarcodeFormat.QR_CODE, w, h);
// Decodes like this fails
LuminanceSource ls = new BufferedImageLuminanceSource(encodedBufferedImage);
Result result = new QRCodeReader().decode(new BinaryBitmap( new HybridBinarizer(ls)));
byte[] resultBytes = result.getText().getBytes(Charset.forName("ISO-8859-1")); // a byte[] with byte 63 is given
return resultBytes;
非常に古いバージョンではAPIが(正確に知っていない)ので、それはうまく機能タールの方法を持っていたので、奇妙に見えます:
Vector byteSegments = result.getByteSegments();
だから私はこの方法を除去し、メタデータを介し、ByteSegmentsを取得する方法があることを実現した理由を検索してみました。
:のように私のデコード方法のルックスので、// Decodes like this works perfectly
LuminanceSource ls = new BufferedImageLuminanceSource(encodedBufferedImage);
Result result = new QRCodeReader().decode(new BinaryBitmap( new HybridBinarizer(ls)));
Vector byteSegments = (Vector) result.getResultMetadata().get(ResultMetadataType.BYTE_SEGMENTS);
int i = 0;
int tam = 0;
for (Object o : byteSegments) {
byte[] bs = (byte[])o;
tam += bs.length;
}
byte[] resultBytes = new byte[tam];
i = 0;
for (Object o : byteSegments) {
byte[] bs = (byte[])o;
for (byte b : bs) {
resultBytes[i++] = b;
}
}
return resultBytes;