Flutter+百度人工智能实现测验值app
Flutter 顏值大師
基于 Flutter + 百度人工智能 開發(fā)出的一款測顏值的 App。
學(xué)習(xí)最重要的一點(diǎn)就是:擁有一顆滿懷學(xué)習(xí)熱情的心
項(xiàng)目核心知識點(diǎn)
1.渲染頭部區(qū)域
// 頭部 AppBar 區(qū)域 appBar: AppBar(title: Text("人臉識別",// 設(shè)置標(biāo)題文字樣式style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),),// 設(shè)置標(biāo)題居中顯示centerTitle: true, )2. 渲染多個浮動按鈕
正常情況下,一個頁面中,通過 floatingActionButton 選項(xiàng),默認(rèn)只能渲染一個浮動按鈕。 如果需要渲染多個浮動按鈕,可以通過 ButtonBar 控件來實(shí)現(xiàn),代碼示例如下:
floatingActionButton: ButtonBar(// alignment 屬性用來指定子元素如何在橫軸上進(jìn)行排列// MainAxisAlignment.spaceAround 表示分散對齊alignment: MainAxisAlignment.spaceAround,// 子元素children: <Widget>[// 第一個浮動按鈕FloatingActionButton(onPressed: () {},tooltip: 'takephoto',child: Icon(Icons.photo_camera),),// 第二個浮動按鈕FloatingActionButton(onPressed: () {},tooltip: 'takepicture',child: Icon(Icons.photo_library),)], )3. 使用第三方插件實(shí)現(xiàn)選擇照片的功能
一些特殊的功能,可以在插件商店中搜索對應(yīng)的插件,從而輕松實(shí)現(xiàn),插件商店的地址為 https://pub.dev/flutter
4. 把用戶選擇的照片渲染到頁面
5. 申請百度 AI 開放平臺賬號并創(chuàng)建人臉識別的應(yīng)用
6. 鑒權(quán)認(rèn)證機(jī)制
如果要成功調(diào)用百度 AI 的接口,必須先通過百度的鑒權(quán)認(rèn)證。百度的鑒權(quán)認(rèn)證非常簡單,只要能夠成功獲取到 Access Token,就可以拿著百度頒發(fā)給我們的 Access Token 訪問對應(yīng)的 AI 接口。百度 AI 鑒權(quán)的文檔地址為 https://ai.baidu.com/docs#/Auth/top
7. 通過 dio 發(fā)起網(wǎng)絡(luò)數(shù)據(jù)請求
插件地址 https://pub.dev/packages/dio ,使用步驟如下:
8. Toast 提示
9. 圖片轉(zhuǎn) base64 字符串
在調(diào)用測顏值的 API 期間,需要先把圖片轉(zhuǎn)為 base64 的字符串,轉(zhuǎn)換過程如下:
// 將照片轉(zhuǎn)換為字節(jié)數(shù)組 var imageBytes = await image.readAsBytes(); // 將字節(jié)數(shù)組轉(zhuǎn)換為 base64 格式的字符串 var imageBase64 = base64Encode(imageBytes);10. 為 dio 的 post 請求設(shè)置 data 和 options
在發(fā)送 post 請求期間,如果需要設(shè)置 body 請求體和 options 配置項(xiàng),可以參考如下代碼:
// 請求的URL地址 var testFaceURL = 'https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=' + accessResult.data['access_token'];// 發(fā)起請求 var testFaceResult = await dio.post(testFaceURL,// 發(fā)送到后臺的 body 數(shù)據(jù)data: {'image': imageBase64,'image_type': 'BASE64',// face_field 是要獲取的人臉信息字段,// 年齡,性別,顏值,表情,眼鏡,情緒'face_field': 'age,gender,beauty,expression,glasses,emotion'},// 請求配置options: new Options(responseType: ResponseType.json));11. 渲染人臉信息
12. 實(shí)現(xiàn) loading 效果
全部源碼:
// 導(dǎo)入依賴項(xiàng) import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'dart:io'; import 'dart:convert'; import 'package:dio/dio.dart'; import 'package:toast/toast.dart';Dio dio = new Dio();class MyFacePage extends StatefulWidget {MyFacePage({Key key,}) : super(key: key);@override_MyFacePageState createState() => _MyFacePageState(); }class _MyFacePageState extends State<MyFacePage> {// 用戶通過攝像頭或圖片庫選擇的照片F(xiàn)ile _image;var faceInfo;bool isloading = false;Map genderMap = {'male': '男', 'female': '女'};Map expressionMap = {'none': '不笑', 'smile': '微笑', 'laugh': '大笑'};Map glassesMap = {'none': '無眼鏡', 'common': '普通眼鏡', 'sun': '墨鏡'};Map emotionMap = {'angry': '憤怒','disgust': '厭惡','fear': '恐懼','happy': '高興','sad': '傷心','surprise': '驚訝','neutral': '無情緒'};@overrideWidget build(BuildContext context) {return Scaffold(// 頭部 AppBar 區(qū)域appBar: AppBar(title: Text("人臉識別",style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),),centerTitle: true,),// 中間頁面主體區(qū)域body: renderBody(),// 底部浮動按鈕區(qū)域floatingActionButton: ButtonBar(alignment: MainAxisAlignment.spaceAround,children: <Widget>[FloatingActionButton(onPressed: () {choosePic(ImageSource.camera);},tooltip: 'takephoto',child: Icon(Icons.photo_camera),),FloatingActionButton(onPressed: () {choosePic(ImageSource.gallery);},tooltip: 'takepicture',child: Icon(Icons.photo_library),)],), // This trailing comma makes auto-formatting nicer for build methods.);}// 渲染頁面主體區(qū)域Widget renderBody() {// 如果用戶沒有選擇任何圖片,則只渲染文本if (_image == null) {return Center(child: Text('暫無圖片!'),);}// 在頁面上渲染對應(yīng)的圖片return Stack(children: <Widget>[Image.file(_image,height: double.infinity,fit: BoxFit.cover,),renderFaceInfo()],);}// 渲染識別出來的人臉信息Widget renderFaceInfo() {if (faceInfo == null) {if (isloading) {return Center(child: CircularProgressIndicator());}return Text('');}return Center(child: Container(decoration: BoxDecoration(// 背景顏色color: Colors.white54,// 圓角borderRadius: BorderRadius.all(Radius.circular(5))),width: 300,height: 200,child: Column(mainAxisAlignment: MainAxisAlignment.spaceAround,children: <Widget>[Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: <Widget>[Text('年齡:${faceInfo['age']}歲'),Text('性別:' + genderMap[faceInfo['gender']['type']]),],),Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: <Widget>[Text('顏值:${faceInfo['beauty']}分'),Text('表情:' + expressionMap[faceInfo['expression']['type']]),],),Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: <Widget>[Text('眼鏡:' + glassesMap[faceInfo['glasses']['type']]),Text('情緒:' + emotionMap[faceInfo['emotion']['type']]),],)],),),);}// 點(diǎn)擊按鈕,選擇圖片void choosePic(source) async {// 得到選取的照片var image = await ImagePicker.pickImage(source: source);setState(() {_image = image;faceInfo = null;});// 如果選取的照片為空,則不執(zhí)行后續(xù)人臉檢測的業(yè)務(wù)邏輯if (image == null) {return;}// 調(diào)用獲取人臉信息的函數(shù)getFaceInfo(image);}// 發(fā)起請求,獲取人臉信息void getFaceInfo(image) async {setState(() {isloading = true;});// 將照片轉(zhuǎn)換為字節(jié)數(shù)組var imageBytes = await image.readAsBytes();// 將字節(jié)數(shù)組轉(zhuǎn)換為 base64 格式的字符串var imageBase64 = base64Encode(imageBytes);// 人工智能API接口鑒權(quán)var accessURL ="https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=o631j8eLGBQq88uj8IXsVeGO&client_secret=Pses7CgBpF5Hf9owM6N8v8iX6iLAP7G5";var accessResult = await dio.post(accessURL);// 判斷是否獲取到了access_tokenif (accessResult.data['access_token'] == null) {setState(() {isloading = false;});Toast.show("鑒權(quán)失敗!", context,duration: Toast.LENGTH_LONG, gravity: Toast.CENTER);return;}// 發(fā)起請求,獲取檢測結(jié)果var testFaceURL ='https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=' +accessResult.data['access_token'];var testFaceResult = await dio.post(testFaceURL,data: {'image': imageBase64,'image_type': 'BASE64','face_field': 'age,gender,beauty,expression,glasses,emotion'},options: new Options(responseType: ResponseType.json));// print(testFaceResult.data);// 識別失敗if (testFaceResult.data['error_msg'] != 'SUCCESS' ||testFaceResult.data['result']['face_num'] <= 0) {setState(() {isloading = false;});Toast.show("人臉識別失敗!", context,duration: Toast.LENGTH_LONG, gravity: Toast.CENTER);return;}// 識別成功setState(() {faceInfo = testFaceResult.data['result']['face_list'][0];isloading = false;});print(faceInfo);} }總結(jié)
以上是生活随笔為你收集整理的Flutter+百度人工智能实现测验值app的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Flutter 调用地图软件(高德、百度
- 下一篇: flutter中state详解