How to integrate a Photo Editor into your Android app

6-minute Video Tutorial


6 min read
How to integrate a Photo Editor into your Android app
As developer friendliness is paramount to us, we created a short video tutorial to guide you through our integration process. We created similar tutorials for iOS and HTML5, so make sure to check those out as well.(Please make sure to get a trial license for the PhotoEditor SDK before integrating it.)

Video Transcript

Today we’re going to show you how to integrate the PhotoEditor SDK into your Android app. We’re going to need Android Studio and the PhotoEditor SDK’s documentation to do so.

First, we’re going to launch a new Android Studio project. Here, we can choose a name for our application. Then, we’re going to insert our company domain and our package name. Inserting a package name is very important as you need a license that is issued for your specific package name to run the PhotoEditor SDK.

We’re also going to include Kotlin support, as every modern Android app should do that.

We then choose Phone and Tablet and API 16 because this is the oldest API that the SDK currently supports. Please note, that this is eventually going to change.

We then choose Empty Activity. Here you can set a name. For this tutorial, however, we’re going to leave it as it is.

Now, a new Android Studio project is created.

For the sake of clarity, we’re going to use the project view.

First, we have to include the license. To do so, we open the PhotoeditorApp folder and navigate through the subfolders app, src and main. In this subfolder, we create yet another folder called assets. We then simply paste our license into it.

We head over to the documentation, find the section for Android and make sure that the latest version is selected. As of the time of this recording that is version 6 or V6. Then we navigate to the “Getting Started” section. Here you can also look up how to include the license. We head over to the project’s build.gradle file and paste this line which is the path to our SDK repository under buildscript and repositories.

maven { url 'https://artifactory.img.ly/artifactory/imgly' }

We then copy this line and paste it under dependencies, and thus, we have linked the SDK.

classpath 'ly.img.android.pesdk:plugin:6.0.8'

Next, we’re going to apply the PESDK plugin. So, we find the app’s build.gradle folder and paste this line under the other plugins.

apply plugin: 'ly.img.android.pesdk'

Now, we’re going to insert the PhotoEditor SDK’s configuration that contains all tools. We copy this block and paste it under the PESDK plugin. It is important that the license naming here matches the name of the license file we previously imported.

pesdkConfig {

    licencePath "LICENSE" // Name of the Licence file in the asset folder

    // If you use another supportLibVersion ('com.android.support'), change this version here to update your own supportLibVersion
    supportLibVersion "27.1.1"

    // Define the modules you need
    modules {
        // Add all the backend modules you need
        include 'ly.img.android.pesdk.operation:text'
        include 'ly.img.android.pesdk.operation:frame'
        include 'ly.img.android.pesdk.operation:focus'
        include 'ly.img.android.pesdk.operation:brush'
        include 'ly.img.android.pesdk.operation:camera'
        include 'ly.img.android.pesdk.operation:filter'
        include 'ly.img.android.pesdk.operation:sticker'
        include 'ly.img.android.pesdk.operation:overlay'
        include 'ly.img.android.pesdk.operation:adjustment'
        include 'ly.img.android.pesdk.operation:text-design'
        include 'ly.img.android.pesdk.operation:abstract-sticker'

        // Add all the UI modules you need
        include 'ly.img.android.pesdk.ui.mobile_ui:core'
        include 'ly.img.android.pesdk.ui.mobile_ui:text'
        include 'ly.img.android.pesdk.ui.mobile_ui:focus'
        include 'ly.img.android.pesdk.ui.mobile_ui:frame'
        include 'ly.img.android.pesdk.ui.mobile_ui:brush'
        include 'ly.img.android.pesdk.ui.mobile_ui:filter'
        include 'ly.img.android.pesdk.ui.mobile_ui:camera'
        include 'ly.img.android.pesdk.ui.mobile_ui:sticker'
        include 'ly.img.android.pesdk.ui.mobile_ui:overlay'
        include 'ly.img.android.pesdk.ui.mobile_ui:transform'
        include 'ly.img.android.pesdk.ui.mobile_ui:adjustment'
        include 'ly.img.android.pesdk.ui.mobile_ui:text-design'


        // Add the serializer if you want
        include 'ly.img.android.pesdk:serializer'

        // Add asset packs if you want
        include 'ly.img.android.pesdk.assets:font-basic'
        include 'ly.img.android.pesdk.assets:font-text-design'
        include 'ly.img.android.pesdk.assets:frame-basic'
        include 'ly.img.android.pesdk.assets:filter-basic'
        include 'ly.img.android.pesdk.assets:overlay-basic'
        include 'ly.img.android.pesdk.assets:sticker-shapes'
        include 'ly.img.android.pesdk.assets:sticker-emoticons'
    }
}

Then, we copy the buildToolsVersion und paste it in the android category. And for the app to compile in the correct Java version, we copy this code block and paste it at the end of the android category.

compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

We hit “Sync Now” to save our settings. That often takes a while, so we sped it up for you.

We want to build a simple application that just consists of a single button that starts the photo editor. So first, we create a button. To do so, we navigate to the app folder and open the subfolders src, res and layout to find the activity_main (or whichever way you decided to name it). We click on “Text” to edit the file and add a button. For height and width, we enter wrap_content. Now, we set an ID for the button and call it sdk_button. We then set a display text for the button. For this tutorial, we'll use the string app_name, but you, of course, can choose whichever string you like.

We return to the app folder and find the MainActivity in the subfolders src and java. We head over to the documentation, where we are presented with two options. We can either start the editor in camera mode or in the device’s gallery. We’ll go with the camera mode. As we’re writing our MainActivity in Kotlin, we choose the Kotlin code example and paste it in the MainActivity. We can overwrite the onCreate as it is also included in the code example.

companion object {
        const val PESDK_RESULT = 1
    }

    // Important permission request for Android 6.0 and above, don't forget to add this!
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        PermissionRequest.onRequestPermissionsResult(requestCode, permissions, grantResults)
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }

    override fun permissionGranted() {}

    override fun permissionDenied() {
        /* TODO: The Permission was rejected by the user. The Editor was not opened,
         * Show a hint to the user and try again. */
    }

    // Create an empty new SettingsList and apply the changes on this reference.
    private fun createPesdkSettingsList() = SettingsList().apply {

        // If you include our asset packs and use our UI you also have to add them to the UI,
        // otherwise, they are only available for the backend
        // See the specific feature sections of our guides if you want to know how to add your own Assets.

        getSettingsModel(UiConfigFilter::class.java).apply {
            setFilterList(FilterPackBasic.getFilterPack())
        }

        getSettingsModel(UiConfigText::class.java).apply {
            setFontList(FontPackBasic.getFontPack())
        }

        getSettingsModel(UiConfigFrame::class.java).apply {
            setFrameList(FramePackBasic.getFramePack())
        }

        getSettingsModel(UiConfigOverlay::class.java).apply {
            setOverlayList(OverlayPackBasic.getOverlayPack())
        }

        getSettingsModel(UiConfigSticker::class.java).apply {
            setStickerLists(
              StickerPackEmoticons.getStickerCategory(),
              StickerPackShapes.getStickerCategory()
            )
        }

        // Set custom camera image export settings
        getSettingsModel(CameraSettings::class.java).apply {
            setExportDir(Directory.DCIM, "SomeFolderName")
            setExportPrefix("camera_")
        }

        // Set custom editor image export settings
        getSettingsModel(EditorSaveSettings::class.java).apply{
            setExportDir(Directory.DCIM, "SomeFolderName")
            setExportPrefix("result_")
            savePolicy = EditorSaveSettings.SavePolicy.RETURN_ALWAYS_ONLY_OUTPUT
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        openCamera()
    }

    private fun openCamera() {
        val settingsList = createPesdkSettingsList()

        CameraPreviewBuilder(this)
          .setSettingsList(settingsList)
          .startActivityForResult(this, PESDK_RESULT)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: android.content.Intent) {
        super.onActivityResult(requestCode, resultCode, data)

        if (resultCode == Activity.RESULT_OK && requestCode == PESDK_RESULT) { // Editor has saved an Image.

            val resultURI = data.getParcelableExtra<Uri?>(ImgLyIntent.RESULT_IMAGE_URI)?.also {
                // Scan result uri to show it up in the Gallery
                sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE).setData(it))
            }

            val sourceURI = data.getParcelableExtra<Uri?>(ImgLyIntent.SOURCE_IMAGE_URI)?.also {
                // Scan source uri to show it up in the Gallery
                sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE).setData(it))
            }

            Log.i("PESDK", "Source image is located here $sourceURI")
            Log.i("PESDK", "Result image is located here $resultURI")

            // TODO: Do something with the result image

            // OPTIONAL: read the latest state to save it as a serialisation
            val lastState = data.getParcelableExtra<SettingsList>(ImgLyIntent.SETTINGS_LIST)
            try {
                PESDKFileWriter(lastState).writeJson(File(
                  Environment.getExternalStorageDirectory(),
                  "serialisationReadyToReadWithPESDKFileReader.json"
                ))
            } catch (e: IOException) { e.printStackTrace() }

        } else if (resultCode == Activity.RESULT_CANCELED && requestCode == PESDK_RESULT) {

            // Editor was canceled
            val sourceURI = data.getParcelableExtra<Uri?>(ImgLyIntent.SOURCE_IMAGE_URI)
            // TODO: Do something...
        }
    }

Right now, we are presented with quite some error warnings, but that’s no problem at all because we still need to implement the interface, as you can see here: PermissionRequest.Response. Here, we must choose the dedicated ly.img.android.pesdk.ui.utils and add .response at the end.

After that, we’re down to only two errors because we still need to integrate the correct directory. Again, we choose the dedicated ly.img.android.pesdk.backend.model.constant. And thus all errors are resolved.

If we were to start the app now it would automatically run the editor in camera mode. But we don’t want the editor to start automatically, hence the button we previously added. So, in order to change that, we scroll to the onCreate method and as you can see here, the app would instantly open the camera.

We create a new variable that we’re going to call sdkButton and set it equal with findViewbyId. We then set the ID to sdk_button, set an OnClickListener and paste openCamera beneath it.

And, we have a working little app that contains the PhotoEditor SDK. You could take a deeper dive into PhotoEditor SDK integration in other environments and frameworks in the official documentation put together by developers themselves.

Thanks for reading! To stay in the loop, subscribe to our Newsletter.

Related Articles

CE.SDK v1.20 Release Notes
2 min read
CE.SDK v1.19 Release Notes
3 min read
CE.SDK v1.17 Release Notes
2 min read
CE.SDK v1.16 Release Notes
1 min read
CE.SDK v1.14 Release Notes
2 min read

GO TOP