Integrate powerful photo editing into your Android app.

This guide covers requirements, dynamic integration steps, memory considerations, customization options, and the most important API methods of Codenia Photo Editor for Android.

Requirements and Important Integration Notes

Minimum SDK: The Photo Editor requires minSdk = 26.

Activity configuration: The activity hosting the editor must define android:configChanges="keyboard|keyboardHidden|orientation|screenSize". This is required because the Photo Editor does not save or restore its internal state.

Memory recommendation: It is strongly recommended to enable android:largeHeap="true" and to pass an image of reasonable size to the editor.

Images in normal camera resolution are usually not a problem, because the Photo Editor is designed to use memory carefully and releases memory whenever possible. However, out-of-memory errors cannot be fully ruled out, especially on older devices or devices with problematic graphics hardware.

Compatibility: The Photo Editor is fully compatible with devices using 16 KB memory page size configurations. This ensures compliance with current Google Play requirements.

Required Activity Configuration

<activity
    android:name=".YourEditorActivity"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize" />

Recommended Application Setting

<application
    android:largeHeap="true" ... />

Overview

Codenia Photo Editor for Android is delivered as a lightweight AAR library and provides a fully integrated editing UI through PhotoEditorView. It works completely offline and does not require any backend, API key, or network connection.

The main entry point is the class com.codenia.photoeditor.api.PhotoEditorView. It is a ready-to-use UI component based on RelativeLayout and is typically created and added dynamically at runtime when the user wants to edit an image.

Before the editor is shown, set the source bitmap and optionally configure tools, filters, fonts, stickers, crop options, and the license key. When the user finishes editing, the result is returned through the callback interface OnEditorActionListener.

Typical Integration Flow

A typical integration of Codenia Photo Editor for Android follows this sequence:

  • A PhotoEditorView instance is created and configured.
  • The source bitmap is passed to the editor using setImageBitmap().
  • The app receives callbacks via onDone(), onCancel(), and onError().
  • When editing is finished, the returned bitmap can be previewed, saved, or processed further.
  • The editor view should be removed from the view hierarchy when editing is completed or canceled.

Features

  • Fully offline photo editing with no external services or network dependencies
  • Ready-to-use UI component delivered as an AAR library
  • 15 built-in tools including crop, rotate, text, stickers, drawing, filters, tone curve, and color adjustments
  • Configurable tool order and visibility
  • Custom stickers and custom fonts
  • Configurable crop aspect ratio options
  • Filter title and visibility configuration
  • Optional adjustable filter intensity
  • Multiple filter thumbnail styles
  • Evaluation mode without feature limitation
  • Supports 16 KB memory page sizes (Google Play compliant)

Integration

1. Add the AAR and dependencies

Add codenia-photoeditor.aar to your project (e.g. into the app/libs directory) and include it in your Gradle configuration.

Download AAR file
dependencies {
    // ---------------------------------------------------------------------
    // Codenia Photo Editor (AAR)
    // ---------------------------------------------------------------------
    implementation files("libs/codenia-photoeditor.aar")

    // ---------------------------------------------------------------------
    // Required AndroidX dependencies
    // ---------------------------------------------------------------------
    implementation "androidx.appcompat:appcompat:1.7.1"
    implementation "androidx.recyclerview:recyclerview:1.4.0"
    implementation "androidx.constraintlayout:constraintlayout:2.2.1"
    implementation "androidx.emoji2:emoji2:1.6.0"
    implementation "androidx.emoji2:emoji2-bundled:1.6.0"
}

Note: The Emoji2 dependencies are required to ensure consistent and high-quality emoji rendering in text stickers during scaling, rotation, and glow effects.

2. Prepare a parent container

Because the editor is used dynamically, your activity should provide an existing parent view such as a RelativeLayout or another suitable container.

<RelativeLayout
    android:id="@+id/rootLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

3. Provide a source bitmap

Set the source bitmap with setImageBitmap() before adding the PhotoEditorView to your container. The editor requires a valid, non-null, non-recycled bitmap.

4. Register a listener and add the editor view

Use setOnEditorActionListener() to receive the edited bitmap, cancellation events, or configuration errors, then add the view to your container.

Important: You must call setImageBitmap() before adding the editor view to your container. If no source image is set, the editor will report an error through the listener.

Basic Usage

The following example shows a typical dynamic integration:

Important: Do not reuse a PhotoEditorView instance across multiple editing sessions. Always create a new PhotoEditorView when opening the editor.

PhotoEditorView photoEditorView;
							
private void showPhotoEditorView(@NonNull Bitmap bitmap) {
    photoEditorView = new PhotoEditorView(this);

    photoEditorView.setImageBitmap(bitmap);

    photoEditorView.setOnEditorActionListener(new PhotoEditorView.OnEditorActionListener() {
        @Override
        public void onDone(Bitmap resultBitmap) {
            // handle the edited image here and remove the editor view
            removePhotoEditorView();
        }

        @Override
        public void onCancel() {
            // remove the editor view here
            removePhotoEditorView();
        }

        @Override
        public void onError(@NonNull String message) {
            // show or log the error here and remove the editor view
            removePhotoEditorView();
        }
    });

    rootLayout.addView(photoEditorView);
}

Remove the editor view

private void removePhotoEditorView() {
    if (photoEditorView == null) return;

    photoEditorView.setOnEditorActionListener(null);

    if (photoEditorView.getParent() instanceof ViewGroup) {
        ((ViewGroup) photoEditorView.getParent()).removeView(photoEditorView);
    }

    photoEditorView = null;
}

Customization

Limit the available tools

If you do not call setTools(), all tools are enabled by default. You can restrict the editor to only the tools your app needs.

photoEditorView.setTools(
    PhotoEditorView.Tool.CROP,
    PhotoEditorView.Tool.ROTATE,
    PhotoEditorView.Tool.FILTER,
    PhotoEditorView.Tool.TEXT,
    PhotoEditorView.Tool.STICKER
);

Change the order of tools

The order passed to setTools() defines the order in which tools appear in the UI.

Configure crop aspect ratios

Use setCropAspectRatioOptions() to define which crop ratios are available.

photoEditorView.setCropAspectRatioOptions(Arrays.asList(
    AspectRatioOption.free(),
    AspectRatioOption.original(),
    AspectRatioOption.fixed(1, 1, "1 : 1")
));

Use custom stickers

Important: The AAR includes only three example stickers for demonstration purposes. You must provide your own sticker resources for production use.

Use setStickerResourceIds() to replace the default stickers with your own drawable resources.

photoEditorView.setStickerResourceIds(new int[] {
    R.drawable.sticker_1,
    R.drawable.sticker_2,
    R.drawable.sticker_3
});

Use custom fonts

Use setAvailableFonts() to replace the default fonts shown by the text tool. The name resource IDs and font resource IDs must have the same length.

photoEditorView.setAvailableFonts(
    new int[] {
        R.string.font_name_roboto,
        R.string.font_name_lobster
    },
    new int[] {
        R.font.roboto_regular,
        R.font.lobster
    }
);

Configure filters

You can customize filter names and visibility using setFilterSettings().

The editor provides exactly 30 predefined filters. To configure them, create a FilterSettings instance with exactly 30 FilterSetting objects. If no FilterSettings instance is provided, all 30 filters are displayed and default numeric titles (1 to 30) are used.

Each FilterSetting defines the display name and visibility of one predefined filter. The order is fixed and corresponds to the internal filter order of the editor.

This means you can rename or hide existing filters, but you cannot add your own filters, replace the predefined filters with custom ones, or change their order.

Note: FilterSettings must always contain exactly 30 FilterSetting objects.

FilterSettings filterSettings = new FilterSettings(
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("Filter 1", true),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("Filter 2", true),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("Filter 3", true),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false),
    new FilterSetting("", false)
    );
							
photoEditorView.setFilterSettings(filterSettings);

Enable or disable adjustable filter intensity

photoEditorView.setFilterIntensityAdjustable(true);

Change filter thumbnail style

The appearance of filter thumbnails can be customized using setFilterThumbnailStyle().

The selected style controls the shape of the thumbnails, whether a caption is displayed, and how the selection border is rendered.

  • Shape: rounded, circular, or square thumbnails
  • Caption: optional text label below the thumbnail
  • Selection style: optional inner gap between image and selection border
public enum FilterThumbnailStyle {

    // Rounded corners, no caption below, no inner gap between image and selection border.
    ROUNDED_NO_CAPTION_NO_GAP,
    
    // Rounded corners, no caption below, with an inner gap between image and selection border.
    ROUNDED_NO_CAPTION_GAP,
    
    // Circular, no caption below, no inner gap between image and selection border.
    CIRCLE_NO_CAPTION_NO_GAP,
    
    // Circular, no caption below, with an inner gap between image and selection border.
    CIRCLE_NO_CAPTION_GAP,
    
    // Square corners, no caption below, no inner gap between image and selection border.
    SQUARE_NO_CAPTION_NO_GAP,
    
    // Square corners, no caption below, with an inner gap between image and selection border.
    SQUARE_NO_CAPTION_GAP,
    
    // Rounded corners, caption label below, no inner gap between image and selection border.
    ROUNDED_WITH_CAPTION_NO_GAP,
    
    // Rounded corners, caption label below, with an inner gap between image and selection border.
    ROUNDED_WITH_CAPTION_GAP,
    
    // Circular, caption label below, no inner gap between image and selection border.
    CIRCLE_WITH_CAPTION_NO_GAP,
    
    // Circular, caption label below, with an inner gap between image and selection border.
    CIRCLE_WITH_CAPTION_GAP,
    
    // Square corners, caption label below (style variant 1), no inner gap between image and selection border.
    SQUARE_WITH_CAPTION_STYLE1_NO_GAP,
    
    // Square corners, caption label below (style variant 1), with an inner gap between image and selection border.
    SQUARE_WITH_CAPTION_STYLE1_GAP,
    
    // Square corners, caption label below (style variant 2).
    SQUARE_WITH_CAPTION_STYLE2
}
photoEditorView.setFilterThumbnailStyle(
    PhotoEditorView.FilterThumbnailStyle.ROUNDED_WITH_CAPTION_GAP
);

Note: If not set, the default style is SQUARE_WITH_CAPTION_STYLE2.

The different styles allow you to adapt the filter UI to match the visual design of your app.

Localization

Important: The AAR includes only English resources by default. Additional translations are not bundled intentionally.

This ensures that your app only advertises the languages it actually supports. You must explicitly add the required localization files to your project.

The Photo Editor supports the following locales. You can add any of these languages by including the corresponding photo_editor_strings.xml files in your app.

<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
    <locale android:name="ar"/>
    <locale android:name="ca"/>
    <locale android:name="cs"/>
    <locale android:name="da"/>
    <locale android:name="de"/>
    <locale android:name="el"/>
    <locale android:name="en"/>
    <locale android:name="es"/>
    <locale android:name="fi"/>
    <locale android:name="fr"/>
    <locale android:name="he"/>
    <locale android:name="hi"/>
    <locale android:name="hr"/>
    <locale android:name="hu"/>
    <locale android:name="in"/>
    <locale android:name="it"/>
    <locale android:name="iw"/>
    <locale android:name="ja"/>
    <locale android:name="ko"/>
    <locale android:name="ms"/>
    <locale android:name="nb"/>
    <locale android:name="nl"/>
    <locale android:name="no"/>
    <locale android:name="pl"/>
    <locale android:name="pt"/>
    <locale android:name="ro"/>
    <locale android:name="ru"/>
    <locale android:name="sk"/>
    <locale android:name="sv"/>
    <locale android:name="th"/>
    <locale android:name="tr"/>
    <locale android:name="uk"/>
    <locale android:name="vi"/>
    <locale android:name="zh"/>
    <locale android:name="zh-rCN"/>
    <locale android:name="zh-rHK"/>
    <locale android:name="zh-rMO"/>
    <locale android:name="zh-rTW"/>
</locale-config>

To enable a language, copy the corresponding translation file into your project, for example:

res/values-de/photo_editor_strings.xml

For convenience, you can download all available localization files here: Download localization files

Customize editor colors

The appearance of the Photo Editor can be customized by overriding its color resources in your app's colors.xml.

This allows you to adapt the editor UI to match the visual design of your application, including backgrounds, text colors, icons, dialogs, sliders, tone curve elements, filter thumbnails, and tool defaults.

To override the default theme, define colors with the same names in your project:

<resources>

    <!-- Codenia Photo Editor Colors -->

    <color name="photo_editor_background_primary">#242424</color>
    <color name="photo_editor_background_secondary">#3c3c3c</color>
    <color name="photo_editor_background_secondary_accent">#444444</color>
    <color name="photo_editor_title_color">#ffffff</color>
    <color name="photo_editor_text_color">#dadada</color>
    <color name="photo_editor_icon_color">#dadada</color>
    <color name="photo_editor_seekbar_color">#dadada</color>
    <color name="photo_editor_progressbar_color">#75ccff</color>
    <color name="photo_editor_button_cancel_color">#dadada</color>
    <color name="photo_editor_button_ok_color">#dadada</color>
    <color name="photo_editor_button_done_color">#75ccff</color>

    <color name="photo_editor_tone_curve_border_color">#60dadada</color>
    <color name="photo_editor_tone_curve_grid_color">#60dadada</color>
    <color name="photo_editor_tone_curve_point_color">#dadada</color>
    <color name="photo_editor_tone_curve_point_border_color">#242424</color>
    <color name="photo_editor_tone_curve_line_color">#dadada</color>

    <!-- Filter thumbnails colors for all styles except SQUARE_WITH_CAPTION_STYLE2 -->
    <color name="photo_editor_filter_thumbnail_selected_border_color">#75ccff</color>
    <color name="photo_editor_filter_thumbnail_selected_text_color">#dadada</color>
    <color name="photo_editor_filter_thumbnail_unselected_text_color">#dadada</color>

    <!-- Filter thumbnails colors for SQUARE_WITH_CAPTION_STYLE2 -->
    <color name="photo_editor_filter_thumbnail_style2_selected_text_color">#dadada</color>
    <color name="photo_editor_filter_thumbnail_style2_selected_text_background_color">#3070ab</color>
    <color name="photo_editor_filter_thumbnail_style2_unselected_text_color">#dadada</color>
    <color name="photo_editor_filter_thumbnail_style2_unselected_text_background_color">#242424</color>

    <color name="photo_editor_filter_seekbar_background">#7d000000</color>

    <color name="photo_editor_draw_tool_default_drawing_color">#3555b5</color>
    <color name="photo_editor_draw_tool_slider_background_color">#dadada</color>
    <color name="photo_editor_draw_tool_slider_thumb_color">#3c3c3c</color>

    <color name="photo_editor_text_tool_default_text_color">#000000</color>
    <color name="photo_editor_text_tool_default_glow_color">#0099e5</color>
    <color name="photo_editor_font_wheel_background_color">#dadada</color>
    <color name="photo_editor_font_wheel_text_color">#242424</color>

    <color name="photo_editor_dialog_background_color">#242424</color>
    <color name="photo_editor_dialog_title_color">#ffffff</color>
    <color name="photo_editor_dialog_message_color">#dadada</color>
    <color name="photo_editor_dialog_button_text_color">#dadada</color>
    <color name="photo_editor_dialog_edittext_line_color">#242424</color>
    <color name="photo_editor_dialog_edittext_text_color">#dadada</color>
    <color name="photo_editor_dialog_edittext_cursor_color">#5088b9</color>

    <color name="photo_editor_overlay_alpha_opening_color">#000000</color>
    <color name="photo_editor_overlay_alpha_tool_processing_color">#000000</color>

</resources>

Note: You only need to override the colors you want to change. All other values will fall back to the default colors provided by the Photo Editor.

Tip: Defining your own color scheme allows you to seamlessly integrate the Photo Editor into your app's design system.

Customize dimensions

The layout of the Photo Editor can be adjusted by overriding its dimension resources in your app's dimens.xml.

This allows you to change sizes such as toolbar height, bottom panel height, tool item width, text sizes, thumbnail padding, selection stroke width, and corner radius.

<resources>
    <dimen name="photo_editor_top_bar_height">50dp</dimen>
    <dimen name="photo_editor_top_bar_cancel_text_size">16sp</dimen>
    <dimen name="photo_editor_top_bar_title_text_size">16sp</dimen>
    <dimen name="photo_editor_top_bar_ok_text_size">16sp</dimen>
    <dimen name="photo_editor_top_bar_done_text_size">16sp</dimen>

    <dimen name="photo_editor_bottom_panel_height">90dp</dimen>

    <dimen name="photo_editor_tool_menu_item_width">76dp</dimen>
    <dimen name="photo_editor_tool_menu_padding_top">10dp</dimen>
    <dimen name="photo_editor_tool_menu_padding_left_and_right">0dp</dimen>
    <dimen name="photo_editor_tool_menu_caption_height">30dp</dimen>
    <dimen name="photo_editor_tool_menu_text_size">12sp</dimen>

    <dimen name="photo_editor_filter_menu_height_with_caption">130dp</dimen>
    <dimen name="photo_editor_filter_menu_height_without_caption">110dp</dimen>

    <dimen name="photo_editor_filter_selection_stroke_width">3dp</dimen>
    <dimen name="photo_editor_filter_selection_gap_width">3dp</dimen>

    <dimen name="photo_editor_filter_thumbnail_padding_with_caption">6dp</dimen>
    <dimen name="photo_editor_filter_thumbnail_padding_without_caption">10dp</dimen>

    <dimen name="photo_editor_filter_thumbnail_caption_height">25sp</dimen>
    <dimen name="photo_editor_filter_thumbnail_caption_text_size">12sp</dimen>

    <dimen name="photo_editor_filter_thumbnail_corner_radius">18dp</dimen>

    <dimen name="photo_editor_text_tool_color_picker_slider_height">22dp</dimen>
</resources>

Note: You only need to override the dimension resources you want to change. All other values will fall back to the defaults provided by the Photo Editor.

Customize overlay opacity

The Photo Editor uses overlay opacity values during opening and tool processing states. These values can be customized by overriding the fraction resources in your app's fractions.xml.

<resources>
    <fraction name="photo_editor_overlay_alpha_opening">40%</fraction>
    <fraction name="photo_editor_overlay_alpha_tool_processing">40%</fraction>
</resources>

Note: These fractions control the opacity of the corresponding overlay colors, such as photo_editor_overlay_alpha_opening_color and photo_editor_overlay_alpha_tool_processing_color.

Customize boolean behavior

Some editor behaviors can be configured by overriding boolean resources in your app's bools.xml.

<resources>
    <bool name="photo_editor_button_text_all_caps">false</bool>
    <bool name="photo_editor_text_tool_use_fake_bold_for_cjk">true</bool>
    <bool name="photo_editor_text_tool_auto_open_input_dialog">true</bool>
</resources>
  • photo_editor_button_text_all_caps — controls whether button text is displayed in all caps
  • photo_editor_text_tool_use_fake_bold_for_cjk — enables fake bold rendering for CJK text in the text tool
  • photo_editor_text_tool_auto_open_input_dialog — controls whether the text input dialog opens automatically when the text tool is used

Note: These boolean resources allow you to fine-tune default editor behavior.

Show or hide exit confirmation

Controls whether the editor shows a confirmation dialog when the user attempts to exit the editor.

photoEditorView.setShowExitConfirmationMessage(true);

Back Navigation Handling

The hosting activity should forward back button events to the PhotoEditorView before handling them itself. This allows the editor to handle the back action when needed.

If photoEditorView.handleBackPressed() returns true, the editor has consumed the back press and no further action should be taken. If it returns false, the activity should handle the back press as usual.

getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
    @Override
    public void handleOnBackPressed() {

        if (photoEditorView != null) {
            if (photoEditorView.handleBackPressed()) {
                // The editor handled the back press
                return;
            }
        }

        // Fallback: handle back press in the activity
        finish();
    }
});

Note: The editor does not automatically handle the Android back button. Your activity remains responsible for handling it if the editor does not consume the event.

License Key

You can test the editor without a license key. In evaluation mode, all features remain available, but exported images contain a watermark.

To remove the watermark, set a valid license key before exporting edited content.

photoEditorView.setLicenseKey("YOUR_LICENSE_KEY");

Note: The license key is tied to the Android application ID (bundle ID). A separate license is required for each app.

Important API Methods

  • setImageBitmap(Bitmap bitmap) — sets the source image to edit
  • setOnEditorActionListener(OnEditorActionListener listener) — receives done, cancel, and error callbacks
  • setLicenseKey(String licenseKey) — removes the watermark when a valid key is used
  • setTools(Tool... tools) — defines which tools are visible and in what order
  • setFilterSettings(FilterSettings filterSettings) — configures filter titles and visibility
  • setFilterIntensityAdjustable(boolean adjustable) — enables or disables filter intensity control
  • setFilterThumbnailStyle(FilterThumbnailStyle style) — changes the visual style of filter thumbnails
  • setShowExitConfirmationMessage(boolean show) — controls whether a confirmation dialog is shown on exit
  • setAvailableFonts(int[] nameResIds, int[] fontResIds) — replaces the available fonts of the text tool
  • setStickerResourceIds(int[] customStickerResourceIds) — replaces the default sticker set
  • setCropAspectRatioOptions(List<AspectRatioOption> options) — configures crop ratio options
  • handleBackPressed() — allows integration with the Android back button

Available Tools

The editor currently provides the following tools:

  • FILTER
  • BRIGHTNESS
  • CONTRAST
  • VIGNETTE
  • FLIP
  • CROP
  • ROTATE
  • SATURATION
  • COLORS
  • SHARPEN
  • WARMTH
  • TONE_CURVE
  • DRAW
  • STICKER
  • TEXT

Memory and Performance Recommendations

  • Use images of reasonable size whenever possible.
  • Consider downscaling preview bitmaps shown outside the editor.
  • Enable android:largeHeap="true" if your app frequently edits large images.
  • Even with careful memory handling, out-of-memory errors cannot be completely ruled out on all devices.

Important Notes

  • A PhotoEditorView instance should not be reused across multiple editing sessions. Create a new instance each time the editor is opened.
  • The source bitmap must not be null.
  • The source bitmap must not be recycled.
  • The editor does not modify the passed bitmap directly. It works on an internal copy.
  • The caller remains responsible for the lifecycle of the original bitmap.
  • If the editor view is detached from the window, internal resources are released automatically.
  • Custom font name and font arrays must have the same length.
  • If setTools() is not called, all tools are enabled by default.
  • Very large bitmaps may still cause out-of-memory errors depending on the device.
  • Using a downscaled preview outside the editor can help reduce memory usage.
  • The AAR includes only three example stickers. You must provide your own for production use.

Note: The editor does not provide undo/redo functionality. Changes are applied directly and cannot be reverted step-by-step.

For a complete working integration example, see the Sample Project.