詳解Android?Flutter如何使用相機(jī)實(shí)現(xiàn)拍攝照片
簡介
在app中使用相機(jī)肯定是再平常不過的一項(xiàng)事情了,相機(jī)肯定涉及到了底層原生代碼的調(diào)用,那么在flutter中如何快速簡單的使用上相機(jī)的功能呢?
一起來看看吧。
使用相機(jī)前的準(zhǔn)備工作
flutter中為使用camera提供了一個(gè)叫做camera的插件,我們首先需要安裝這個(gè)插件。
安裝插件的步驟很簡單,如下所示:
flutter pub add camera
該命令會(huì)在pubspec.xml中添加下面的內(nèi)容:
dependencies: flutter: sdk: flutter camera: ^0.10.0+1
除了camera之外,我們還需要對(duì)照相機(jī)拍攝的照片進(jìn)行保存,這樣我們還需要用到path_provider和path這兩個(gè)plugin。
我們使用同樣的方式對(duì)這兩個(gè)插件進(jìn)行安裝。
安裝好之后,我們就可以在flutter中的代碼中愉快的使用camera了。
在使用camera之前,我們還需要獲取相應(yīng)的權(quán)限信息,比如在IOS中,我們需要在 ios/Runner/Info.plist中添加下面的權(quán)限信息:
<key>NSCameraUsageDescription</key> <string>flutter需要用到你的照相機(jī)</string>
在andorid中需要配合minSdkVersion>=21來使用。
在flutter中使用camera
camera插件為我們提供了一系列的功能來方便camera的使用。
camera的使用需要遵循下面的步驟,因?yàn)楝F(xiàn)在的手機(jī)可能會(huì)有多個(gè)攝像頭,所以我們需要通過api獲取到可以使用的攝像頭列表。
接下來我們使用選中的攝像頭,進(jìn)行一些控制操作,然后需要使用相應(yīng)的camera視圖來展示相應(yīng)的照相機(jī)圖像.
最后調(diào)用攝像頭相關(guān)的拍攝功能進(jìn)行拍攝。
聽起來好像挺復(fù)雜的,事實(shí)上只要遵照上面的順序,一切都是非常簡單的。
首先我們需要獲取可用的攝像頭列表,這個(gè)步驟是通過調(diào)用camera包中的availableCameras方法來實(shí)現(xiàn)的:
Future<List<CameraDescription>> availableCameras() async { return CameraPlatform.instance.availableCameras(); }
availableCameras是一個(gè)異步方法,返回的是一個(gè)Future對(duì)象,其中的值是CameraDescription列表。
CameraDescription是對(duì)camera的描述文件:
const CameraDescription({ required this.name, required this.lensDirection, required this.sensorOrientation, });
name是攝像頭的名稱,lensDirection是攝像頭面對(duì)的方向,sensorOrientation是傳感器的方向,也就說你的手機(jī)是正常放置,還是選擇90度放置。
因?yàn)閍vailableCameras是一個(gè)異步方法,所以我們需要把它包裹在一個(gè)異步方法中進(jìn)行調(diào)用:
Future<void> main() async { // 保證所有的插件都加載完畢 WidgetsFlutterBinding.ensureInitialized(); //獲取攝像頭列表 final cameras = await availableCameras(); //拿到第一個(gè)攝像頭 final firstCamera = cameras.first; ....
這里我們拿到了第一個(gè)攝像頭,注意,這里的firstCamera是一個(gè)CameraDescription對(duì)象。
因?yàn)槟M器上沒有攝像頭,如果你是在模擬器上運(yùn)行上面的程序的話,將會(huì)拋出下面的異常:
[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: No element
#0 List.first (dart:core-patch/growable_array.dart:343:5)
為了對(duì)這個(gè)camra進(jìn)行控制, 我們需要?jiǎng)?chuàng)建一個(gè)CameraController對(duì)象:
class CameraAppState extends State<CameraApp> { late CameraController _controller; late Future<void> _initializeControllerFuture; @override void initState() { super.initState(); _controller = CameraController( widget.camera, ResolutionPreset.medium, ); _initializeControllerFuture = _controller.initialize(); }
CameraController的構(gòu)造函數(shù)需要一個(gè)CameraDescription對(duì)象和分辨率等信息,并且還需要進(jìn)行初始化,這里我們調(diào)用了它的initialize方法。
這里的initialize方法也是一個(gè)異步方法。
為了在CameraController初始化之后再對(duì)Camera進(jìn)行使用,我們需要在返回的widget中使用FutureBuilder來構(gòu)建:
body: FutureBuilder<void>( future: _initializeControllerFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { return CameraPreview(_controller); } else { return const Center(child: CircularProgressIndicator()); } }, )
具體要展示什么內(nèi)容呢?這里使用的是camera包中自帶的CameraPreview組件。
CameraPreview需要傳入一個(gè)CameraController對(duì)象,也就是之前我們創(chuàng)建的對(duì)象。
最后就是調(diào)用CameraController的方法進(jìn)行拍照了。我們把拍照的邏輯放在floatingActionButton中,如下所示:
floatingActionButton: FloatingActionButton( onPressed: () async { try { await _initializeControllerFuture; final image = await _controller.takePicture(); if (!mounted) return; await Navigator.of(context).push( MaterialPageRoute( builder: (context) => DisplayPictureScreen( imagePath: image.path, ), ), ); } catch (e) { print(e); } }, child: const Icon(Icons.camera_alt), )
具體的邏輯就是調(diào)用controller.takePicture方法進(jìn)行拍照。將拍好照的image放在一個(gè)新的widget中展示。
總結(jié)
攝像頭是app中常用的功能,flutter中的camera插件為我們提供了攝像頭的控制功能,非常簡單。
本文的例子:https://github.com/ddean2009/learn-flutter.git
到此這篇關(guān)于詳解Android Flutter如何使用相機(jī)實(shí)現(xiàn)拍攝照片的文章就介紹到這了,更多相關(guān)Android Flutter相機(jī)拍攝照片內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android Studio Gradle插件版本與Gradle版本之間的對(duì)應(yīng)關(guān)系
今天小編就為大家分享一篇關(guān)于Android Studio Gradle插件版本與Gradle版本之間的對(duì)應(yīng)關(guān)系,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12Android開發(fā)中多進(jìn)程共享數(shù)據(jù)簡析
這篇文章主要為大家簡單分析Android開發(fā)中多進(jìn)程共享數(shù)據(jù),怎么做才能讓這兩邊共享數(shù)據(jù),感興趣的小伙伴們可以參考一下2016-04-04淺談RecyclerView(完美替代ListView,GridView)
RecyclerView絕對(duì)是一款功能強(qiáng)大的控件,涵蓋了ListView,GridView,瀑布流等數(shù)據(jù)表現(xiàn)的形式。本文對(duì)其進(jìn)行系統(tǒng)介紹,有需要的朋友可以看下2016-12-12解析Android開發(fā)優(yōu)化之:對(duì)界面UI的優(yōu)化詳解(三)
本篇文章主要討論一下復(fù)雜界面中常用的一種技術(shù)——界面延遲加載技術(shù)2013-05-05Flutter模仿實(shí)現(xiàn)微信底部導(dǎo)航欄流程詳解
這篇文章主要介紹了Flutter模仿實(shí)現(xiàn)微信底部導(dǎo)航欄流程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-05-05Flutter實(shí)現(xiàn)底部導(dǎo)航欄創(chuàng)建詳解
ConvexBottomBar是一個(gè)底部導(dǎo)航欄組件,用于展現(xiàn)凸起的TAB效果,支持多種內(nèi)置樣式與動(dòng)畫交互。本文將利用ConvexBottomBar創(chuàng)建漂亮的底部導(dǎo)航欄,感興趣的可以學(xué)習(xí)一下2022-01-01