日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Flutter+百度人工智能实现测验值app

發布時間:2025/3/19 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Flutter+百度人工智能实现测验值app 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Flutter 顏值大師

基于 Flutter + 百度人工智能 開發出的一款測顏值的 App。

學習最重要的一點就是:擁有一顆滿懷學習熱情的心

項目核心知識點

1.渲染頭部區域

// 頭部 AppBar 區域 appBar: AppBar(title: Text("人臉識別",// 設置標題文字樣式style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),),// 設置標題居中顯示centerTitle: true, )

2. 渲染多個浮動按鈕

正常情況下,一個頁面中,通過 floatingActionButton 選項,默認只能渲染一個浮動按鈕。 如果需要渲染多個浮動按鈕,可以通過 ButtonBar 控件來實現,代碼示例如下:

floatingActionButton: ButtonBar(// alignment 屬性用來指定子元素如何在橫軸上進行排列// 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. 使用第三方插件實現選擇照片的功能

一些特殊的功能,可以在插件商店中搜索對應的插件,從而輕松實現,插件商店的地址為 https://pub.dev/flutter

  • 在 pubspec.yaml 的 dependencies 節點中,新增插件如下:
  • dependencies:image_picker: ^0.6.7+4
  • 在 lib/main.dart 文件的頭部,導入對應的插件:
  • import 'package:image_picker/image_picker.dart';
  • 在 _MyHomePageState 這個狀態管理類中,定義 _image 私有數據,用來存儲用戶選擇的照片:
  • class _MyHomePageState extends State<MyHomePage> {// 用戶通過攝像頭或圖片庫選擇的照片File _image; }
  • 在 lib/main.dart 文件的頭部,導入 File 類對應的類庫:
  • import 'dart:io';
  • 在 lib/main.dart 中,定義函數 choosePic 來實現選取照片的功能:
  • // 點擊按鈕,選擇圖片 // 形參中的 source 為選取照片的方式,有兩種,分別為: // ImageSource.camera 從相機拍照并得到照片 // ImageSource.gallery 從本地相冊選擇照片 void choosePic(source) async {// 得到選取的照片var image = await ImagePicker.pickImage(source: source);setState(() {_image = image;faceInfo = null;});// 如果選取的照片為空,則不執行后續人臉檢測的業務邏輯if (image == null) {return;} }
  • 在浮動按鈕的 onPressed 事件處理函數中,調用第 5 步中定義的 choosePic 函數,并把選取照片的方式傳遞到函數中:
  • 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),)], )

    4. 把用戶選擇的照片渲染到頁面

  • 將 Scaffold 控件的 body 參數,修改成 renderBody() 函數的調用,通過 renderBody() 函數,返回被渲染的頁面結構,具體代碼如下:
  • @override Widget build(BuildContext context) {return Scaffold(// 頭部 AppBar 區域appBar: AppBar(),// 中間頁面主體區域body: renderBody(),// 浮動按鈕區域floatingActionButton: ButtonBar()) }
  • 定義 renderBody() 函數如下:
  • // 渲染頁面主體區域 Widget renderBody() {// 如果用戶沒有選擇任何圖片,則只渲染文本if (_image == null) {return Center(child: Text('暫無圖片!'),);}// 在頁面上渲染對應的圖片return Stack(children: <Widget>[Image.file(_image, // 被渲染的圖片height: double.infinity, // 圖片高度撐滿整個頁面的高度fit: BoxFit.cover, // 圖片的填充模式)]); }

    5. 申請百度 AI 開放平臺賬號并創建人臉識別的應用

  • 瀏覽器訪問 http://ai.baidu.com/ 后,注冊百度 AI 開放平臺賬號
  • 登錄賬號,并進入控制臺,在左側菜單中選擇 人臉識別 后,點擊 創建應用 按鈕
  • 填寫對應的應用信息后,點擊 立即創建 按鈕,最終獲取到對應的 API Key 和 Secret Key
  • 6. 鑒權認證機制

    如果要成功調用百度 AI 的接口,必須先通過百度的鑒權認證。百度的鑒權認證非常簡單,只要能夠成功獲取到 Access Token,就可以拿著百度頒發給我們的 Access Token 訪問對應的 AI 接口。百度 AI 鑒權的文檔地址為 https://ai.baidu.com/docs#/Auth/top

    7. 通過 dio 發起網絡數據請求

    插件地址 https://pub.dev/packages/dio ,使用步驟如下:

  • 在 pubspec.yaml 的 dependencies 節點中,新增插件如下:
  • dependencies: dio: ^3.0.10
  • 在 lib/main.dart 頭部,引入 dio,并創建實例對象:
  • import 'package:dio/dio.dart'; Dio dio = new Dio();
  • 通過 dio.post() 發起 post 請求,代碼格式如下:
  • // 通過 async 和 await 簡化異步 API 調用方式 void getHttp() async {// 發起 post 請求// 參數1:請求的URL地址【必選】// 參數2:通過請求體發送的數據【可選】// 參數3:請求配置項【可選】var response = await dio.post("請求地址", data: {/* body請求體 */}, options: new Options());// 打印服務器返回的數據print(response.data); }

    8. Toast 提示

  • 在 pubspec.yaml 的 dependencies 節點中,新增插件如下:
  • dependencies:toast: ^0.1.3
  • 在 lib/main.dart 中導入對應的插件:
  • import 'package:toast/toast.dart';
  • 調用 Toast.show() 函數提示消息:
  • // 參數1:提示消息 // 參數2:提示消息多久后自動隱藏 // 參數3:位置 Toast.show("鑒權失敗!", context, duration: Toast.LENGTH_LONG, gravity: Toast.CENTER);

    9. 圖片轉 base64 字符串

    在調用測顏值的 API 期間,需要先把圖片轉為 base64 的字符串,轉換過程如下:

    // 將照片轉換為字節數組 var imageBytes = await image.readAsBytes(); // 將字節數組轉換為 base64 格式的字符串 var imageBase64 = base64Encode(imageBytes);

    10. 為 dio 的 post 請求設置 data 和 options

    在發送 post 請求期間,如果需要設置 body 請求體和 options 配置項,可以參考如下代碼:

    // 請求的URL地址 var testFaceURL = 'https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=' + accessResult.data['access_token'];// 發起請求 var testFaceResult = await dio.post(testFaceURL,// 發送到后臺的 body 數據data: {'image': imageBase64,'image_type': 'BASE64',// face_field 是要獲取的人臉信息字段,// 年齡,性別,顏值,表情,眼鏡,情緒'face_field': 'age,gender,beauty,expression,glasses,emotion'},// 請求配置options: new Options(responseType: ResponseType.json));

    11. 渲染人臉信息

  • 修改 renderBody() 函數,在 Stack 控件中,通過調用 renderFaceInfo() 函數,渲染人臉信息區域:
  • // 渲染頁面主體區域 Widget renderBody() {// 如果用戶沒有選擇任何圖片,則只渲染文本if (_image == null) {return Center(child: Text('暫無圖片!'),);}// 在頁面上渲染對應的圖片return Stack(children: <Widget>[Image.file(_image,height: double.infinity,fit: BoxFit.cover,),// 渲染人臉信息區域 +++ renderFaceInfo()]); }
  • 定義 renderFaceInfo() 函數如下:
  • // 渲染識別出來的人臉信息Widget renderFaceInfo() {// 如果人臉信息為空,則渲染空字符串if (faceInfo == null) {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']]),],)],),),);}
  • 在 _MyHomePageState 狀態管理類中,定義 Map 映射,輔助渲染人臉信息:
  • // 性別 Map genderMap = {'male': '男', 'female': '女'}; // 表情 Map expressionMap = {'none': '不笑', 'smile': '微笑', 'laugh': '大笑'}; // 眼鏡 Map glassesMap = {'none': '無眼鏡', 'common': '普通眼鏡', 'sun': '墨鏡'}; // 情緒 Map emotionMap = {'angry': '憤怒','disgust': '厭惡','fear': '恐懼','happy': '高興','sad': '傷心','surprise': '驚訝','neutral': '無情緒' };

    12. 實現 loading 效果

  • 在 _MyHomePageState 狀態管理類中,定義 isloading 數據如下:
  • class _MyHomePageState extends State<MyHomePage> {// false 為不顯示 loading// true 為顯示 loadingbool isloading = false; }
  • 修改 getFaceInfo() 函數如下,在適當的時機重置 isloading 的值:
  • // 發起請求,獲取人臉信息 void getFaceInfo(image) async {// 只要調用這個函數,就立即展示 loading 效果setState(() {isloading = true;});// 鑒權// ... 省略不必要的代碼// 鑒權失敗if (accessResult.data['access_token'] == null) {// 鑒權失敗,隱藏 loading 效果setState(() {isloading = false;});// ... 省略不必要的代碼return;}// 鑒權成功// 檢測人臉信息// ... 省略不必要的代碼// 檢測失敗if (testFaceResult.data['error_msg'] != 'SUCCESS' ||testFaceResult.data['result']['face_num'] <= 0) {// 檢測失敗,隱藏 loading 效果setState(() {isloading = false;});// ... 省略不必要的代碼return;}// 檢測成功,隱藏 loading 效果setState(() {faceInfo = testFaceResult.data['result']['face_list'][0];isloading = false;}); }
  • 修改 renderFaceInfo() 函數,按需渲染 loading 效果:
  • // 渲染識別出來的人臉信息 Widget renderFaceInfo() {if (faceInfo == null) { ++ //如果 isloading 為 true,就在頁面正中央渲染 loading 效果 ++ if (isloading) { ++ return Center(child: CircularProgressIndicator()); ++ }// 否則,直接渲染空字符串return Text('');}// ... 省略不必要的代碼 }

    全部源碼:

    // 導入依賴項 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> {// 用戶通過攝像頭或圖片庫選擇的照片File _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 區域appBar: AppBar(title: Text("人臉識別",style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),),centerTitle: true,),// 中間頁面主體區域body: renderBody(),// 底部浮動按鈕區域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.);}// 渲染頁面主體區域Widget renderBody() {// 如果用戶沒有選擇任何圖片,則只渲染文本if (_image == null) {return Center(child: Text('暫無圖片!'),);}// 在頁面上渲染對應的圖片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']]),],)],),),);}// 點擊按鈕,選擇圖片void choosePic(source) async {// 得到選取的照片var image = await ImagePicker.pickImage(source: source);setState(() {_image = image;faceInfo = null;});// 如果選取的照片為空,則不執行后續人臉檢測的業務邏輯if (image == null) {return;}// 調用獲取人臉信息的函數getFaceInfo(image);}// 發起請求,獲取人臉信息void getFaceInfo(image) async {setState(() {isloading = true;});// 將照片轉換為字節數組var imageBytes = await image.readAsBytes();// 將字節數組轉換為 base64 格式的字符串var imageBase64 = base64Encode(imageBytes);// 人工智能API接口鑒權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("鑒權失敗!", context,duration: Toast.LENGTH_LONG, gravity: Toast.CENTER);return;}// 發起請求,獲取檢測結果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);} }

    總結

    以上是生活随笔為你收集整理的Flutter+百度人工智能实现测验值app的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。