iT邦幫忙

2021 iThome 鐵人賽

DAY 26
0
AI & Data

觀賞魚辨識的YOLO全餐系列 第 26

Day 26 - HBuilderX 與 Native.js API 讀取圖片

Day 26 - HBuilderX 與 Native.js API 讀取圖片

Day 25 - HBuilder X 產生 apk 已經完成使用 HBuilderX來打包 Android apk,接下來要做的是將觀賞魚辨識相關的功能實作到這個前端系統中,需要的功能分析如下:

  1. 使用相機跟相簿:這在打包 apk 時已經有設定權限了。
  2. 壓縮圖片,因為 YOLO 辨識不需要太高的解析度,可以將圖片先壓縮至寬度為 1024 就可以。
  3. 上傳圖片到 AWS EC2。
  4. 讀取回傳值,並顯示結果。

設計畫面

先設計畫面,後面再針對功能來個別設計,畫面部分成三部分,上面為標題,中間為圖示,最下方提供兩個按鈕,分別提供從相機或是相冊取得圖片來源。

  • tap:首頁包含了
    • header:標題功能,如CWA 觀賞魚辨識
    • du:圖示,僅供美化介面。
    • an:功能按鈕,提供了兩個功能
  • rq:第二頁,用來呈現結果的畫面,分別提供從相機或是相冊取得圖片來源。
<body>
    <div id="tap">

        <header id="header">
            <div class="tt">CWA 觀賞魚辨識</div>
        </header>
        
        <div id="dcontent" class="dcontent">
            <div id="tu">
                <img src="img/index/yu.jpg" />				
            </div>
            <div id="an">
                <li class="an" class="button button-select" onclick="appendByCamera()">
                    
                    <a href="#rq">
                        <img src="img/index/pz.png" />
                    </a>
                </li>
                <li class="an" class="button button-select" onclick="appendByGallery()">
                    <a href="#rq">
                        <img src="img/index/tk.png" />
                    </a>
                </li>	
            </div>
        </div>
    </div>

    <div id="rq">
        <div id="img-output"></div>
        <div id="output">  </div>
        <div id="img"></div>
        <div class="hiu"><a href="index.html">再来一张</a> </div>
    </div>
</body>

可以透過 HBuilderX 的預覽功能看到畫面的成果,如下圖所示,除了可以預覽成果,也可以指定希望在哪一種手機上的預覽成果,目前設定的手機效果是 iPhone 6/7/8 的直式效果。

https://ithelp.ithome.com.tw/upload/images/20210926/20129510d4N3sxDfUO.png
圖 1、手機應用畫面設計預覽

接著要實現這兩個函數:

  • appendByCamera() - 從相機中上傳圖片。
  • appendByGallery() - 從相冊中上傳圖片。

而這需要應用到手機本身的功能,所以需要去查相關 5+ App 的開發 API中與相機相關跟與相冊的手冊

appendByCamera 方法主要的工作是:拍照;將照片存在相冊中;將照片顯示在應用中;將相片上傳到 EC2 主機上,並顯示出來。

appendByCamera()

// 從相機中獲取圖片並上傳
function appendByCamera(){
	plus.camera.getCamera().captureImage(
        function(p){ # 拍照成功的回傳函數
            # 將照片存在相冊中
            plus.gallery.save(p, function(){});
            plus.io.resolveLocalFileSystemURL(p, function(pq) {
                pathPhoto = pq.toLocalURL();
                var str = '<img src="' + pathPhoto + '" width="100%">'
                # 將結果顯示在 id='img-output' 的元件上
                outLineHTML(str);
            }, function(e) {});
            # 將相片上傳到 EC2 主機上
            appendFile(p);
        });
}

appendByGallery 方法主要的工作是從相冊中挑選圖片;將照片顯示在應用中;將相片上傳到 EC2 主機上,並顯示出來。

appendByGallery()

// 從相冊中上傳圖片
function appendByGallery(){
	plus.gallery.pick(function(p){
		var str = '<img src="' + p + '" width="100%">';
		# 將結果顯示在 id='img-output' 的元件上
        outLineHTML(str);
        # 將相片上傳到 EC2 主機上
		appendFile(p);	
	});
}

appendFile 方法提供了壓縮圖片,上傳圖片,並顯示結果的功能

appendFile()

var server="http://[EC2_PUBLIC_IP4]/imgUpload/";
var files=[];
var index=1;
function appendFile(p){
	files.push({name:"fileUpload"+index,path:p});
	var wt=plus.nativeUI.showWaiting();
    # 壓縮圖片至 1024
	plus.zip.compressImage({
		src:p,
		dst:"cm.jpg",
		quality:20,
		overwrite:true,
		width:'1024',
	}, function(i){
		plus.nativeUI.closeWaiting();
        # 上傳圖片
		var task=plus.uploader.createUpload(
			server,
			{method:"post"},
			function(t,status){ //上傳成功,顯示結果
				if (status == 200) {
					var tr = t.responseText;
					var utr = unescape(tr.replace(/\\u/gi, '%u'));
					var arr = JSON.parse(utr);
					var str = '<p>魚名:'+arr[0].fishName+'</p><p>識別數量:'+arr[0].fishQtn+'</p><p>拉丁名:'+arr[0].LatinName+'</p><p>分布地區:'+arr[0].distribution+'</p>';
					outLine(str);
					var tu = '<img src="' + arr[0].processImg + '" width="100%">';
					outimg(tu);
					wt.close();
				}	else {
					outLine("上傳失敗:"+status);
					wt.close();
				}
			}
		);
		task.addFile("cm.jpg",{key:"fileUpload"});
		task.start();
	},function(e){
		plus.nativeUI.closeWaiting();
		outLine("壓縮圖片失敗: "+JSON.stringify(e));
	});
}

接著利用雲打包,將整個應用打包成 apk 上傳到手機上進行安裝,安裝成功後運行,畫面如下。

https://ithelp.ithome.com.tw/upload/images/20210926/20129510ubbPBtY4sO.jpg
圖 2、手機應用執行畫面

在小米手機上,利用拍照功能會產生壓縮圖片失敗的畫面,所以我們現在外面先拍下一張照片,如下圖所示。

https://ithelp.ithome.com.tw/upload/images/20210926/20129510MgKcrC2aWJ.jpg
圖 3、手機拍照圖片

圖片的資訊如下圖所示,有 13.57 MB的空間。

https://ithelp.ithome.com.tw/upload/images/20210926/20129510PO1sPRaEH1.png
圖 4、照片資訊

在應用中透過相冊選取該照片,上傳供 EC2 進行辨識,辨識結果如下圖。

https://ithelp.ithome.com.tw/upload/images/20210926/20129510RTFNczeoyV.jpg
圖 5、辨識結果

而回到 AWS EC2 觀看上傳的圖片,發現上傳的檔案 (cm.jpg) 只有 47 KB左右的空間容量,壓縮了 288 倍。最重要的是,經 ARC 測試的結果,反而是原始檔案是無法辨識的。

https://ithelp.ithome.com.tw/upload/images/20210926/201295104tdMWJVsTE.png
圖 6、上傳的照片資訊

https://ithelp.ithome.com.tw/upload/images/20210926/20129510b7SXdlZtYS.png
圖 7、Advanced REST Client上傳原圖的辨識結果

在手機上操作的感受,辨識的回傳速度不到一秒內就完成,主要是因為上傳的圖片都經過處理了。至此,全端的實作已經算是告一個段落。

參考資料


上一篇
Day 25 - HBuilder X 產生 apk
下一篇
Day 27 - 成本估計與 Amazon DynamoDB
系列文
觀賞魚辨識的YOLO全餐33

尚未有邦友留言

立即登入留言