您的位置:首页 > 编程语言 > Go语言

二维码、条形码扫描——使用Google ZXing

2012-08-13 08:38 134 查看
我在项目中用到了二维码扫描的技术,用的是Google提供的ZXing开源项目,它提供二维码和条形码的扫描。扫描条形码就是直接读取条形码的内容,扫描二维码是按照自己指定的二维码格式进行编码和解码。

可以到http://code.google.com/p/zxing/下载ZXing项目的源码,然后按照官方文档进行开发,我这里使用的ZXing是经过简化版的,去除了一些一般使用不必要的文件,项目工程截图如下:



其中encoding包是我在它的基础上自己加上去的,功能是根据传入的字符串来生成二维码图片,返回一个Bitmap,其余的包是ZXing项目自带的。另外对扫描界面的布局我也进行了修改,官方的扫描界面是横向的,我改成了纵向的,并加入了顶部的Tab和取消按钮(camera.xml),另外还需要的一些文件是colors.xml、ids.xml,这些都是原本ZXing项目中自带的,最后就是libs下面的jar包。

先来看看最后的效果:

首先是根据输入的字符串生成二维码图片(左图),然后扫描二维码图片可以在界面上显示扫描结果(右图):





点击Open Camera按钮代开扫描框(左图),扫描条形码结果如下(右图):





接下来看如何使用,首先是把ZXing项目中的一些文件拷贝到我们自己的项目中,然后在Mainifest文件中进行配置权限:

[html] view
plaincopy

<uses-permission android:name="android.permission.VIBRATE" />

<uses-permission android:name="android.permission.CAMERA" />

<uses-feature android:name="android.hardware.camera" />

<uses-feature android:name="android.hardware.camera.autofocus" />

还有就是扫描界面Activity的配置:

[html] view
plaincopy

<activity

android:configChanges="orientation|keyboardHidden"

android:name="com.zxing.activity.CaptureActivity"

android:screenOrientation="portrait"

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

android:windowSoftInputMode="stateAlwaysHidden" >

</activity>

接下来是我自己项目的布局文件:

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="@android:color/white"

android:orientation="vertical" >

<Button

android:id="@+id/btn_scan_barcode"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_marginTop="30dp"

android:text="Open camera" />

<LinearLayout

android:orientation="horizontal"

android:layout_marginTop="10dp"

android:layout_width="fill_parent"

android:layout_height="wrap_content">

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textColor="@android:color/black"

android:textSize="18sp"

android:text="Scan result:" />

<TextView

android:id="@+id/tv_scan_result"

android:layout_width="fill_parent"

android:textSize="18sp"

android:textColor="@android:color/black"

android:layout_height="wrap_content" />

</LinearLayout>

<EditText

android:id="@+id/et_qr_string"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_marginTop="30dp"

android:hint="Input the text"/>

<Button

android:id="@+id/btn_add_qrcode"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Generate QRcode" />

<ImageView

android:id="@+id/iv_qr_image"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="10dp"

android:layout_gravity="center"/>

</LinearLayout>

下面是主Activity的代码,主要功能是打开扫描框、显示扫描结果、根据输入的字符串生成二维码图片:

[java] view
plaincopy

public class BarCodeTestActivity extends Activity {

/** Called when the activity is first created. */

private TextView resultTextView;

private EditText qrStrEditText;

private ImageView qrImgImageView;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

resultTextView = (TextView) this.findViewById(R.id.tv_scan_result);

qrStrEditText = (EditText) this.findViewById(R.id.et_qr_string);

qrImgImageView = (ImageView) this.findViewById(R.id.iv_qr_image);

Button scanBarCodeButton = (Button) this.findViewById(R.id.btn_scan_barcode);

scanBarCodeButton.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

//打开扫描界面扫描条形码或二维码

Intent openCameraIntent = new Intent(BarCodeTestActivity.this,CaptureActivity.class);

startActivityForResult(openCameraIntent, 0);

}

});

Button generateQRCodeButton = (Button) this.findViewById(R.id.btn_add_qrcode);

generateQRCodeButton.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

try {

String contentString = qrStrEditText.getText().toString();

if (!contentString.equals("")) {

//根据字符串生成二维码图片并显示在界面上,第二个参数为图片的大小(350*350)

Bitmap qrCodeBitmap = EncodingHandler.createQRCode(contentString, 350);

qrImgImageView.setImageBitmap(qrCodeBitmap);

}else {

Toast.makeText(BarCodeTestActivity.this, "Text can not be empty", Toast.LENGTH_SHORT).show();

}

} catch (WriterException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

});

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

//处理扫描结果(在界面上显示)

if (resultCode == RESULT_OK) {

Bundle bundle = data.getExtras();

String scanResult = bundle.getString("result");

resultTextView.setText(scanResult);

}

}

}

其中生成二维码图片的代码在EncodingHandler.java中:

[java] view
plaincopy

public final class EncodingHandler {

private static final int BLACK = 0xff000000;

public static Bitmap createQRCode(String str,int widthAndHeight) throws WriterException {

Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();

hints.put(EncodeHintType.CHARACTER_SET, "utf-8");

BitMatrix matrix = new MultiFormatWriter().encode(str,

BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);

int width = matrix.getWidth();

int height = matrix.getHeight();

int[] pixels = new int[width * height];

for (int y = 0; y < height; y++) {

for (int x = 0; x < width; x++) {

if (matrix.get(x, y)) {

pixels[y * width + x] = BLACK;

}

}

}

Bitmap bitmap = Bitmap.createBitmap(width, height,

Bitmap.Config.ARGB_8888);

bitmap.setPixels(pixels, 0, width, 0, 0, width, height);

return bitmap;

}

}

最后是在哪里对扫描结果进行解码,进入CaptureActivity.java找到下面这个方法便可以对自己对结果进行操作:

[java] view
plaincopy

/**

* Handler scan result

* @param result

* @param barcode

*/

public void handleDecode(Result result, Bitmap barcode) {

inactivityTimer.onActivity();

playBeepSoundAndVibrate();

String resultString = result.getText();

//FIXME

if (resultString.equals("")) {

Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show();

}else {

// System.out.println("Result:"+resultString);

Intent resultIntent = new Intent();

Bundle bundle = new Bundle();

bundle.putString("result", resultString);

resultIntent.putExtras(bundle);

this.setResult(RESULT_OK, resultIntent);

}

CaptureActivity.this.finish();

}

以上过程没有把每一步的详细步骤写出来,整体思路基本大致如上,源码下载:源码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: