A Flutter plugin for iOS and Android for picking images from the image library, and taking new pictures with the camera.
Note: This plugin is still under development, and some APIs might not be available yet. Feedback welcome and Pull Requests are most welcome!
First, add image_picker
as a dependency in your pubspec.yaml file.
Add the following keys to your Info.plist file, located in <project root>/ios/Runner/Info.plist
:
NSPhotoLibraryUsageDescription
- describe why your app needs permission for the photo library. This is called Privacy - Photo Library Usage Description in the visual editor.NSCameraUsageDescription
- describe why your app needs access to the camera. This is called Privacy - Camera Usage Description in the visual editor.NSMicrophoneUsageDescription
- describe why your app needs access to the microphone, if you intend to record videos. This is called Privacy - Microphone Usage Description in the visual editor.No configuration required - the plugin should work out of the box.
import 'package:image_picker/image_picker.dart';
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
File _image;
Future getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.camera);
setState(() {
_image = image;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Image Picker Example'),
),
body: new Center(
child: _image == null
? new Text('No image selected.')
: new Image.file(_image),
),
floatingActionButton: new FloatingActionButton(
onPressed: getImage,
tooltip: 'Pick Image',
child: new Icon(Icons.add_a_photo),
),
);
}
}
com.android.support:appcompat-v7
dependency with com.android.support:support-core-utils
, which results in smaller APK sizes.pickVideo
method will now return null when the user cancels picking a video.pickImage
method will now return null when the user cancels picking the image, instead of hanging indefinitely.source
parameter for the pickImage
is now required. Also, the ImageSource.any
option doesn't exist anymore.ImageSource.camera
.android/build.gradle
. For example:allprojects {
repositories {
jcenter()
maven { // NEW
url "https://maven.google.com" // NEW
} // NEW
}
}
example/lib/main.dart
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:video_player/video_player.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Image Picker Demo',
home: new MyHomePage(title: 'Image Picker Example'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<File> _imageFile;
bool isVideo = false;
VideoPlayerController _controller;
VoidCallback listener;
void _onImageButtonPressed(ImageSource source) {
setState(() {
if (_controller != null) {
_controller.setVolume(0.0);
_controller.removeListener(listener);
}
if (isVideo) {
ImagePicker.pickVideo(source: source).then((File file) {
if (file != null && mounted) {
setState(() {
_controller = VideoPlayerController.file(file)
..addListener(listener)
..setVolume(1.0)
..initialize()
..setLooping(true)
..play();
});
}
});
} else {
_imageFile = ImagePicker.pickImage(source: source);
}
});
}
@override
void deactivate() {
if (_controller != null) {
_controller.setVolume(0.0);
_controller.removeListener(listener);
}
super.deactivate();
}
@override
void dispose() {
if (_controller != null) {
_controller.dispose();
}
super.dispose();
}
@override
void initState() {
super.initState();
listener = () {
setState(() {});
};
}
Widget _previewVideo(VideoPlayerController controller) {
if (controller == null) {
return const Text(
'You have not yet picked a video',
textAlign: TextAlign.center,
);
} else if (controller.value.initialized) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: AspectRatioVideo(controller),
);
} else {
return const Text(
'Error Loading Video',
textAlign: TextAlign.center,
);
}
}
Widget _previewImage() {
return FutureBuilder<File>(
future: _imageFile,
builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.data != null) {
return Image.file(snapshot.data);
} else if (snapshot.error != null) {
return const Text(
'Error picking image.',
textAlign: TextAlign.center,
);
} else {
return const Text(
'You have not yet picked an image.',
textAlign: TextAlign.center,
);
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: isVideo ? _previewVideo(_controller) : _previewImage(),
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
onPressed: () {
isVideo = false;
_onImageButtonPressed(ImageSource.gallery);
},
heroTag: 'image0',
tooltip: 'Pick Image from gallery',
child: const Icon(Icons.photo_library),
),
Padding(
padding: const EdgeInsets.only(top: 16.0),
child: FloatingActionButton(
onPressed: () {
isVideo = false;
_onImageButtonPressed(ImageSource.camera);
},
heroTag: 'image1',
tooltip: 'Take a Photo',
child: const Icon(Icons.camera_alt),
),
),
Padding(
padding: const EdgeInsets.only(top: 16.0),
child: FloatingActionButton(
backgroundColor: Colors.red,
onPressed: () {
isVideo = true;
_onImageButtonPressed(ImageSource.gallery);
},
heroTag: 'video0',
tooltip: 'Pick Video from gallery',
child: const Icon(Icons.video_library),
),
),
Padding(
padding: const EdgeInsets.only(top: 16.0),
child: FloatingActionButton(
backgroundColor: Colors.red,
onPressed: () {
isVideo = true;
_onImageButtonPressed(ImageSource.camera);
},
heroTag: 'video1',
tooltip: 'Take a Video',
child: const Icon(Icons.videocam),
),
),
],
),
);
}
}
class AspectRatioVideo extends StatefulWidget {
final VideoPlayerController controller;
AspectRatioVideo(this.controller);
@override
AspectRatioVideoState createState() => new AspectRatioVideoState();
}
class AspectRatioVideoState extends State<AspectRatioVideo> {
VideoPlayerController get controller => widget.controller;
bool initialized = false;
VoidCallback listener;
@override
void initState() {
super.initState();
listener = () {
if (!mounted) {
return;
}
if (initialized != controller.value.initialized) {
initialized = controller.value.initialized;
setState(() {});
}
};
controller.addListener(listener);
}
@override
Widget build(BuildContext context) {
if (initialized) {
final Size size = controller.value.size;
return new Center(
child: new AspectRatio(
aspectRatio: size.width / size.height,
child: new VideoPlayer(controller),
),
);
} else {
return new Container();
}
}
}
Add this to your package's pubspec.yaml file:
dependencies:
image_picker: ^0.4.8
You can install packages from the command line:
with Flutter:
$ flutter packages get
Alternatively, your editor might support flutter packages get
.
Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:image_picker/image_picker.dart';
Version | Uploaded | Documentation | Archive |
---|---|---|---|
0.5.0+3 | Feb 8, 2019 |
|
|
0.5.0+2 | Feb 8, 2019 |
|
|
0.5.0+1 | Jan 31, 2019 |
|
|
0.5.0 | Jan 24, 2019 |
|
|
0.4.12+1 | Jan 18, 2019 |
|
|
0.4.12 | Jan 10, 2019 |
|
|
0.4.10 | Aug 30, 2018 |
|
|
0.4.8 | Aug 28, 2018 |
|
|
0.4.7 | Aug 21, 2018 |
|
|
0.4.6 | Jul 26, 2018 |
|
|
Popularity:
Describes how popular the package is relative to other packages.
[more]
|
100
|
Health:
Code health derived from static analysis.
[more]
|
100
|
Maintenance:
Reflects how tidy and up-to-date the package is.
[more]
|
100
|
Overall:
Weighted score of the above.
[more]
|
100
|
We analyzed this package on Feb 14, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:
Detected platforms: Flutter
References Flutter, and has no conflicting libraries.
Package | Constraint | Resolved | Available |
---|---|---|---|
Direct dependencies | |||
Dart SDK | >=2.0.0-dev.28.0 <3.0.0 | ||
flutter | 0.0.0 | ||
Transitive dependencies | |||
collection | 1.14.11 | ||
meta | 1.1.6 | 1.1.7 | |
sky_engine | 0.0.99 | ||
typed_data | 1.1.6 | ||
vector_math | 2.0.8 | ||
Dev dependencies | |||
flutter_test | |||
video_player | 0.5.2 |