Docs
API Docs

Filters

Filters tool

Our PhotoEditor SDK features more than 60 high-quality filters and enables you to add custom filters with ease. The processing of the images is lightning fast and adding your own filters neither requires super math nor high-level coding skills.

To examine the included filters, you can download the example app from the Play Store or clone our demo repository.

The backend settings are implemented in the FilterSettings class and displayed using the FilterToolPanel. If you want to customize the appearance of this tool, take a look at the customization section.

Add custom lut filters

If you want to add a custom filter element to the user interface, a filter asset must exist in the backend. To add it you can use the following code as orientation. It is important to have a unique identifier for the asset and define the format you want to use. And of course you have to specify which Lut filter image you want to use. If you include the “Assets: Filter-Basic” module, all filter assets are part of the backend without adding them manually.

ConfigMap<FilterAsset> filterAssetsMap = settingsList.getSettingsModel(AssetConfig.class).getAssetMap(FilterAsset.class);

// Add a custom lut filter asset to the backend
filterAssetsMap.add(new LutColorFilterAsset("my_unique_lut_id", ImageSource.create(R.drawable.imgly_lut_ad1920_5_5_128), 5, 5, 128));
settingsList.getSettingsModel(AssetConfig::class.java).apply {
    getAssetMap(FilterAsset::class.java).apply {

        // Add a custom lut filter asset to the backend
        add(LutColorFilterAsset("my_unique_lut_id", ImageSource.create(R.drawable.imgly_lut_ad1920_5_5_128), 5, 5, 128))
    }
}

Response filters

We use a technology called LUTs in order to add new filters to our SDK. The main idea is that colors respond to operations that are carried out during the filtering process. We ‘record’ that very response by applying the filter to the identity image shown below.

Starting with version 4.0, we support lower resolution LUT files in order to further reduce your apps deployment size and speed up live filters and filter previews. The supported formats are:

  • 512x512 LUT with 8 columns and 8 rows (download )
  • 256x256 LUT with 7 columns and 7 rows (download )
  • 256x256 LUT with 6 columns and 6 rows (download )
  • 128x128 LUT with 5 columns and 5 rows (download )

Using a smaller LUT file may lead to issues when applying your filter, as our processing engine needs to interpolate missing values. We recommend starting with the smallest possible LUT file and falling back to larger files if you notice that your filter can’t be fully reproduced:

Identity 512x512 8x8 LUT Identity 256x256 7x7 LUT Identity 256x256 6x6 LUT Identity 128x128 5x5 LUT

The black borders are required in order to optimize performance and the number of rows translates to the resolution for the green channel, the number of columns translates to the resolution of the red channel and the number of tiles translates to the blue channels resolution. And larger LUTs naturally guarantee a larger resolution across all channels.

The resulting image can be used within our SDK and the recorded changes can then be applied to any image by looking up the transformed colors in the modified LUT.

If you want to create a new filter, you’ll need to download one of the identity LUTs shown above, load it into an image editing software of your choice, apply your operations, save it and add it to your app. Please note that not all operations can be translated into a response filter. Typically those operations use surrounding the pixels to determine the color of the pixel, such as blur.

WARNING: As any compression artifacts in the edited LUT could lead to distorted results when applying the filter, you need to save your LUT as a PNG file.

The last step is to add the filter to the list of available filters by creating a LutColorFilterAsset object just as described above. The object takes the following three parameters:

  1. String resource identifier of the filters name, which will not be displayed in the default layout, but is used for Accessibility.
  2. Preview image resource for the CameraPreviewActivity. This image is replaced with a filtered version of the current image within the editor.
  3. Drawable-nodpi or Raw resource identifier of the PNG LUT.

WARNING: Be sure to put the LUT PNG file in the ‘res/drawable-nodpi’ folder. Otherwise, the LUT will be scaled by the Android system.

Adding the custom filter to the available filters then looks like this:

DataSourceIdItemList<FilterItem> folderContent = new DataSourceIdItemList<>(); // Create a list to add all items of one folder

DataSourceIdItemList<AbstractIdItem> filterInUiList = settingsList.getSettingsModel(UiConfigFilter.class).getFilterList();
filterInUiList.clear(); // To clear the whole list

// Add a custom filter to a custom filter category and display it in the `FilterToolPanel`
folderContent.add(new FilterItem("my_unique_lut_id", "Custom filter"));
filterInUiList.add(new FolderItem("imgly_filter_category_custom", "Custom filters", ImageSource.create(R.drawable.imgly_lut_ad1920_5_5_128), folderContent));

folderContent.clear(); // Clear folder list after adding the folder to the filter list
folderContent.add(new FilterItem(DuotoneFilterAssetDesert.ID, R.string.pesdk_filter_asset_duotoneDesert));
folderContent.add(new FilterItem(DuotoneFilterAssetPeach.ID, R.string.pesdk_filter_asset_duotonePeach));
folderContent.add(new FilterItem(DuotoneFilterAssetClash.ID, R.string.pesdk_filter_asset_duotoneClash));
folderContent.add(new FilterItem(DuotoneFilterAssetPlum.ID, R.string.pesdk_filter_asset_duotonePlum));
folderContent.add(new FilterItem(DuotoneFilterAssetBreezy.ID, R.string.pesdk_filter_asset_duotoneBreezy));
folderContent.add(new FilterItem(DuotoneFilterAssetDeepBlue.ID, R.string.pesdk_filter_asset_duotoneDeepBlue));
folderContent.add(new FilterItem(DuotoneFilterAssetFrog.ID, R.string.pesdk_filter_asset_duotoneFrog));
folderContent.add(new FilterItem(DuotoneFilterAssetSunset.ID, R.string.pesdk_filter_asset_duotoneSunset));
filterInUiList.add(new FolderItem("imgly_filter_category_duotone", R.string.pesdk_filter_folder_duotone, ImageSource.create(R.drawable.pesdk_filter_category_duotone), folderContent));

folderContent.clear(); // Clear folder list after adding the folder to the filter list
folderContent.add(new FilterItem(ColorFilterAssetAD1920.ID, R.string.pesdk_filter_asset_ad1920));
folderContent.add(new FilterItem(ColorFilterAssetBW.ID, R.string.pesdk_filter_asset_bw));
folderContent.add(new FilterItem(ColorFilterAssetX400.ID, R.string.pesdk_filter_asset_x400));
folderContent.add(new FilterItem(ColorFilterAssetLitho.ID, R.string.pesdk_filter_asset_litho));
folderContent.add(new FilterItem(ColorFilterAssetSepiahigh.ID, R.string.pesdk_filter_asset_sepiaHigh));
folderContent.add(new FilterItem(ColorFilterAssetPlate.ID, R.string.pesdk_filter_asset_plate));
folderContent.add(new FilterItem(ColorFilterAssetSin.ID, R.string.pesdk_filter_asset_sin));
filterInUiList.add(new FolderItem("imgly_filter_category_bw", R.string.pesdk_filter_folder_b_and_w, ImageSource.create(R.drawable.pesdk_filter_category_b_w), folderContent));

folderContent.clear(); // Clear folder list after adding the folder to the filter list
folderContent.add(new FilterItem(ColorFilterAssetBlues.ID, R.string.pesdk_filter_asset_blues));
folderContent.add(new FilterItem(ColorFilterAssetFront.ID, R.string.pesdk_filter_asset_front));
folderContent.add(new FilterItem(ColorFilterAssetTexas.ID, R.string.pesdk_filter_asset_texas));
folderContent.add(new FilterItem(ColorFilterAssetCelsius.ID, R.string.pesdk_filter_asset_celsius));
folderContent.add(new FilterItem(ColorFilterAssetCool.ID, R.string.pesdk_filter_asset_cool));
filterInUiList.add(new FolderItem("imgly_filter_category_vintage", R.string.pesdk_filter_folder_vintage, ImageSource.create(R.drawable.pesdk_filter_category_vintage), folderContent));

folderContent.clear(); // Clear folder list after adding the folder to the filter list
folderContent.add(new FilterItem(ColorFilterAssetChest.ID, R.string.pesdk_filter_asset_chest));
folderContent.add(new FilterItem(ColorFilterAssetWinter.ID, R.string.pesdk_filter_asset_winter));
folderContent.add(new FilterItem(ColorFilterAssetKDynamic.ID, R.string.pesdk_filter_asset_dynamic));
folderContent.add(new FilterItem(ColorFilterAssetFall.ID, R.string.pesdk_filter_asset_fall));
folderContent.add(new FilterItem(ColorFilterAssetLenin.ID, R.string.pesdk_filter_asset_lenin));
folderContent.add(new FilterItem(ColorFilterAssetPola669.ID, R.string.pesdk_filter_asset_669));
filterInUiList.add(new FolderItem("imgly_filter_category_smooth", R.string.pesdk_filter_folder_smooth, ImageSource.create(R.drawable.pesdk_filter_category_smooth), folderContent));

folderContent.clear(); // Clear folder list after adding the folder to the filter list
folderContent.add(new FilterItem(ColorFilterAssetElder.ID, R.string.pesdk_filter_asset_elder));
folderContent.add(new FilterItem(ColorFilterAssetOrchid.ID, R.string.pesdk_filter_asset_orchid));
folderContent.add(new FilterItem(ColorFilterAssetBleached.ID, R.string.pesdk_filter_asset_bleached));
folderContent.add(new FilterItem(ColorFilterAssetBleachedBlue.ID, R.string.pesdk_filter_asset_bBlue));
folderContent.add(new FilterItem(ColorFilterAssetBreeze.ID, R.string.pesdk_filter_asset_breeze));
folderContent.add(new FilterItem(ColorFilterAssetBlueShadows.ID, R.string.pesdk_filter_asset_blueShade));
filterInUiList.add(new FolderItem("imgly_filter_category_cold", R.string.pesdk_filter_folder_cold, ImageSource.create(R.drawable.pesdk_filter_category_cold), folderContent));

folderContent.clear(); // Clear folder list after adding the folder to the filter list
folderContent.add(new FilterItem(ColorFilterAssetSunset.ID, R.string.pesdk_filter_asset_sunset));
folderContent.add(new FilterItem(ColorFilterAssetEighties.ID, R.string.pesdk_filter_asset_80s));
folderContent.add(new FilterItem(ColorFilterAssetEvening.ID, R.string.pesdk_filter_asset_evening));
folderContent.add(new FilterItem(ColorFilterAssetK2.ID, R.string.pesdk_filter_asset_k2));
folderContent.add(new FilterItem(ColorFilterAssetNoGreen.ID, R.string.pesdk_filter_asset_noGreen));
filterInUiList.add(new FolderItem("imgly_filter_category_warm", R.string.pesdk_filter_folder_warm, ImageSource.create(R.drawable.pesdk_filter_category_warm), folderContent));

folderContent.clear(); // Clear folder list after adding the folder to the filter list
folderContent.add(new FilterItem(ColorFilterAssetAncient.ID, R.string.pesdk_filter_asset_ancient));
folderContent.add(new FilterItem(ColorFilterAssetCottonCandy.ID, R.string.pesdk_filter_asset_candy));
folderContent.add(new FilterItem(ColorFilterAssetClassic.ID, R.string.pesdk_filter_asset_classic));
folderContent.add(new FilterItem(ColorFilterAssetColorful.ID, R.string.pesdk_filter_asset_colorful));
folderContent.add(new FilterItem(ColorFilterAssetCreamy.ID, R.string.pesdk_filter_asset_creamy));
folderContent.add(new FilterItem(ColorFilterAssetFixie.ID, R.string.pesdk_filter_asset_fixie));
folderContent.add(new FilterItem(ColorFilterAssetFood.ID, R.string.pesdk_filter_asset_food));
folderContent.add(new FilterItem(ColorFilterAssetFridge.ID, R.string.pesdk_filter_asset_fridge));
folderContent.add(new FilterItem(ColorFilterAssetGlam.ID, R.string.pesdk_filter_asset_glam));
folderContent.add(new FilterItem(ColorFilterAssetGobblin.ID, R.string.pesdk_filter_asset_goblin));
folderContent.add(new FilterItem(ColorFilterAssetHighContrast.ID, R.string.pesdk_filter_asset_hicon));
folderContent.add(new FilterItem(ColorFilterAssetHighCarb.ID, R.string.pesdk_filter_asset_carb));
folderContent.add(new FilterItem(ColorFilterAssetK1.ID, R.string.pesdk_filter_asset_k1));
folderContent.add(new FilterItem(ColorFilterAssetK6.ID, R.string.pesdk_filter_asset_k6));
folderContent.add(new FilterItem(ColorFilterAssetKeen.ID, R.string.pesdk_filter_asset_keen));
folderContent.add(new FilterItem(ColorFilterAssetLomo.ID, R.string.pesdk_filter_asset_lomo));
folderContent.add(new FilterItem(ColorFilterAssetLomo100.ID, R.string.pesdk_filter_asset_lomo100));
folderContent.add(new FilterItem(ColorFilterAssetLucid.ID, R.string.pesdk_filter_asset_lucid));
folderContent.add(new FilterItem(ColorFilterAssetMellow.ID, R.string.pesdk_filter_asset_mellow));
folderContent.add(new FilterItem(ColorFilterAssetNeat.ID, R.string.pesdk_filter_asset_neat));
folderContent.add(new FilterItem(ColorFilterAssetPale.ID, R.string.pesdk_filter_asset_pale));
folderContent.add(new FilterItem(ColorFilterAssetPitched.ID, R.string.pesdk_filter_asset_pitched));
folderContent.add(new FilterItem(ColorFilterAssetPolaSx.ID, R.string.pesdk_filter_asset_sx));
folderContent.add(new FilterItem(ColorFilterAssetPro400.ID, R.string.pesdk_filter_asset_pro400));
folderContent.add(new FilterItem(ColorFilterAssetQuozi.ID, R.string.pesdk_filter_asset_quozi));
folderContent.add(new FilterItem(ColorFilterAssetSettled.ID, R.string.pesdk_filter_asset_settled));
folderContent.add(new FilterItem(ColorFilterAssetSeventies.ID, R.string.pesdk_filter_asset_70s));
folderContent.add(new FilterItem(ColorFilterAssetSoft.ID, R.string.pesdk_filter_asset_soft));
folderContent.add(new FilterItem(ColorFilterAssetSteel.ID, R.string.pesdk_filter_asset_steel));
folderContent.add(new FilterItem(ColorFilterAssetSummer.ID, R.string.pesdk_filter_asset_summer));
folderContent.add(new FilterItem(ColorFilterAssetTender.ID, R.string.pesdk_filter_asset_tender));
folderContent.add(new FilterItem(ColorFilterAssetTwilight.ID, R.string.pesdk_filter_asset_twilight));
filterInUiList.add(new FolderItem("imgly_filter_category_legacy", R.string.pesdk_filter_folder_legacy, ImageSource.create(R.drawable.pesdk_filter_category_legacy), folderContent));
folderContent.clear(); // Clear folder list after adding the folder to the filter list
val filterInUiList = settingsList.getSettingsModel(UiConfigFilter::class.java).filterList.apply {
    clear() // To clear the whole list

    // Add a custom filter to a custom filter category and display it in the `FilterToolPanel`
    add(FolderItem("imgly_filter_category_custom", "Custom filters", ImageSource.create(R.drawable.imgly_lut_ad1920_5_5_128),
        DataSourceIdItemList<FilterItem>().apply {
            add(FilterItem("my_unique_lut_id", "Custom filter"))
        }
    ))

    add(FolderItem("imgly_filter_category_duotone", R.string.pesdk_filter_folder_duotone, ImageSource.create(R.drawable.pesdk_filter_category_duotone),
        DataSourceIdItemList<FilterItem>().apply {
            add(FilterItem(DuotoneFilterAssetDesert.ID, R.string.pesdk_filter_asset_duotoneDesert))
            add(FilterItem(DuotoneFilterAssetPeach.ID, R.string.pesdk_filter_asset_duotonePeach))
            add(FilterItem(DuotoneFilterAssetClash.ID, R.string.pesdk_filter_asset_duotoneClash))
            add(FilterItem(DuotoneFilterAssetPlum.ID, R.string.pesdk_filter_asset_duotonePlum))
            add(FilterItem(DuotoneFilterAssetBreezy.ID, R.string.pesdk_filter_asset_duotoneBreezy))
            add(FilterItem(DuotoneFilterAssetDeepBlue.ID, R.string.pesdk_filter_asset_duotoneDeepBlue))
            add(FilterItem(DuotoneFilterAssetFrog.ID, R.string.pesdk_filter_asset_duotoneFrog))
            add(FilterItem(DuotoneFilterAssetSunset.ID, R.string.pesdk_filter_asset_duotoneSunset))
        }
    ))

    add(FolderItem("imgly_filter_category_bw", R.string.pesdk_filter_folder_b_and_w, ImageSource.create(R.drawable.pesdk_filter_category_b_w),
        DataSourceIdItemList<FilterItem>().apply {
            add(FilterItem(ColorFilterAssetAD1920.ID, R.string.pesdk_filter_asset_ad1920))
            add(FilterItem(ColorFilterAssetBW.ID, R.string.pesdk_filter_asset_bw))
            add(FilterItem(ColorFilterAssetX400.ID, R.string.pesdk_filter_asset_x400))
            add(FilterItem(ColorFilterAssetLitho.ID, R.string.pesdk_filter_asset_litho))
            add(FilterItem(ColorFilterAssetSepiahigh.ID, R.string.pesdk_filter_asset_sepiaHigh))
            add(FilterItem(ColorFilterAssetPlate.ID, R.string.pesdk_filter_asset_plate))
            add(FilterItem(ColorFilterAssetSin.ID, R.string.pesdk_filter_asset_sin))
        }
    ))

    add(FolderItem("imgly_filter_category_vintage", R.string.pesdk_filter_folder_vintage, ImageSource.create(R.drawable.pesdk_filter_category_vintage),
        DataSourceIdItemList<FilterItem>().apply {
            add(FilterItem(ColorFilterAssetBlues.ID, R.string.pesdk_filter_asset_blues))
            add(FilterItem(ColorFilterAssetFront.ID, R.string.pesdk_filter_asset_front))
            add(FilterItem(ColorFilterAssetTexas.ID, R.string.pesdk_filter_asset_texas))
            add(FilterItem(ColorFilterAssetCelsius.ID, R.string.pesdk_filter_asset_celsius))
            add(FilterItem(ColorFilterAssetCool.ID, R.string.pesdk_filter_asset_cool))
        }
    ))

    add(FolderItem("imgly_filter_category_smooth", R.string.pesdk_filter_folder_smooth, ImageSource.create(R.drawable.pesdk_filter_category_smooth),
        DataSourceIdItemList<FilterItem>().apply {
            add(FilterItem(ColorFilterAssetChest.ID, R.string.pesdk_filter_asset_chest))
            add(FilterItem(ColorFilterAssetWinter.ID, R.string.pesdk_filter_asset_winter))
            add(FilterItem(ColorFilterAssetKDynamic.ID, R.string.pesdk_filter_asset_dynamic))
            add(FilterItem(ColorFilterAssetFall.ID, R.string.pesdk_filter_asset_fall))
            add(FilterItem(ColorFilterAssetLenin.ID, R.string.pesdk_filter_asset_lenin))
            add(FilterItem(ColorFilterAssetPola669.ID, R.string.pesdk_filter_asset_669))
        }
    ))

    add(FolderItem("imgly_filter_category_cold", R.string.pesdk_filter_folder_cold, ImageSource.create(R.drawable.pesdk_filter_category_cold),
        DataSourceIdItemList<FilterItem>().apply {
            add(FilterItem(ColorFilterAssetElder.ID, R.string.pesdk_filter_asset_elder))
            add(FilterItem(ColorFilterAssetOrchid.ID, R.string.pesdk_filter_asset_orchid))
            add(FilterItem(ColorFilterAssetBleached.ID, R.string.pesdk_filter_asset_bleached))
            add(FilterItem(ColorFilterAssetBleachedBlue.ID, R.string.pesdk_filter_asset_bBlue))
            add(FilterItem(ColorFilterAssetBreeze.ID, R.string.pesdk_filter_asset_breeze))
            add(FilterItem(ColorFilterAssetBlueShadows.ID, R.string.pesdk_filter_asset_blueShade))
        }
    ))

    add(FolderItem("imgly_filter_category_warm", R.string.pesdk_filter_folder_warm, ImageSource.create(R.drawable.pesdk_filter_category_warm),
        DataSourceIdItemList<FilterItem>().apply {
            add(FilterItem(ColorFilterAssetSunset.ID, R.string.pesdk_filter_asset_sunset))
            add(FilterItem(ColorFilterAssetEighties.ID, R.string.pesdk_filter_asset_80s))
            add(FilterItem(ColorFilterAssetEvening.ID, R.string.pesdk_filter_asset_evening))
            add(FilterItem(ColorFilterAssetK2.ID, R.string.pesdk_filter_asset_k2))
            add(FilterItem(ColorFilterAssetNoGreen.ID, R.string.pesdk_filter_asset_noGreen))
        }
    ))

    add(FolderItem("imgly_filter_category_legacy", R.string.pesdk_filter_folder_legacy, ImageSource.create(R.drawable.pesdk_filter_category_legacy),
        DataSourceIdItemList<FilterItem>().apply {
            add(FilterItem(ColorFilterAssetAncient.ID, R.string.pesdk_filter_asset_ancient))
            add(FilterItem(ColorFilterAssetCottonCandy.ID, R.string.pesdk_filter_asset_candy))
            add(FilterItem(ColorFilterAssetClassic.ID, R.string.pesdk_filter_asset_classic))
            add(FilterItem(ColorFilterAssetColorful.ID, R.string.pesdk_filter_asset_colorful))
            add(FilterItem(ColorFilterAssetCreamy.ID, R.string.pesdk_filter_asset_creamy))
            add(FilterItem(ColorFilterAssetFixie.ID, R.string.pesdk_filter_asset_fixie))
            add(FilterItem(ColorFilterAssetFood.ID, R.string.pesdk_filter_asset_food))
            add(FilterItem(ColorFilterAssetFridge.ID, R.string.pesdk_filter_asset_fridge))
            add(FilterItem(ColorFilterAssetGlam.ID, R.string.pesdk_filter_asset_glam))
            add(FilterItem(ColorFilterAssetGobblin.ID, R.string.pesdk_filter_asset_goblin))
            add(FilterItem(ColorFilterAssetHighContrast.ID, R.string.pesdk_filter_asset_hicon))
            add(FilterItem(ColorFilterAssetHighCarb.ID, R.string.pesdk_filter_asset_carb))
            add(FilterItem(ColorFilterAssetK1.ID, R.string.pesdk_filter_asset_k1))
            add(FilterItem(ColorFilterAssetK6.ID, R.string.pesdk_filter_asset_k6))
            add(FilterItem(ColorFilterAssetKeen.ID, R.string.pesdk_filter_asset_keen))
            add(FilterItem(ColorFilterAssetLomo.ID, R.string.pesdk_filter_asset_lomo))
            add(FilterItem(ColorFilterAssetLomo100.ID, R.string.pesdk_filter_asset_lomo100))
            add(FilterItem(ColorFilterAssetLucid.ID, R.string.pesdk_filter_asset_lucid))
            add(FilterItem(ColorFilterAssetMellow.ID, R.string.pesdk_filter_asset_mellow))
            add(FilterItem(ColorFilterAssetNeat.ID, R.string.pesdk_filter_asset_neat))
            add(FilterItem(ColorFilterAssetPale.ID, R.string.pesdk_filter_asset_pale))
            add(FilterItem(ColorFilterAssetPitched.ID, R.string.pesdk_filter_asset_pitched))
            add(FilterItem(ColorFilterAssetPolaSx.ID, R.string.pesdk_filter_asset_sx))
            add(FilterItem(ColorFilterAssetPro400.ID, R.string.pesdk_filter_asset_pro400))
            add(FilterItem(ColorFilterAssetQuozi.ID, R.string.pesdk_filter_asset_quozi))
            add(FilterItem(ColorFilterAssetSettled.ID, R.string.pesdk_filter_asset_settled))
            add(FilterItem(ColorFilterAssetSeventies.ID, R.string.pesdk_filter_asset_70s))
            add(FilterItem(ColorFilterAssetSoft.ID, R.string.pesdk_filter_asset_soft))
            add(FilterItem(ColorFilterAssetSteel.ID, R.string.pesdk_filter_asset_steel))
            add(FilterItem(ColorFilterAssetSummer.ID, R.string.pesdk_filter_asset_summer))
            add(FilterItem(ColorFilterAssetTender.ID, R.string.pesdk_filter_asset_tender))
            add(FilterItem(ColorFilterAssetTwilight.ID, R.string.pesdk_filter_asset_twilight))
        }
    ))
}