通过谷歌官方例子手把手教你改造自己的Zxing扫描android程序(三)

上篇文章中我们已经完成了及其粗糙版本的扫码App,这篇文章我们将对这个粗糙的扫码App进行优化;

和市面大多数扫码一样,做成竖屏
扫码框的位置优化
自定义title
看心情优化

立起来!

CaptureActivity 配置设成portait,onResume 中注释掉设置横屏的代码

 <activity android:name=".CaptureActivity"
            android:screenOrientation="portrait"
            android:clearTaskOnLaunch="true"
            android:stateNotNeeded="true"

            android:windowSoftInputMode="stateAlwaysHidden">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

 //setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);

跑一下程序,完美!


image.png

这个时候,已经能扫二维码了,但是识别率很低,把手机横着扫,识别率就高,把扫码后识别的图片打印出来,发现只是表面上看起来竖屏了,但是相机识别的还是横屏的内容。


image.png

ZXing 横屏转竖屏

需要修改的地方就2处
第一个地方,CameraManager里的 getFramingRectInpreview()方法,增加cameraResolution的判断

if(cameraResolution.x>cameraResolution.y){  //x大于y 改成竖屏数据,y和x互换 计算截图

        rect.left = rect.left * cameraResolution.y / screenResolution.x;
        rect.right = rect.right * cameraResolution.y / screenResolution.x;
        rect.top = rect.top * cameraResolution.x / screenResolution.y;
        rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;

      }else{

        rect.left = rect.left * cameraResolution.x / screenResolution.x;
        rect.right = rect.right * cameraResolution.x / screenResolution.x;
        rect.top = rect.top * cameraResolution.y / screenResolution.y;
        rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;
      }

第二个地方,DecodeHandler 的decode(byte[] data, int width, int height) 方法对data[](这个data就是要解析的数据源)数据进行矩阵替换,宽高互换

private void decode(byte[] data, int width, int height) {
    long start = System.currentTimeMillis();
    Result rawResult = null;
    byte[] newData = new byte[data.length];
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++)
        newData[x * height + height - y - 1] = data[x + y * width];
    }
    int tmp = width; // Here we are swapping, that's the difference to #11
    width = height;
    height = tmp;
    data = newData;
    PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
    if (source != null) {

两步骚操作之后,我们再来看看效果


image.png

完美!
如果想修改扫码框的位置 可以在此处修改

public synchronized Rect getFramingRect() {
    if (framingRect == null) {
      if (camera == null) {
        return null;
      }
      Point screenResolution = configManager.getScreenResolution();
      if (screenResolution == null) {
        // Called early, before init even finished
        return null;
      }

      int width = findDesiredDimensionInRange(screenResolution.x, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH);
      int height = findDesiredDimensionInRange(screenResolution.y, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);

      int leftOffset = (screenResolution.x - width) / 2;//修改比例改变扫码框位置
      int topOffset = (screenResolution.y - height) / 3;
      framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
      Log.d(TAG, "Calculated framing rect: " + framingRect);
    }
    return framingRect;
  }

Zxing 增加从相册选取图片二维码识别

添加一个按钮,点击事件吊起相册

mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); //"android.intent.action.GET_CONTENT"
                innerIntent.setType("image/*");
                Intent wrapperIntent = Intent.createChooser(innerIntent, "选择二维码");
                startActivityForResult(wrapperIntent, 100);
            }
        });

在onActivityResult里处理选择的代码

@Override
    protected void onActivityResult(final int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case 100:
                    handleAlbumPic(data);
                    break;
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

这个地方碰到超多坑,利用Zxing给的方法和网上找的方法,各种识别图片NotfoundException,
而且新的Zxing包和之前的包接口还不一样了,用网上的很多方法都不行,就在我快要放弃的时候,看到一篇博客提供了如下代码,虽然识别率不是很高,但是也算是成功了。识别率这个问题,大家可以在加入zbar解析。

 Uri sourceUri = data.getData();

        try {
            // 下面这句话可以通过URi获取到文件的bitmap
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),sourceUri);

            // 在这里我用到的 getSmallerBitmap 非常重要,下面就要说到
            bitmap = ImageUtil.getSmallerBitmap(bitmap);

            // 获取bitmap的宽高,像素矩阵
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            int[] pixels = new int[width*height];
            bitmap.getPixels(pixels,0,width,0,0,width,height);

            // 最新的库中,RGBLuminanceSource 的构造器参数不只是bitmap了
            RGBLuminanceSource source = new RGBLuminanceSource(width,height,pixels);
            BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
            MultiFormatReader reader = new MultiFormatReader();
            Result result = null;

            // 尝试解析此bitmap,!!注意!! 这个部分一定写到外层的try之中,因为只有在bitmap获取到之后才能解析。写外部可能会有异步的问题。(开始解析时bitmap为空)
            try {
                result = reader.decode(binaryBitmap);

                handleDecode(result,bitmap,1);

            } catch (NotFoundException e) {
                Log.i(TAG, "onActivityResult: notFind");
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

这里将bitmap进行了转化,将大图变小,太大zxing就notfound exception了

public static Bitmap getSmallerBitmap(Bitmap bitmap){
        int size = bitmap.getWidth()*bitmap.getHeight() / 160000;
        if (size <= 1) return bitmap; // 如果小于
        else {
            Matrix matrix = new Matrix();
            matrix.postScale((float) (1 / Math.sqrt(size)), (float) (1 / Math.sqrt(size)));
            Bitmap resizeBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), 
            bitmap.getHeight(), matrix, true);
            return resizeBitmap;
        }
    }

博客原文 https://blog.csdn.net/qq_28057541/article/details/52119896
老版本Zxing 解决方案:https://blog.csdn.net/u013200308/article/details/68067564
GitHub 项目地址,ZxingDemo是修改后的
主要难点就是Zxing竖屏切换,Camera获取的数据源也要切换的问题。都看到这里了,点个赞呗。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容