寫在最前(這是對上一篇博文的問題做的更新【android利用zbar二維碼掃描】)
前天早上登陸CSDN時候一條消息:一網友提出了兩點疑惑
- 掃描框目前隻是做的假象,是全屏的圖檔進行解析
- 中文亂碼現象
各種查找,今天得以修複:及時共享給各位網友.
1.掃描框定義
/**
* 2014-7-15 上午11:14:21
* Created By niexiaoqiang
*/
package com.example.qu;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
/**
* 查找框
* @author niexiaoqiang
*/
public class FinderView extends View {
private static final long ANIMATION_DELAY = ;
private Paint finderMaskPaint;
private int measureedWidth;
private int measureedHeight;
public FinderView(Context context) {
super(context);
init(context);
}
public FinderView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(leftRect, finderMaskPaint);
canvas.drawRect(topRect, finderMaskPaint);
canvas.drawRect(rightRect, finderMaskPaint);
canvas.drawRect(bottomRect, finderMaskPaint);
//畫框
zx_code_kuang.setBounds(middleRect);
zx_code_kuang.draw(canvas);
if (lineRect.bottom < middleRect.bottom) {
zx_code_line.setBounds(lineRect);
lineRect.top = lineRect.top + lineHeight / ;
lineRect.bottom = lineRect.bottom + lineHeight / ;
} else {
lineRect.set(middleRect);
lineRect.bottom = lineRect.top + lineHeight;
zx_code_line.setBounds(lineRect);
}
zx_code_line.draw(canvas);
postInvalidateDelayed(ANIMATION_DELAY, middleRect.left, middleRect.top, middleRect.right, middleRect.bottom);
}
private Rect topRect = new Rect();
private Rect bottomRect = new Rect();
private Rect rightRect = new Rect();
private Rect leftRect = new Rect();
private Rect middleRect = new Rect();
private Rect lineRect = new Rect();
private Drawable zx_code_kuang;
private Drawable zx_code_line;
private int lineHeight;
private void init(Context context) {
int finder_mask = context.getResources().getColor(R.color.finder_mask);
finderMaskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
finderMaskPaint.setColor(finder_mask);
zx_code_kuang = context.getResources().getDrawable(R.drawable.zx_code_kuang);
zx_code_line = context.getResources().getDrawable(R.drawable.zx_code_line);
lineHeight = ;
}
//新增該方法//
/**
* 根據圖檔size求出矩形框在圖檔所在位置,tip:相機旋轉90度以後,拍攝的圖檔是橫着的,所有傳遞參數時,做了交換
* @param w
* @param h
* @return
*/
public Rect getScanImageRect(int w, int h) {
//先求出實際矩形
Rect rect = new Rect();
rect.left = middleRect.left;
rect.right = middleRect.right;
float temp = h / (float) measureedHeight;
rect.top = (int) (middleRect.top * temp);
rect.bottom = (int) (middleRect.bottom * temp);
return rect;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measureedWidth = MeasureSpec.getSize(widthMeasureSpec);
measureedHeight = MeasureSpec.getSize(heightMeasureSpec);
int borderWidth = measureedWidth / + ;
middleRect.set((measureedWidth - borderWidth) / , (measureedHeight - borderWidth) / , (measureedWidth - borderWidth) / + borderWidth, (measureedHeight - borderWidth) / + borderWidth);
lineRect.set(middleRect);
lineRect.bottom = lineRect.top + lineHeight;
leftRect.set(, middleRect.top, middleRect.left, middleRect.bottom);
topRect.set(, , measureedWidth, middleRect.top);
rightRect.set(middleRect.right, middleRect.top, measureedWidth, middleRect.bottom);
bottomRect.set(, middleRect.bottom, measureedWidth, measureedHeight);
}
}
2.掃描界面
package com.example.qu;
import net.sourceforge.zbar.Config;
import net.sourceforge.zbar.Image;
import net.sourceforge.zbar.ImageScanner;
import net.sourceforge.zbar.Symbol;
import net.sourceforge.zbar.SymbolSet;
import android.app.Activity;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.TextView;
public class MainActivity extends Activity implements SurfaceHolder.Callback {
private static String TAG = "xiaoqiang";
private Camera mCamera;
private SurfaceHolder mHolder;
private SurfaceView surface_view;
private ImageScanner scanner;
private Handler autoFocusHandler;
private AsyncDecode asyncDecode;
private FinderView finder_view;
private TextView textview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ac_zbar_finder);
init();
}
private void init() {
surface_view = (SurfaceView) findViewById(R.id.surface_view);
finder_view = (FinderView) findViewById(R.id.finder_view);
textview = (TextView) findViewById(R.id.textview);
mHolder = surface_view.getHolder();
mHolder.addCallback(this);
scanner = new ImageScanner();
scanner.setConfig(, Config.X_DENSITY, );
scanner.setConfig(, Config.Y_DENSITY, );
autoFocusHandler = new Handler();
asyncDecode = new AsyncDecode();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mHolder.getSurface() == null) {
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
}
try {
mCamera.setDisplayOrientation();
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallback(previewCallback);
mCamera.startPreview();
mCamera.autoFocus(autoFocusCallback);
} catch (Exception e) {
Log.d("DBG", "Error starting camera preview: " + e.getMessage());
}
}
/**
* 預覽資料
*/
PreviewCallback previewCallback = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
if (asyncDecode.isStoped()) {
// Camera.Parameters parameters = camera.getParameters();
// Size size = parameters.getPreviewSize();
// Image barcode = new Image(size.width, size.height, "Y800");
// barcode.setData(data);
// asyncDecode = new AsyncDecode();
// asyncDecode.execute(barcode);
Camera.Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
//圖檔是被旋轉了90度的
Image source = new Image(size.width, size.height, "Y800");
Rect scanImageRect = finder_view.getScanImageRect(size.height, size.width);
//圖檔旋轉了90度,将掃描框的TOP作為left裁剪
source.setCrop(scanImageRect.top, scanImageRect.left, scanImageRect.bottom, scanImageRect.right);
source.setData(data);
asyncDecode = new AsyncDecode();
asyncDecode.execute(source);
}
}
};
private class AsyncDecode extends AsyncTask<Image, Void, Void> {
private boolean stoped = true;
private String str = "";
@Override
protected Void doInBackground(Image... params) {
stoped = false;
StringBuilder sb = new StringBuilder();
Image barcode = params[];
int result = scanner.scanImage(barcode);
if (result != ) {
// mCamera.setPreviewCallback(null);
// mCamera.stopPreview();
SymbolSet syms = scanner.getResults();
for (Symbol sym : syms) {
switch (sym.getType()) {
case Symbol.CODABAR:
Log.d(TAG, "條形碼 " + sym.getData());
//條形碼
sb.append(sym.getData() + "\n");
break;
case Symbol.CODE128:
//128編碼格式二維碼
Log.d(TAG, "128編碼格式二維碼: " + sym.getData());
sb.append(sym.getData() + "\n");
break;
case Symbol.QRCODE:
//QR碼二維碼
Log.d(TAG, "QR碼二維碼 :" + sym.getData());
sb.append(sym.getData() + "\n");
break;
case Symbol.ISBN10:
//ISBN10圖書查詢
Log.d(TAG, "ISBN10圖書查詢 : " + sym.getData());
sb.append(sym.getData() + "\n");
break;
case Symbol.ISBN13:
//ISBN13圖書查詢
Log.d(TAG, "ISBN13圖書查詢 : " + sym.getData());
sb.append(sym.getData() + "\n");
break;
case Symbol.NONE:
Log.d(TAG, "未知 : " + sym.getData());
sb.append(sym.getData() + "\n");
break;
default:
Log.d(TAG, "其他: " + sym.getData());
sb.append(sym.getData() + "\n");
break;
}
}
}
str = sb.toString();
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
stoped = true;
if (null == str || str.equals("")) {
} else {
textview.setText(str);
}
}
public boolean isStoped() {
return stoped;
}
}
/**
* 自動對焦回調
*/
AutoFocusCallback autoFocusCallback = new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
autoFocusHandler.postDelayed(doAutoFocus, );
}
};
//自動對焦
private Runnable doAutoFocus = new Runnable() {
public void run() {
if (null == mCamera || null == autoFocusCallback) {
return;
}
mCamera.autoFocus(autoFocusCallback);
}
};
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera = Camera.open();
} catch (Exception e) {
mCamera = null;
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
3.布局定義
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.example.qu.FinderView
android:id="@+id/finder_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:gravity="center_vertical"
android:textColor="@color/rea" />
</FrameLayout>
一些資源檔案請下載下傳源碼,如果沒有積分可QQ聯系312122330
關于亂碼的解決
我重新使用NDK編譯了zbar的庫,并對zbarlib\jni\zbar\qrcode\qrdectxt.c做了如下修改
/*This is the encoding the standard says is the default.*/
/*********************************************/
/********* 修改此處以支援中文 **********/
/*********************************************/
//latin1_cd=iconv_open("UTF-8","ISO8859-1");
latin1_cd = iconv_open("UTF-8", "GB18030");
/*But this one is often used, as well.*/
//sjis_cd = iconv_open("UTF-8", "SJIS");
sjis_cd = iconv_open("UTF-8", "GB2312");
/*********************************************/
NDK編譯這塊兒有麻煩的朋友,估計就要好好學習下了。 東西太多,不好些博文
附代碼下載下傳: http://download.csdn.net/download/nie312122330/7747533
文章來原: http://www.itnose.net/detail/6083222.html