Search
Loading...
Skip to content

Integrate Mobile Camera

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: showcases
description: "Showcases common use cases of the `imgly_editor` Flutter plugin."
publish_to: 'none'
version: 1.54.0
environment:
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.6
dev_dependencies:
flutter_test:
sdk: flutter
integration_test:
sdk: flutter
flutter_driver:
sdk: flutter
image: ^4.2.0
flutter_lints: ^3.0.0
flutter:
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 only
def 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>