13.zxing二维码的扫描
----------------------------------------------新浪微盘3
1.ZXingDemoChange(竖屏)-----------------------------现在已经不用
(1)使用布局------默认是竖屏,图片竖直放
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2008 ZXing authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<SurfaceView
android:id="@+id/preview_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:layout_gravity="center" />
<!-- -->
<com.zijunlin.Zxing.Demo.view.ViewfinderView
android:id="@+id/viewfinder_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/transparent" />
<TextView
android:id="@+id/txtResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp" />
<RelativeLayout
android:layout_width="48dp"
android:layout_height="fill_parent"
android:background="@drawable/bg_status_lan"
android:gravity="center_horizontal" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@drawable/selector_btn_back_lan"
android:onClick="btn_back" />
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/iv_scan_title" />
</RelativeLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="right"
android:layout_marginRight="60dp"
android:src="@drawable/iv_scan_note" />
</FrameLayout>
(2)ViewfinderView----------------改变四角,改变红线
package com.zijunlin.Zxing.Demo.view;
import com.google.zxing.ResultPoint;
import com.zijunlin.Zxing.DemoChange.R;
import com.zijunlin.Zxing.Demo.camera.CameraManager;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.View;
import java.util.Collection;
import java.util.HashSet;
/**
* This view is overlaid on top of the camera preview. It adds the viewfinder rectangle and partial
* transparency outside it, as well as the laser scanner animation and result points.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
public final class ViewfinderView extends View {
private static final int[] SCANNER_ALPHA = { 0, 64, 128, 192, 255, 192, 128, 64 };
private static final long ANIMATION_DELAY = 100L;
private static final int OPAQUE = 0xFF;
private final Paint paint;
private Bitmap resultBitmap;
private final int maskColor;
private final int resultColor;
private final int frameColor;
private final int frameColorChange;
private final int laserColor;
private final int resultPointColor;
private int scannerAlpha;
private Collection<ResultPoint> possibleResultPoints;
private Collection<ResultPoint> lastPossibleResultPoints;
// This constructor is used when the class is built from an XML resource.
public ViewfinderView(Context context, AttributeSet attrs) {
super(context, attrs);
// Initialize these once for performance rather than calling them every time in onDraw().
paint = new Paint();
Resources resources = getResources();
maskColor = resources.getColor(R.color.viewfinder_mask);
resultColor = resources.getColor(R.color.result_view);
frameColor = resources.getColor(R.color.viewfinder_frame);
frameColorChange = resources.getColor(R.color.viewfinder_frame_change);
laserColor = resources.getColor(R.color.viewfinder_laser);
resultPointColor = resources.getColor(R.color.possible_result_points);
scannerAlpha = 0;
possibleResultPoints = new HashSet<ResultPoint>(5);
}
@Override
public void onDraw(Canvas canvas) {
Rect frame = CameraManager.get().getFramingRect();
if (frame == null) {
return;
}
int width = canvas.getWidth();
int height = canvas.getHeight();
// Draw the exterior (i.e. outside the framing rect) darkened
// 绘制外貌
paint.setColor(resultBitmap != null ? resultColor : maskColor);
canvas.drawRect(0, 0, width, frame.top, paint);
canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);
canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);
canvas.drawRect(0, frame.bottom + 1, width, height, paint);
if (resultBitmap != null) {
// Draw the opaque result bitmap over the scanning rectangle
paint.setAlpha(OPAQUE);
canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint);
} else {
// Draw a two pixel solid black border inside the framing rect
// 画边框(默认)
/*
paint.setColor(frameColor);
canvas.drawRect(frame.left, frame.top, frame.right + 1, frame.top + 2, paint);
canvas.drawRect(frame.left, frame.top + 2, frame.left + 2, frame.bottom - 1, paint);
canvas.drawRect(frame.right - 1, frame.top, frame.right + 1, frame.bottom - 1, paint);
canvas.drawRect(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1, paint);
*/
// 画边框
paint.setColor(frameColorChange);
paint.setStyle(Style.FILL);
int rectHeight = getResources().getDimensionPixelSize(R.dimen.rect_height);
int rectWidth = getResources().getDimensionPixelSize(R.dimen.rect_width);
// 上左
canvas.drawRect(frame.left - rectHeight, frame.top - rectHeight, frame.left + rectWidth, frame.top, paint);
// 上右
canvas.drawRect(frame.right - rectWidth, frame.top - rectHeight, frame.right + rectHeight, frame.top, paint);
// 右上
canvas.drawRect(frame.right, frame.top - rectHeight, frame.right + rectHeight, frame.top + rectWidth, paint);
// 右下
canvas.drawRect(frame.right, frame.bottom - rectWidth, frame.right + rectHeight, frame.bottom + rectHeight, paint);
// 下右
canvas.drawRect(frame.right - rectWidth, frame.bottom, frame.right + rectHeight, frame.bottom + rectHeight, paint);
// 下左
canvas.drawRect(frame.left - rectHeight, frame.bottom, frame.left + rectWidth, frame.bottom + rectHeight, paint);
// 左下
canvas.drawRect(frame.left - rectHeight, frame.bottom - rectWidth, frame.left, frame.bottom + rectHeight, paint);
// 左上
canvas.drawRect(frame.left - rectHeight, frame.top - rectHeight, frame.left, frame.top + rectWidth, paint);
// Draw a red "laser scanner" line through the middle to show decoding is active
// 中间的红线
paint.setColor(laserColor);
paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
//横着的线(默认)
/* int middle = frame.height() / 2 + frame.top;
canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);
Draw a two pixel solid black border inside the framing rect*/
//竖着的线
int middle = frame.width() / 2 + frame.left;
canvas.drawRect(middle - 2, frame.top - 1, middle + 2, frame.bottom - 1, paint);
Collection<ResultPoint> currentPossible = possibleResultPoints;
Collection<ResultPoint> currentLast = lastPossibleResultPoints;
if (currentPossible.isEmpty()) {
lastPossibleResultPoints = null;
} else {
possibleResultPoints = new HashSet<ResultPoint>(5);
lastPossibleResultPoints = currentPossible;
paint.setAlpha(OPAQUE);
paint.setColor(resultPointColor);
for (ResultPoint point : currentPossible) {
canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 6.0f, paint);
}
}
if (currentLast != null) {
paint.setAlpha(OPAQUE / 2);
paint.setColor(resultPointColor);
for (ResultPoint point : currentLast) {
canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 3.0f, paint);
}
}
// Request another update at the animation interval, but only repaint the laser line,
// not the entire viewfinder mask.
postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top, frame.right, frame.bottom);
}
}
public void drawViewfinder() {
resultBitmap = null;
invalidate();
}
/**
* Draw a bitmap with the result points highlighted instead of the live scanning display.
*
* @param barcode An image of the decoded barcode.
*/
public void drawResultBitmap(Bitmap barcode) {
resultBitmap = barcode;
invalidate();
}
public void addPossibleResultPoint(ResultPoint point) {
possibleResultPoints.add(point);
}
}
(3)详情见demo
(4).二维码历史性的东西
使用zxing包,qrcode
(5).二维码的精简
以前很长一段时间.关于zxing包的精简是比较火.
(6).二维码横竖屏切换
图片横着切
2.二维码动画-------仿微信扫描效果
(1).zxingDemoNew(竖排,扫描动画,不变形)
(2)ViewfinderView
public final class ViewfinderView extends View {
private static final String TAG = "log";
/**
* 刷新界面的时间
*/
private static final long ANIMATION_DELAY = 10L;
private static final int OPAQUE = 0xFF;
/**
* 画笔对象的引用
*/
private Paint paint;
/**
* 将扫描的二维码拍下来,这里没有这个功能,暂时不考虑
*/
private Bitmap resultBitmap;
private final int maskColor;
private final int resultColor;
private final int resultPointColor;
private Collection<ResultPoint> possibleResultPoints;
private Collection<ResultPoint> lastPossibleResultPoints;
public ViewfinderView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
Resources resources = getResources();
maskColor = resources.getColor(R.color.viewfinder_mask);
resultColor = resources.getColor(R.color.result_view);
resultPointColor = resources.getColor(R.color.possible_result_points);
possibleResultPoints = new HashSet<ResultPoint>(5);
}
@Override
public void onDraw(Canvas canvas) {
// 中间的扫描框,你要修改扫描框的大小,去CameraManager里面修改
Rect frame = CameraManager.get().getFramingRect();
if (frame == null) {
return;
}
// 获取屏幕的宽和高
int width = canvas.getWidth();
int height = canvas.getHeight();
paint.setColor(resultBitmap != null ? resultColor : maskColor);
// 画出扫描框外面的阴影部分,共四个部分,扫描框的上面到屏幕上面,扫描框的下面到屏幕下面
// 扫描框的左边面到屏幕左边,扫描框的右边到屏幕右边
canvas.drawRect(0, 0, width, frame.top, paint);
canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);
canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);
canvas.drawRect(0, frame.bottom + 1, width, height, paint);
if (resultBitmap != null) {
// Draw the opaque result bitmap over the scanning rectangle
paint.setAlpha(OPAQUE);
canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint);
} else {
Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.scan_4);
int mBitmapWidth = mBitmap.getWidth();
/* 画四个角 */
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.scan_1), frame.left, frame.top, paint);// 左上边
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.scan_2), frame.right - mBitmapWidth, frame.top, paint);// 右上边
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.scan_3), frame.left, frame.bottom - mBitmapWidth, paint);// 左下边
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.scan_4), frame.right - mBitmapWidth, frame.bottom
- mBitmapWidth, paint);// 右下边
Collection<ResultPoint> currentPossible = possibleResultPoints;
Collection<ResultPoint> currentLast = lastPossibleResultPoints;
if (currentPossible.isEmpty()) {
lastPossibleResultPoints = null;
} else {
possibleResultPoints = new HashSet<ResultPoint>(5);
lastPossibleResultPoints = currentPossible;
paint.setAlpha(OPAQUE);
paint.setColor(resultPointColor);
for (ResultPoint point : currentPossible) {
canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 6.0f, paint);
}
}
if (currentLast != null) {
paint.setAlpha(OPAQUE / 2);
paint.setColor(resultPointColor);
for (ResultPoint point : currentLast) {
canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 3.0f, paint);
}
}
// 只刷新扫描框的内容,其他地方不刷新
postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top, frame.right, frame.bottom);
}
}
public void drawViewfinder() {
resultBitmap = null;
invalidate();
}
/**
* Draw a bitmap with the result points highlighted instead of the live
* scanning display.
*
* @param barcode
* An image of the decoded barcode.
*/
public void drawResultBitmap(Bitmap barcode) {
resultBitmap = barcode;
invalidate();
}
public void addPossibleResultPoint(ResultPoint point) {
possibleResultPoints.add(point);
}
}
3.ZXingCodeLibs---------含闪光灯
(1)lib中
/**
* 在handleDecode获取扫描结果
* @author Kevin
*
*/
public final class CaptureActivity extends Activity implements
SurfaceHolder.Callback {
private static final String TAG = CaptureActivity.class.getSimpleName();
private CameraManager cameraManager;
private CaptureActivityHandler handler;
private Result savedResultToShow;
private ViewfinderView viewfinderView;
private boolean hasSurface;
private Collection<BarcodeFormat> decodeFormats;
private InactivityTimer inactivityTimer;
private String characterSet;
private BeepManager beepManager;
final static String profix1 = "?appid=";
final static String profix2 = "-title=";
final static String action = "muzhiwan.action.detail";
final static String bundle_key = "detail";
ImageView opreateView;
ViewfinderView getViewfinderView() {
return viewfinderView;
}
public Handler getHandler() {
return handler;
}
public CameraManager getCameraManager() {
return cameraManager;
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.capture);
hasSurface = false;
inactivityTimer = new InactivityTimer(this);
beepManager = new BeepManager(this);
opreateView = (ImageView) findViewById(R.id.button_openorcloseClick);
opreateView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (cameraManager != null) {
Config.KEY_FRONT_LIGHT = !Config.KEY_FRONT_LIGHT;
if (Config.KEY_FRONT_LIGHT == true) {
opreateView
.setImageResource(R.drawable.mzw_camera_close);
} else {
opreateView
.setImageResource(R.drawable.mzw_camera_open);
}
cameraManager.getConfigManager().initializeTorch(
cameraManager.getCamera().getParameters(), false);
onPause();
onResume();
}
}
});
}
@Override
protected void onResume() {
super.onResume();
// CameraManager must be initialized here, not in onCreate(). This is
// necessary because we don't
// want to open the camera driver and measure the screen size if we're
// going to show the help on
// first launch. That led to bugs where the scanning rectangle was the
// wrong size and partially
// off screen.
cameraManager = new CameraManager(getApplication());
viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
viewfinderView.setCameraManager(cameraManager);
handler = null;
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) {
// The activity was paused but not stopped, so the surface still
// exists. Therefore
// surfaceCreated() won't be called, so init the camera here.
initCamera(surfaceHolder);
} else {
// Install the callback and wait for surfaceCreated() to init the
// camera.
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
beepManager.updatePrefs();
inactivityTimer.onResume();
}
@Override
protected void onPause() {
if (handler != null) {
handler.quitSynchronously();
handler = null;
}
inactivityTimer.onPause();
cameraManager.closeDriver();
if (!hasSurface) {
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
surfaceHolder.removeCallback(this);
}
super.onPause();
}
@Override
protected void onDestroy() {
inactivityTimer.shutdown();
super.onDestroy();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
// restartPreviewAfterDelay(0L);
return super.onKeyDown(keyCode, event);
case KeyEvent.KEYCODE_FOCUS:
case KeyEvent.KEYCODE_CAMERA:
// Handle these events so they don't launch the Camera app
return true;
// Use volume up/down to turn on light
case KeyEvent.KEYCODE_VOLUME_DOWN:
cameraManager.setTorch(false);
return true;
case KeyEvent.KEYCODE_VOLUME_UP:
cameraManager.setTorch(true);
return true;
}
return super.onKeyDown(keyCode, event);
}
private void decodeOrStoreSavedBitmap(Bitmap bitmap, Result result) {
// Bitmap isn't used yet -- will be used soon
if (handler == null) {
savedResultToShow = result;
} else {
if (result != null) {
savedResultToShow = result;
}
if (savedResultToShow != null) {
Message message = Message.obtain(handler,
R.id.decode_succeeded, savedResultToShow);
handler.sendMessage(message);
}
savedResultToShow = null;
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (holder == null) {
Log.e(TAG,
"*** WARNING *** surfaceCreated() gave us a null surface!");
}
if (!hasSurface) {
hasSurface = true;
initCamera(holder);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
hasSurface = false;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
/**
* A valid barcode has been found, so give an indication of success and show
* the results.
*
* @param rawResult
* The contents of the barcode.
* @param barcode
* A greyscale bitmap of the camera data which was decoded.
*/
public void handleDecode(Result rawResult, Bitmap barcode) {
inactivityTimer.onActivity();
ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(
this, rawResult);
boolean fromLiveScan = barcode != null;
if (fromLiveScan) {
// Then not from history, so beep/vibrate and we have an image to
// draw on
beepManager.playBeepSoundAndVibrate();
// drawResultPoints(barcode, rawResult);
viewfinderView.drawResultBitmap(barcode);
}
//扫描二维码得到的结果 String
String text = rawResult.getText();
Log.d(TAG, "result-->" + text);
}
/**
* Superimpose a line for 1D or dots for 2D to highlight the key features of
* the barcode.
*
* @param barcode
* A bitmap of the captured image.
* @param rawResult
* The decoded results which contains the points to draw.
*/
private void drawResultPoints(Bitmap barcode, Result rawResult) {
ResultPoint[] points = rawResult.getResultPoints();
if (points != null && points.length > 0) {
Canvas canvas = new Canvas(barcode);
Paint paint = new Paint();
paint.setColor(getResources().getColor(R.color.result_points));
if (points.length == 2) {
paint.setStrokeWidth(4.0f);
drawLine(canvas, paint, points[0], points[1]);
} else if (points.length == 4
&& (rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A || rawResult
.getBarcodeFormat() == BarcodeFormat.EAN_13)) {
// Hacky special case -- draw two lines, for the barcode and
// metadata
drawLine(canvas, paint, points[0], points[1]);
drawLine(canvas, paint, points[2], points[3]);
} else {
paint.setStrokeWidth(10.0f);
for (ResultPoint point : points) {
canvas.drawPoint(point.getX(), point.getY(), paint);
}
}
}
}
private static void drawLine(Canvas canvas, Paint paint, ResultPoint a,
ResultPoint b) {
canvas.drawLine(a.getX(), a.getY(), b.getX(), b.getY(), paint);
}
private void initCamera(SurfaceHolder surfaceHolder) {
if (surfaceHolder == null) {
throw new IllegalStateException("No SurfaceHolder provided");
}
if (cameraManager.isOpen()) {
Log.w(TAG,
"initCamera() while already open -- late SurfaceView callback?");
return;
}
try {
cameraManager.openDriver(surfaceHolder);
// Creating the handler starts the preview, which can also throw a
// RuntimeException.
if (handler == null) {
handler = new CaptureActivityHandler(this, viewfinderView,
decodeFormats, characterSet, cameraManager);
}
decodeOrStoreSavedBitmap(null, null);
} catch (IOException ioe) {
Log.w(TAG, ioe);
Toast.makeText(this, R.string.camera_problem, Toast.LENGTH_SHORT)
.show();
finish();
} catch (RuntimeException e) {
// Barcode Scanner has seen crashes in the wild of this variety:
// java.?lang.?RuntimeException: Fail to connect to camera service
Log.w(TAG, "Unexpected error initializing camera", e);
Toast.makeText(this, R.string.framwork_problem, Toast.LENGTH_SHORT)
.show();
}
}
public void restartPreviewAfterDelay(long delayMS) {
if (handler != null) {
handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
}
}
public void drawViewfinder() {
viewfinderView.drawViewfinder();
}
}
(2).使用--------------Zing--------ZXingCodeLibs
//1.启动扫描界面
Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
startActivityForResult(intent, SCANNIN_GREQUEST_CODE);
// 2.处理扫描结果
/**
*
* @param result
* @param barcode
*/
public void handleDecode(Result result, Bitmap barcode) {
inactivityTimer.onActivity();
playBeepSoundAndVibrate();
// 扫描结果
String resultString = result.getText();
if (resultString.equals("")) {
Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show();
} else {
//2.传递扫描结果
Intent resultIntent = new Intent();
Bundle bundle = new Bundle();
bundle.putString("result", resultString);
bundle.putParcelable("bitmap", barcode);
resultIntent.putExtras(bundle);
this.setResult(RESULT_OK, resultIntent);
}
CaptureActivity.this.finish();
}
//3.收到回传的 结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case SCANNIN_GREQUEST_CODE:
if (resultCode == RESULT_OK) {
Bundle bundle = data.getExtras();
//显示扫描到的内容
tv_result.setText(bundle.getString("result"));
//显示
iv_qrcode.setImageBitmap((Bitmap) data.getParcelableExtra("bitmap"));
}
break;
}
}