C#开发移动应用系列(3.使用照相机扫描二维码+各种基础知识)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 原文:C#开发移动应用系列(3.使用照相机扫描二维码+各种基础知识)前言 上篇文章地址: C#开发移动应用系列(1.环境搭建) C#开发移动应用系列(2.使用WebView搭建WebApp应用) 今天我们来讲一下如何使用Camera来调用照相机扫描二维码.
原文: C#开发移动应用系列(3.使用照相机扫描二维码+各种基础知识)

前言

上篇文章地址:

C#开发移动应用系列(1.环境搭建)

C#开发移动应用系列(2.使用WebView搭建WebApp应用)

今天我们来讲一下如何使用Camera来调用照相机扫描二维码.

(Tips:大神别问我为什么不用Camera2,饭要一口口吃..慢慢来.....................其实是我还没看懂..)

确定一下本篇的学习目标:

1.学会如何调用Camera来实现照相机预览

2.学会如何跳转Activity并传值

3.学会如何识别相机预览中的二维码,并读取

效果图:

 

 

 

正文

1.学会如何调用Camera来实现照相机预览

   我们先来看看如何使用Camera来实现照相机预览..

   我们首先新建一个Activity,...嗯..暂且命名为SaoYiSaoActivity (不是骚..是扫..)

   在Resources\layout 创建对应的界面,SaoYiSao.axml

   在SaoYiSaoActivity的OnCreate中加载这个页面,代码如下:

   

protected override void OnCreate(Bundle savedInstanceState)
{
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.SaoYiSao);
          
}

在SaoYiSao.axml中拖入控件SurfaceView,这里的SurfaceView是用来展示预览画面的..(具体的SurfaceView作用自行百度..或者等我下篇..)

同样,我们把它铺满全屏,如图:

下面我们开始写代码...

因为我们要调用照相机和监控SurfaceView.所以我们的SaoYiSaoActivity 需要继承一些东西,代码如下:

public class SaoYiSaoActivity : Activity,Android.Hardware.Camera.IPreviewCallback,ISurfaceHolderCallback

需要继承Android.Hardware.Camera.IPreviewCallback来获取照相机的预览回调

需要继承ISurfaceHolderCallback来获取SurfaceView发生在表面的事件和变化

我们实现这两个接口,会得到如下几个方法

OnPreviewFrame(),来自于Android.Hardware.Camera.IPreviewCallback

SurfaceChanged()

SurfaceCreated()

SurfaceDestroyed()

我们一个一个来实现,

不过在此之前,先回到OnCreate()方法中,初始化一下我们的SurfaceView

编写代码如下:

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.SaoYiSao);
            //获取surfaceView1
            var surface = FindViewById<SurfaceView>(Resource.Id.surfaceView1);
            //获取surface的线程
            var holder = surface.Holder;
            //设置线程回调为本类
            holder.AddCallback(this);
            //表明该Surface不包含原生数据
            holder.SetType(Android.Views.SurfaceType.PushBuffers);
            //设置这个Surface的大小
            holder.SetFixedSize(300, 200);
        }

解释都在注释里了..我就不多说了..

下面开始实现刚才的接口..

首先来实现 SurfaceCreated(),代码如下(注:这里是重点):

 1        public void SurfaceCreated(ISurfaceHolder holder)
 2         {
 3             camera = Android.Hardware.Camera.Open();
 4             Android.Hardware.Camera.Parameters p = camera.GetParameters();
 5             p.PictureFormat = ImageFormatType.Jpeg;
 6             camera.SetParameters(p);
 7             camera.SetPreviewCallback(this);
 8             camera.SetPreviewDisplay(holder);
 9             camera.StartPreview();
10 
11 
12         }

讲一下这些代码做了什么,首先很明显..打开照相机.第二句,获取照相机的参数,设置图片类型为Jpeg.重新把参数赋值给照相机.

设置照相机的预览回调为自身类,设置照相机显示为SurfaceView的线程

最后,开始预览.

 

然后我们实现SurfaceDestroyed(),这里是当Surface被销毁之前调用的方法,代码如下(注:也很重要):

public void SurfaceDestroyed(ISurfaceHolder holder)
        {
            //删除回调
            holder.RemoveCallback(this);
            //删除照相机回调
            camera.SetPreviewCallback(null);
            //停止照相机预览
            camera.StopPreview();
            //释放照相机
            camera.Release();
            camera = null;
        }

一定要写这些,不然照相机会一直处于占用状态..然后GG..

实现上面两个方法.其实我们就可以调用照相机预览了...

OnPreviewFrame()这个方法,我们暂时先不实现 放个空的.打个断点

运行,我们会发现.OnPreviewFrame()这个方法会被不停的调用.

里面有两个参数

 

 public void OnPreviewFrame(byte[] data, Android.Hardware.Camera camera)

很明显,这个字节类型的data就是每次照相机预览传回来的当前帧的图片信息.

camera当然就是照相机了..

所以我们就可以从这里一直获取预览的图片帧..(不要心急,慢慢来)

我们进入第二个知识点

2.学会如何跳转Activity并传值

我们知道,安卓的每一个界面转换都是由一个或者多个Activity实现的..

前面我们也单独写了一个SaoYiSaoActivity

那么我们该如何跳转过去呢..往下看..

我们在MainActivity添加一个Button,给他添加一个点击事件,代码如下:

 

btn2.Click += delegate
                {
                    Intent intent = new Intent(this,typeof(SaoYiSaoActivity));
                    intent.AddFlags(ActivityFlags.SingleTop);
                    StartActivityForResult(intent, 1);
                };

用SaoYiSaoActivity类型申明一个Intent ,

然后添加Activity启动模式,为SingleTop.

因为我们要获取SaoYiSaoActivity传递回来的参数,所以我们采用StartActivityForResult来跳转.

第一个参数当然就是要跳转的Intent ,第二个是获取返回值用的Code编号(注意:要大于0)

这样我们就实现了跳到SaoYiSaoActivity..

那么如何获取SaoYiSaoActivity给的返回值呢?.

我们重写Activity的OnActivityResult方法,如下:

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            base.OnActivityResult(requestCode, resultCode, data);

            //如果当初的发的requestCode =1
            if (requestCode == 1 && resultCode == Result.Ok)
            { 
               
                webView.LoadUrl(data.GetStringExtra("code"));
                Toast.MakeText(this, "扫描结果:" + data.GetStringExtra("code"), ToastLength.Short).Show();
            }
        }

大家可以看到,上面我们有一个判断requestCode==1,这个1就是我们传递过去的第二个参数.

当你有多个跳转界面的时候,就可以用这个requestCode来区分.

这样,我们就完成了界面的跳转和获取返回值

3.学会如何识别相机预览中的二维码,并读取

下面我们讲讲如何读取相机中的二维码.

.Net解析二维码,在我的知识储备里面...常用的只有2个库,一个是QRCode,一个是ZXing.Net.(PS:如果有大神知道更好的,请留言赐教..)

很遗憾QRCode,使用的是GDI+ 也就是System.drawing..很明显..我们在手机端..调用不到..

所以只能用ZXing.Net

我们在nuget中搜索ZXing.Net.

如图:

类型很多..而且有各种版本..我们选择ZXing.Net.Mobile,

当然这里还有个ZXing.Net.Mobile.Forms,这个是封装好的二维码扫描控件..本文主要是学习,所以不使用(当然..你主要是实现功能..就用这个..巨人的肩膀上 多刺激..).

我们首先定义一个方法CodeDecoder来专门解析二维码,代码如下:

        /// <summary>
        /// 二维码解码
        /// </summary>
        /// <returns></returns>
        public string CodeDecoder(byte[] data,int width,int height)
        {

            byte[] bytes = data;//获取图片字节
             //设置位图源
            PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, width, height, 0, 0, width,height, false);
            //处理像素值内容信息
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
             //初始化解析器
            ZXing.Reader reader = new QRCodeReader();
            //解析位图
            ZXing.Result result = reader.decode(bitmap);
            if (result == null)
                return null;
            return result.Text;//返回解析结果  
        }

 

前面我们说过了.OnPreviewFrame()是照相机预览的回调.所以我们现在就来实现他.

代码如下:

 public void OnPreviewFrame(byte[] data, Android.Hardware.Camera camera)
        {

            try
            {
                //获取相机宽度
                int previewWidth = camera.GetParameters().PreviewSize.Width;
                //获取相机高度
                int previewHeight = camera.GetParameters().PreviewSize.Height;
                //解析二维码
                var date = CodeDecoder(data, previewWidth, previewHeight);
                //判断是否解析到二维码.
                if (date != null)
                {
                    //跳转回主页面
                    Intent intent = new Intent(this, typeof(MainActivity));
                    //放入一个key 为code 的解析后的值
                    intent.PutExtra("code", date);
                    //状态设为OK
                    SetResult(Android.App.Result.Ok, intent);
                    //关闭当前界面
                    Finish();
                }

            }
            catch (IOException)
            {

               
            }
        }

上面的代码,if中的代码就是如何跳转回主界面,并且传递返回值.

 

最后我们用百度的网址,生成一个二维码,调试,扫描..就是前面的效果图拉~

 

 

写在最后

感觉很多东西..其实基本和JAVA都是一样的..

所以不要抱怨Xamarin的资料少..你能查到相关的JAVA资料..基本也就搞定Xamarin了..

目录
相关文章
|
1月前
|
物联网 数据处理 C#
C#实现上位机开发,串口通信,读写串口数据并处理16进制数据
C#实现上位机开发,串口通信,读写串口数据并处理16进制数据。在自动化、物联网以及工业控制行业中,上位机开发是一项重要的技能。本教程主要介绍使用C#进行上位机开发,重点在于串口通信和数据处理。
293 82
|
3月前
|
缓存 算法 安全
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
110 12
|
4月前
|
前端开发 JavaScript 安全
C#一分钟浅谈:Blazor WebAssembly 开发
Blazor WebAssembly 是一个客户端框架,允许开发者使用C#和Razor语法构建Web应用。本文介绍了Blazor WebAssembly的基本概念、常见问题及解决方案,包括路由配置、数据绑定、异步操作、状态管理和性能优化等方面的内容,并分享了一些易错点及如何避免的方法。希望这些内容能帮助你在Blazor WebAssembly开发中少走弯路,提高开发效率。
168 51
|
4月前
|
缓存 C# 开发者
C# 一分钟浅谈:Blazor Server 端开发
本文介绍了 Blazor Server,一种基于 .NET 的 Web 开发模型,允许使用 C# 和 Razor 语法构建交互式 Web 应用。文章从基础概念、创建应用、常见问题及解决方案、易错点及避免方法等方面详细讲解,帮助开发者快速上手并提高开发效率。
110 2
|
4月前
|
开发框架 缓存 .NET
C# 一分钟浅谈:Blazor Server 端开发
Blazor Server 是基于 ASP.NET Core 的框架,允许使用 C# 和 Razor 语法构建交互式 Web 应用。本文介绍 Blazor Server 的基本概念、快速入门、常见问题及解决方案,帮助开发者快速上手。涵盖创建应用、基本组件、数据绑定、状态管理、跨组件通信、错误处理和性能优化等内容。
228 1
|
4月前
|
测试技术 Go C#
C#一分钟浅谈:ReSharper 插件增强开发效率
【10月更文挑战第25天】ReSharper 是 JetBrains 开发的一款 Visual Studio 插件,旨在提高 .NET 开发者的生产力。它通过代码分析、重构、导航等功能,帮助开发者避免常见错误,提升代码质量和开发效率。本文将通过具体代码案例,详细介绍 ReSharper 的常见功能及其应用。
113 1
|
4月前
|
C# Python
使用wxpython开发跨平台桌面应用,对wxpython控件实现类似C#扩展函数处理的探究
【10月更文挑战第30天】使用 `wxPython` 开发跨平台桌面应用时,可以通过创建辅助类来模拟 C# 扩展函数的功能。具体步骤包括:1. 创建辅助类 `WxWidgetHelpers`;2. 在该类中定义静态方法,如 `set_button_color`;3. 在应用中调用这些方法。这种方法提高了代码的可读性和可维护性,无需修改 `wxPython` 库即可为控件添加自定义功能。但需要注意显式调用方法和避免命名冲突。
|
5月前
|
JSON C# 开发者
C#语言新特性深度剖析:提升你的.NET开发效率
【10月更文挑战第15天】C#语言凭借其强大的功能和易用性深受开发者喜爱。随着.NET平台的演进,C#不断引入新特性,如C# 7.0的模式匹配和C# 8.0的异步流,显著提升了开发效率和代码可维护性。本文将深入探讨这些新特性,助力开发者在.NET开发中更高效地利用它们。
67 1
|
5月前
|
开发框架 NoSQL MongoDB
C#/.NET/.NET Core开发实战教程集合
C#/.NET/.NET Core开发实战教程集合
105 1
|
5月前
|
XML 存储 安全
C#开发的程序如何良好的防止反编译被破解?ConfuserEx .NET混淆工具使用介绍
C#开发的程序如何良好的防止反编译被破解?ConfuserEx .NET混淆工具使用介绍
274 0