In this example, we will show you how to initialize the Camera SDK’s mobile editor in your Flutter app. We also prepared a dedicated example application which you can checkout on GitHub.
Requirements#
For this version, the minimum requirements are:
- Flutter: 3.16.0
- Dart: 2.12.0
- iOS: 16
- Swift: 5.10 (Xcode 15.4)
- Android: 7
Add from pub.dev#
Add the imgly_camera
Flutter plugin to your projects pubspec.yaml
.
imgly_camera: 1.54.0
Android Setup#
In order to integrate the camera for Android, you will need to make some adjustments to your Android configuration. First, update your android/app/build.gradle
file with the following settings:
- Add IMG.LY maven repository in the
android/build.gradle
file.
maven { url "https://artifactory.img.ly/artifactory/maven" }
- Ensure the
minSdkVersion
is set to 24 (Android 7) or later.
minSdk = 24
- If needed, update the Kotlin version to
1.9.10
or any other compatible version. - Add
gradle.ext.kotlinCompilerExtensionVersion
if you are using Kotlin <2.0.0
. The specified version should match the Kotlin version. Use the official compatibility map in here.
gradle.ext.kotlinCompilerExtensionVersion = "1.5.3"
iOS Setup#
In order to integrate the camera for iOS, you will need to make some adjustments to your ios/Runner/Info.plist
file:
- Add a camera usage permissions description (
NSCameraUsageDescription
).
import 'package:flutter/material.dart';import 'package:imgly_camera/imgly_camera.dart';
- Add a microphone usage permissions description (
NSMicrophoneUsageDescription
).
import 'package:flutter/material.dart';import 'package:imgly_camera/imgly_camera.dart';
Usage#
In this example, we’ll demonstrate the basic usage of the camera.
In order to launch the camera, an instance of CameraSettings
needs to be provided. For this, you only need to provide the license
key that you received from IMG.LY.
Optionally, you can provide a unique ID tied to your application’s user. This helps us accurately calculate monthly active users (MAU) and it is especially useful when one person uses the app on multiple devices with a sign-in feature, ensuring they’re counted once.
final settings = CameraSettings( license: "YOUR_LICENSE", // Your license key here userId: "YOUR_USER_ID", // Optional: Your user ID here);
Next, you can open the editor using the IMGLYCamera.openCamera
method.
final result = await IMGLYCamera.openCamera(settings);
That is all. For more than basic configuration, check out all the available configurations.
Full Code#
Here’s the full code for the various files.
pubspec.yaml#
name: showcasesdescription: "Showcases common use cases of the `imgly_editor` Flutter plugin."publish_to: 'none'version: 1.54.0environment: sdk: '>=3.4.3 <4.0.0'dependencies: flutter: sdk: flutter imgly_editor: 1.54.0 imgly_camera: 1.54.0 cupertino_icons: ^1.0.6dev_dependencies: flutter_test: sdk: flutter integration_test: sdk: flutter flutter_driver: sdk: flutter image: ^4.2.0 flutter_lints: ^3.0.0flutter: uses-material-design: true assets: - assets/
android/build.gradle#
allprojects { repositories { google() mavenCentral() maven { url "https://artifactory.img.ly/artifactory/maven" } }}
rootProject.buildDir = "../build"subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}"}subprojects { project.evaluationDependsOn(":app")}
tasks.register("clean", Delete) { delete rootProject.buildDir}
android/app/build.gradle#
plugins { id "com.android.application" id "kotlin-android" // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. id "dev.flutter.flutter-gradle-plugin" id 'com.github.gmazzo.buildconfig'}
def localProperties = new Properties()def localPropertiesFile = rootProject.file("local.properties")if (localPropertiesFile.exists()) { localPropertiesFile.withReader("UTF-8") { reader -> localProperties.load(reader) }}
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")if (flutterVersionCode == null) { flutterVersionCode = "1"}
def flutterVersionName = localProperties.getProperty("flutter.versionName")if (flutterVersionName == null) { flutterVersionName = "1.0"}
buildConfig { className "ShowcasesFlutterBuildConfig" packageName "ly.img.editor.flutter" buildConfigField String, "UNSPLASH_HOST", System.env.CESDK_AND_UNSPLASH_HOST ?: localProperties.getProperty("unsplash_host") ?: ""}
android { namespace = "ly.img.editor.flutter.showcases" compileSdk = 35 // flutter.compileSdkVersion is 34, remove hardcode when flutter updates this value ndkVersion = flutter.ndkVersion
compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 }
defaultConfig { applicationId = "ly.img.editor.flutter.showcases" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdk = 24 targetSdk = 35 // flutter.targetSdkVersion is 34, remove hardcode when flutter updates this value versionCode = flutterVersionCode.toInteger() versionName = flutterVersionName }
signingConfigs { release { storeFile rootProject.file("android-release.keystore") storePassword System.getenv("CESDK_AND_KEYSTORE_PWD") ?: localProperties.getProperty("release_key_password") keyAlias "cesdk-dev" keyPassword System.getenv("CESDK_AND_KEYSTORE_PWD") ?: localProperties.getProperty("release_key_password") } }
buildTypes { release { def shrinkAndMinifyEnabled = System.getenv("CESDK_SHRINK_AND_MINIFY_ENABLED") == null || System.getenv("CESDK_SHRINK_AND_MINIFY_ENABLED") == "true" signingConfig signingConfigs.release minifyEnabled shrinkAndMinifyEnabled shrinkResources shrinkAndMinifyEnabled } }
kotlinOptions { jvmTarget = "1.8" }
buildFeatures { compose true }
composeOptions { kotlinCompilerExtensionVersion = "1.5.3" }}
dependencies { implementation "ly.img:camera:1.54.0" implementation "ly.img:editor:1.54.0" implementation "androidx.compose:compose-bom:2023.05.01" implementation "androidx.activity:activity-compose:1.6.1"}
flutter { source = "../.."}
settings.gradle#
pluginManagement { def flutterSdkPath = { def properties = new Properties() file("local.properties").withInputStream { properties.load(it) } def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" return flutterSdkPath }()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories { google() mavenCentral() gradlePluginPortal() }}
plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "com.android.application" version "8.6.1" apply false id "com.android.library" version "8.6.1" apply false id 'org.jetbrains.kotlin.android' version "1.9.10" apply false id 'com.github.gmazzo.buildconfig' version "5.3.5" apply false}
gradle.ext.kotlinCompilerExtensionVersion = "1.5.3"
rootProject.name = "CE.SDK Flutter Android Examples"include ":app"
// Internal use onlydef ubqRootPath = "../../../../"def useLocalEditor = System.getenv("UBQ_USE_LOCAL_EDITOR") == "true" || getLocalProperty("useLocalEditor") == "true"
String getLocalProperty(String key) { def propertiesFile = new File(rootDir, "local.properties") if (!propertiesFile.exists()) return false def properties = new Properties() properties.load(propertiesFile.newDataInputStream()) return properties.getProperty(key)}
if (useLocalEditor) { includeBuild("$ubqRootPath/apps/cesdk_android") { name "editor" dependencySubstitution { substitute module('ly.img:editor') using project(':editor') substitute module('ly.img:camera') using project(':camera') } }}// Internal use only
camera_flutter.dart#
import 'package:flutter/material.dart';import 'package:imgly_camera/imgly_camera.dart';
class CameraFlutter { /// Opens the camera. void openCamera() async { final settings = CameraSettings( license: "YOUR_LICENSE", // Your license key here userId: "YOUR_USER_ID", // Optional: Your user ID here );
final result = await IMGLYCamera.openCamera(settings); }}
Info.plist#
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict> <key>CADisableMinimumFrameDurationOnPhone</key> <true/> <key>CFBundleDevelopmentRegion</key> <string>$(DEVELOPMENT_LANGUAGE)</string> <key>CFBundleDisplayName</key> <string>Showcases</string> <key>CFBundleExecutable</key> <string>$(EXECUTABLE_NAME)</string> <key>CFBundleIdentifier</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>showcases</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>$(FLUTTER_BUILD_NAME)</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>$(FLUTTER_BUILD_NUMBER)</string> <key>DART_DEFINES</key> <string>$(DART_DEFINES)</string> <key>LSRequiresIPhoneOS</key> <true/> <key>NSCameraUsageDescription</key> <string>This app uses the camera for demonstration purposes.</string> <key>NSMicrophoneUsageDescription</key> <string>This app uses the camera for demonstration purposes.</string> <key>UIApplicationSupportsIndirectInputEvents</key> <true/> <key>UILaunchStoryboardName</key> <string>LaunchScreen</string> <key>UIMainStoryboardFile</key> <string>Main</string> <key>UISupportedInterfaceOrientations</key> <array> <string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeRight</string> </array> <key>UISupportedInterfaceOrientations~ipad</key> <array> <string>UIInterfaceOrientationPortrait</string> <string>UIInterfaceOrientationPortraitUpsideDown</string> <string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeRight</string> </array></dict></plist>