Android用Zxing扫二维码/生成二维码功能

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/nzzl54/article/details/56277389

新年已过,一切恢复真正常,新的一年给自己几句指引:


光努力还不行,方向很重要。

总是想着最坏的结果,就会让人失去改变的勇气。

你当然有权利选择自己的人生--但只有在你真正强大后,逆行的阻力才会降到最小。

never say never.


下面开始记录二维码使用过程吧。官方给的库请自行去github下载:https://github.com/zxing/zxing

一、简介:ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口。Zxing可以实现使用手机的内置的摄像头完成条形码的扫描及解码。该项目可实现的条形码编码和解码。目前支持以下格式:UPC-A,UPC-E、EAN-8,EAN-13、39码、93码。ZXing是个很经典的条码/二维码识别的开源类库,以前在功能机上,就有开发者使用J2ME运用ZXing了,不过要支持JSR-234规范(自动对焦)的手机才能发挥其威力。 


二、ZXing库里面主要的类以及这些类的作用:

CaptureActivity。这个是启动Activity 也就是扫描器。

CaptureFragment。自定义扫描的Fragment。

CaptureActivityHandler 解码处理类,负责调用另外的线程进行解码。
DecodeThread 解码的线程。

com.google.zxing.client.android.camera 包,摄像头控制包。

ViewfinderView 自定义的View,就是我们看见的拍摄时中间的框框了。


三、生成url的二维码,代码如下:url = “http://blog.csdn.net/crazy1235/article/details/56087721?ref=myread”


private final int QR_WIDTH = 300;
private final int QR_HEIGHT = 300;
private ImageView imageView;
@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_qrcode);
        imageView = (ImageView)findViewById(R.id.iv_qrcode);
        String url = getIntent().getStringExtra("url");
        createQRImage(url);
    }
public void createQRImage(String url)
    {
        try
        {
            //判断URL合法性
            if (url == null || "".equals(url) || url.length() < 1)
            {
                return;
            }
            Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            //图像数据转换,使用了矩阵转换
            BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);
            int[] pixels = new int[QR_WIDTH * QR_HEIGHT];
            //下面这里按照二维码的算法,逐个生成二维码的图片,
            //两个for循环是图片横列扫描的结果
            for (int y = 0; y < QR_HEIGHT; y++)
            {
                for (int x = 0; x < QR_WIDTH; x++)
                {
                    if (bitMatrix.get(x, y))
                    {
                        pixels[y * QR_WIDTH + x] = 0xff000000;
                    }
                    else
                    {
                        pixels[y * QR_WIDTH + x] = 0xffffffff;
                    }
                }
            }
            //生成二维码图片的格式,使用ARGB_8888
            Bitmap bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT);
            //显示到一个ImageView上面
            imageView.setImageBitmap(bitmap);
        }
        catch (WriterException e)
        {
            e.printStackTrace();
        }
    }


二维码生成的方法接口,如果你只是使用者方法,很简单,只要传入一个URL即可,就像我截图里面一样,传入一个合法的网址即可。


四、扫二维码功能

Zxing库自带了一个CaptureFragment用来显示扫码框,这个不多说,现在说的是使用自定义的Fragment来显示扫码框。

fragment_scan_frame.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:app="http://schemas.android.com/apk/res-auto"
             android:layout_width="fill_parent"
             android:layout_height="fill_parent" >

    <SurfaceView
        android:id="@+id/preview_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <com.uuzuche.lib_zxing.view.ViewfinderView
        android:id="@+id/viewfinder_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:inner_width="@dimen/wdp_250.0"
        app:inner_height="@dimen/hdp_250.0"
        app:inner_margintop="@dimen/hdp_120.0"
        app:inner_corner_color="@color/green"
        app:inner_corner_length="20dp"
        app:inner_corner_width="1dp"
        app:inner_scan_bitmap="@mipmap/scan_image"
        app:inner_scan_speed="20"
        />

</FrameLayout>

CaptureActivity重点写出自定义Fragment如何替换方法

 //扫码Fragment初始化
        captureFragment = new CaptureFragment ();
        // 为二维码扫描界面设置定制化界面
        CodeUtils.setFragmentArgs (captureFragment, R.layout.fragment_scan_frame);
        captureFragment.setAnalyzeCallback (analyzeCallback);
        getSupportFragmentManager ().beginTransaction ()
                .replace (R.id.fl_my_container, captureFragment)
                .commit ();


最后是扫码结果处理

   /**
     * 二维码解析回调函数
     */
    CodeUtils.AnalyzeCallback analyzeCallback = new CodeUtils.AnalyzeCallback () {
        @Override public void onAnalyzeSuccess (Bitmap mBitmap, String result) {
            if (result.contains ("http")) {
                //是网页的话就跳到下一页面用WebView去显示
                Intent intent = new Intent(CaptureActivity.this,QRCodeActivity.class);
                intent.putExtra("url",result);
                intent.putExtra("isShowWeb",true);
                startActivity(intent);
                return;
            } else if (result.contains (":")) {   //其他情况
            } else {
                //其他情况
                return;
            }
        }

        @Override public void onAnalyzeFailed () {
            captureFragment.restartPreview ();
        }
    };


五、关于SurfaceView ,摘自:http://www.cnblogs.com/lipeil/archive/2012/08/31/2666187.html

surfaceView和View最本质的区别在于:

surfaceView是在一个新起的单独线程中可以重新绘制画面,而View必须在UI的主线程中更新画面。那么在UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中 thread处理,一般就需要有一个event queue的设计来保存touch event,这会稍稍复杂一点,因为涉及到线程同步。SurfaceView封装了一个Surface对象,而不是Canvas。这一点很重要,因为Surface可以使用后台线程绘制。对于那些资源敏感的 操作,或者那些要求快速更新或者高速帧率的地方,例如,使用3D图形,创建游戏,或者实时预览摄像头,这一点特别有用。

所以基于以上,根据游戏特点,一般分成两类。

1 被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。 因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。

2 主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞main UI thread。所以显然view不合适,需要surfaceView来控制。

1. 何时应该使用SurfaceView?
SurfaceView使用的方式与任何View所派生的类都是完全相同的。可以像其他View那样应用动画,并把它们放到布局中。
SurfaceView封装的Surface支持使用本章前面所描述的所有标准Canvas方法进行绘图,同时也支持完全的OpenGL ES库。
使用OpenGL,你可以再Surface上绘制任何支持的2D或者3D对象,与在2D画布上模拟相同的效果相比,这种方法可以依靠硬件加速(可用的时候)来极大地提高性能。
对于显示动态的3D图像来说,例如,那些使用Google Earth功能的应用程序,或者那些提供沉浸体验的交互式游戏,SurfaceView特别有用。它还是实时显示摄像头预览的最佳选择。
2. 创建一个新的SurfaceView控件
要创建一个新的SurfaceView,需要创建一个新的扩展了SurfaceView的类,并实现SurfaceHolder.Callback。
SurfaceHolder回调可以在底层的Surface被创建和销毁的时候通知View,并传递给它对SurfaceHolder对象的引用,其中包含了当前有效的Surface。
一个典型的Surface View设计模型包括一个由Thread所派生的类,它可以接收对当前的SurfaceHolder的引用,并独立地更新它。





猜你喜欢

转载自blog.csdn.net/nzzl54/article/details/56277389