前言

上篇文章地址:

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(, );
}

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

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

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

        public void SurfaceCreated(ISurfaceHolder holder)
{
camera = Android.Hardware.Camera.Open();
Android.Hardware.Camera.Parameters p = camera.GetParameters();
p.PictureFormat = ImageFormatType.Jpeg;
camera.SetParameters(p);
camera.SetPreviewCallback(this);
camera.SetPreviewDisplay(holder);
camera.StartPreview(); }

讲一下这些代码做了什么,首先很明显..打开照相机.第二句,获取照相机的参数,设置图片类型为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, );
};

用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 == && 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, , , 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了..

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

  1. 用c#开发微信 (20) 微信登录网站 - 扫描二维码登录

    像京东,一号店等网站都实现了用微信来登录的功能,就是用手机上的微信扫一扫网站上的二维码,微信上确认后,即可自动用微信的帐号登录网站. 1 创建网站应用 在微信开放平台创建一个网站应用 https:// ...

  2. SNF开发平台WinForm-平板拍照及扫描二维码功能

    在我们做项目的时候,经常会有移动平板处理检验,审核等,方便移动办公.这时就需要在现场拍照上传问题,把当场问题进行上传,也有已经拍完照的图片或加工过的图片进行上传.还有在车间现场一体机,工控机 这种产物 ...

  3. Android开发——通过扫描二维码,打开或者下载Android应用

    Android开发——通过扫描二维码,打开或者下载Android应用   在实现这个功能的时候,被不同的浏览器折磨的胃疼,最后实现了勉强能用,也查考了一下其他人的博客 android实现通过浏览器点击 ...

  4. 用c#开发微信(2)扫描二维码,用户授权后获取用户基本信息 (源码下载)

    本文将介绍基于Senparc.Weixin微信开发框架来实现网页授权来获取用户基本信息.先生成包含授权及回调url信息的二维码:用户用微信扫描之后,被要求授权以获取Ta的用户基本信息:用户授权后,通过 ...

  5. C#微信公众号接口开发实例-高级接口-申请带参数的二维码

    最近公司涉及到微信绑定用户,做了高级接口-申请带参数的二维码,总结了下微信开发接口.微信接口开发都是除了消息用的xml 回复基本上都是用json的形式传递信息(post/get),开发的方法基本都是一 ...

  6. 微信公共服务平台开发(.Net 的实现)9-------处理二维码

    今天我们来共同学习一下微信公共服务平台中一个重要内容---二维码扫描.众所周知二维码目前应用范围很广,在这里不再叙述背景了,但是值得一提的是目前大家手机上面应用的二维码扫描工具是支持的都是QR码和PD ...

  7. Android开发之扫描二维码开发

    原贴地址:http://www.cnblogs.com/Fndroid/p/5540688.html 二维码其实有很多种,但是我们常见的微信使用的是一种叫做QRCode的二维码,像下面这样的,可以放心 ...

  8. Swift开发小技巧--识别选中照片中的二维码

    识别选中照片中的二维码 点击相册按钮,打开用户相册 @IBAction func photoBtnClick(sender: AnyObject) { // 打开相册 // 1.判断是否能够打开相册 ...

  9. Swift开发小技巧--扫描二维码,二维码的描边与锁定,设置扫描范围,二维码的生成(高清,无码,你懂得!)

    二维码的扫描,二维码的锁定与描边,二维码的扫描范围,二维码的生成(高清,无码,你懂得!),识别相册中的二维码 扫描二维码用到的三个重要对象的关系,如图: 1.懒加载各种类 // MARK: - 懒加载 ...

随机推荐

  1. linux 内核的rt_mutex 锁操作实现的临界区

    rt_mutex 定义的锁规则: 以偶对齐的task_struct指针为上锁标记, 偶对齐的指针地址最低位用以标记是否有waiters. rt_mutex的trylock,lock,以及unlock都 ...

  2. IDEA 安装scala插件

    安装scala插件一般有两种方式,在IDEA里面下载或者手动安装 手动安装 首先是下载需要的插件包,官网下载实在太慢,这里提供我下载好的文件,会按时更新成最新版 https://pan.baidu.c ...

  3. Python进阶之装饰器

    函数也是对象 要理解Python装饰器,首先要明白在Python中,函数也是一种对象,因此可以把定义函数时的函数名看作是函数对象的一个引用.既然是引用,因此可以将函数赋值给一个变量,也可以把函数作为一 ...

  4. VM VirtrualBox 安装centos6.5后的网络设置

    小白学习linux(一) 本文只是介绍VirtrualBox安装centos完成后的网络设置: 每次用虚拟机装完centos后,捣鼓半天才能上网.熟话说的好,好记性不如烂笔头,写个随笔记录下设置过程, ...

  5. 热切换Log4j级别配置

    欢迎和大家交流技术相关问题:邮箱: jiangxinnju@163.com博客园地址: http://www.cnblogs.com/jiangxinnjuGitHub地址: https://gith ...

  6. MySQL使用pt-online-change-schema工具在线修改1.6亿级数据表结构

    摘  要:本文阐述了MySQL DDL 的问题现状.pt-online-schema-change的工作原理,并实际利用pt-online-schema-change工具在线修改生产环境下1.6亿级数 ...

  7. php 关于经纬度距离计算方法 成功版

    1.PHP实现通过经纬度计算距离 单位为公里 function getdistance($lng1,$lat1,$lng2,$lat2)//根据经纬度计算距离 { //将角度转为狐度  $radLat ...

  8. 加盟全景-加盟VR虚拟现实-全景智慧城市

    作为一个技术整合型产业,VR行业的硬件厂商几乎没有任何技术基础,很多国产虚拟现实VR创业公司基本都是和几家固定的上游零部件提供商合作,全行业都在等待高通骁龙芯片的升级,这和手机行业有几分相似.去年3月 ...

  9. 互联网二次进化—VR全景智慧城市

    vr全景智慧城市被称为中国首家商业全景平台.VR被称为下一代超级人机交互平台. 时间往前推20年,1996年,电脑还是很新鲜的玩意儿.那时,我第一次接触电脑,在我父亲供职的单位,一个开着空调的房间里, ...

  10. Spring Boot 学习(1)

    文 by / 林本托 Tip 做一个终身学习的人. Spring Boot 初体验 Spring Boot 包含了很多 start(Spring boot 中 的叫法,就是一个模块,后文统一称模块,便 ...