C#開發移動應用系列(3.使用照相機掃描二維碼+各種基礎知識)

2022-01-01 分布式應用運行時

今天我們來講一下如何使用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(),代碼如下(注:這裡是重點):

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, 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了..

相關文章:

原文連結:http://www.cnblogs.com/GuZhenYin/p/7016798.html

.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注公眾號

相關焦點

  • C#開發移動應用系列(1.環境搭建)
    其實也是有感而發,昨天看到Jesse寫的博文(是時候開始用C#快速開發移動應用了),才幡然醒悟 , 原來我們的Xamarin已經如此的成熟了...其實從2013開始就想用Xamarin,奈何 當初收費一座大山壓在身上 完全無法見得廬山真面目後面2015,微軟收購Xamarin,沒過多久就宣布對個人用戶免費..那個興奮勁就別提了..
  • 用Web技術開發移動應用!
    為行動裝置開發應用有好幾種方法,有必要知道每種方法的優點和缺點。一共有三種基礎類型:原生應用、移動端網站和Hybrid 應用,我們會詳細介紹它們的區別。在下圖中,你可以看到三種類型在設計和架構上的對比。圖中還展示了應用如何通過訪問資料庫或者Web 服務API 來加載數據。
  • 二維碼在企業移動中的應用
    日本人在當初發明的時候怎麼也沒有想到,正是這一次不起眼的發明,卻在如今成為了中國移動網際網路飛速崛起浪潮中的弄潮兒。據《中國網際網路發展狀況統計報告》統計,2016年中國人平均每天使用微信掃碼就達10億人次,使用支付寶掃碼達到5億人次。而截止至2018年6月,掃碼使用共享單車的用戶數量達到2.45億,佔總體網民的30.6%。
  • C#開發移動應用之環境搭建
    (點擊上方藍字,可快速關注我們)來源:GuZhenYincnblogs.com/GuZhenYin/p/6971069.html前言其實也是有感而發,看到Jesse寫的博文(是時候開始用《C#快速開發移動應用了
  • 當我們在掃描二維碼時,我們在掃描什麼?
    在二維碼出現之前,我們是使用一維碼的!一維條碼二維碼(又稱二維條碼)是一種比一維碼(又稱一維條碼)更高級的條碼格式。一維碼只能在一個方向(一般是水平方向)上表達信息,而二維碼在水平和垂直方向都可以存儲信息。一維碼只能由數字和字母組成,而二維碼能存儲漢字、數字和圖片等信息,應用領域要廣得多。
  • Unity3d-C#入門基礎
    Unity3d-C#入門基礎Unity主要支持3種語言: C# (pronounced C-sharp), an industry-standard language similar to Java or C++; UnityScript
  • 掃描二維碼 Scan a QR code
    早上送寶寶上學,需要在校門口用手機掃描一下屏幕上的二維碼才能進門。因為每天都要重複這個動作,正好讓寶寶自己嘗試一下。
  • H5 移動端開發基礎知識
    而本文的主題 -- 移動端開發的兼容適配與性能優化,就是希望能從一些常見的移動端開發問題出發,釐清 Web 移動端開發的前前後後,一些技術的發展過程,一些問題的優化手段以及給出一些常見的兼容性問題的解決方案。
  • 將Axure移動端原型生成二維碼教程(二維碼支持微信等app掃描訪問)
    如果能將URL連結生成一個二維碼,直接用微信或QQ等應用直接掃描就能打開原型,這樣訪問體驗能有很大的提升。所以今天這篇分享就是教大家如何將Axure製作的移動端原型生成二維碼。下面這個就是我用原型連結生成的二維碼圖片,直接用微信或QQ掃描這個二維碼就能體驗到效果。
  • Unity基礎教程系列(四)——知識點小技巧總結
    Unity的基礎知識的系列教程中的第一篇。你不需要具有Unity編輯器的任何經驗,但是假定你一般具有多窗口編輯器應用程式的經驗。1 unity基礎unity版本介紹,建議開發使用LTS版本unity編輯器布局介紹,unity顏色空間介紹,一版選用Linear線性空間,gamma空間多為舊行動裝置使用層次結構窗口種的左側眼睛圖標可以顯示隱藏該物體在場景視圖種的顯示狀態2 創建時鐘unity坐標系,左手坐標系
  • 最全C#自學資源匯總
    非常適合0基礎的c#初學者,從開發環境的安裝到基礎的語法,都可以從中學習!2.WinForm系列51CTO《零基礎學軟體之winform常用控制項的使用視頻課程》https://edu.51cto.com/course/8729.html適合0基礎想學習winform的,學習winform控制項的使用,能夠熟練操作控制項。
  • 照相機構成及成像原理
    暗箱使用示意圖     3、照相機的發明     1839 年法國畫家達蓋爾根據小孔成像的原理髮明了被稱為「西洋鏡」的世界第一臺照相機。機身是連接照相機光學、機械、電子三大部分的總載體。它的前端安裝照相機鏡頭。     數位相機機身裡裝有圖像感應器、數字影像處理器和圖像存儲器等電子元件。傳統膠片照相機的機身暗箱裡面裝有膠捲,膠捲中間裝有各種光學、機械、電子元件,使相機成為一個整體。此外,各種攝影附件和輔助器材,在使用中也要與機身連接。因此,照相機機身一般由金屬或經過加工強度較高的注塑材料製成。
  • 機器視覺基礎知識詳解
    隨著工業4.0時代的到來,機器視覺在智能製造業領域的作用越來越重要,為了能讓更多用戶獲取機器視覺的相關基礎知識
  • 美松智能二維碼掃描器|自助收銀,高效掃描識別
    二維碼掃描器應用介紹:二維碼掃描器是商超自助收銀、快遞物流快速錄入、醫療數位化、工廠數位化管理、交通運輸等行業的掃描解決方案,提高工作效率
  • 如何使用JavaScript開發AR(增強現實)移動應用 (一)
    本文封面配圖是去年Jerry看的一部電影《異形:契約》的劇照。
  • 在線工作坊 | 使用Xamarin構建移動應用
    微軟 Reactor 為幫助廣開發者,技術愛好者,更好的學習 .NET Core, C#, Python,數據科學,機器學習,AI,區塊鏈, IoT 等技術,將每周三到周六,組織 3~
  • 【論二維碼】技術基礎普及 行動支付NFC與QR二維碼對比
    短距連結效率高 NFC頗適於行動支付  NFC起源於2004年,是由飛利浦(Philips)、諾基亞(Nokia)及索尼(Sony)以RFID技術為基礎共同開發而成,是一種專為短距需求所設計的高頻無線通訊技術,可讓各類電子裝置在10公分距離內,進行非接觸式的點對點資料交換。
  • 攝影名詞解釋:照相機
    1902年,德國的魯道夫利用賽得爾於1855年建立的三級像差理論,和1881年阿貝研究成功的高折射率低色散光學玻璃 ,製成了著名的「天塞」鏡頭,由於各種像差的降低,使得成像質量大為提高。在此基礎上,1913年德國的巴納克設計製作了使用底片上打有小孔的 、35毫米膠捲的小型萊卡照相機-徠卡單鏡頭旁軸照相機。不過這一時期的35毫米照相機均採用不帶測距器的透視式光學旁軸取景器。
  • 漫談C#程式語言在遊戲領域的應用
    所以,我們就來總結一下C#在遊戲行業中一些具體的應用吧。不必多說了吧,隨著「移動為王」潮流的到來,Unity3D也變得越來越流行。使用C/C++開發,提供C#作為腳本。移動遊戲開發必備神器,而且隨著VR熱潮的到來,使用U3D開發VR內容也十分便利。
  • Android實現條形碼與二維碼掃描
    有個二維碼是目前移動端和webAPP 常用是一種和用戶的交互方式,常用在社交,支付,電商app中,本文介紹實現條形碼與二維碼掃描。