Skip to main content
PESDK/Android/Guides/Border Frames/Add Frames
Language:

From Resources

PhotoEditor SDK supports adding custom frames from the resources. In this example, we add custom static and dynamic frames.

WARNING: Be sure to put the drawables for the frames in the res/drawable-nodpi folder. Otherwise, they will be scaled by the Android system.

Static frame#

Here, we create a static frame using FrameAsset. It takes in a unique identifier (used for serialization/deserialization purposes), the resource drawable, aspect ratio supported by the frame, and group id. The group id is used to group static frames. When the aspect ratio of the photo changes, a frame with the same group id that supports the new aspect ratio is used to replace the older frame.

Dynamic frame#

Dynamic frames consist of four groups, corresponding to each side of the frame. In our example, we opt for the "horizontal inside" mode of arranging image tiles providing only a middle image for the left and right parts of the frame and a start, middle and end image for the top and bottom parts. Refer to the guide on dynamic frames for an in-depth explanation.

We create a dynamic frame using FrameAsset. It takes in a unique identifier (used for serialization/deserialization purposes), CustomPatchFrameAsset, and relative scale. A CustomPatchFrameAsset takes in the frame layout mode (HorizontalInside or VerticalInside), and the four image groups (top, left, right, bottom). The relative scale is used to describe how big the frame should be with respect to the photo it will be applied to.

Add frames to AssetConfig#

To use the frames, they must first be available in the SDK's backend. This is done by adding the frames to the AssetConfig.

Configure UiConfigFrame#

Here, we configure UiConfigFrame and add the custom FrameItems to the frameList.

File:
class PhotoAddFramesFromResources(private val activity: AppCompatActivity) : Example(activity) {
override fun invoke() {
// In this example, we do not need access to the Uri(s) after the editor is closed
// so we pass false in the constructor
val settingsList = PhotoEditorSettingsList(false)
// Set the source as the Uri of the image to be loaded
.configure<LoadSettings> {
it.source = activity.resourceUri(R.drawable.la)
}
// Create a custom static frame
// A static FrameAsset takes in a unique identifier (used for serialization/deserialization purposes), the resource drawable,
// aspect ratio supported by the frame, and group id. The group id is used to group static frames
// When the aspect ratio of the photo changes, a frame with the same group id that supports the new aspect ratio is used to replace the older frame
val customStaticFrame = FrameAsset(
"custom_static_frame",
R.drawable.imgly_frame_rainbow,
CropAspectAsset("imgly_crop_1_1", 1, 1, false),
1
)
// Create a custom dynamic frame
// A dynamic FrameAsset takes in a unique identifier (used for serialization/deserialization purposes), CustomPatchFrameAsset, and relative scale
// A CustomPatchFrameAsset takes in the frame layout mode (HorizontalInside or VerticalInside), and the four image groups (top, left, right, bottom)
// The relative scale is used to describe how big the frame should be in relation to the photo it will be applied to
val customDynamicFrame = FrameAsset(
"custom_dynamic_frame",
CustomPatchFrameAsset(
FrameLayoutMode.HorizontalInside,
FrameImageGroup(
ImageSource.create(R.drawable.imgly_frame_lowpoly_top_left),
ImageSource.create(R.drawable.imgly_frame_lowpoly_top),
FrameTileMode.Stretch,
ImageSource.create(R.drawable.imgly_frame_lowpoly_top_right)
),
FrameImageGroup(
ImageSource.create(R.drawable.imgly_frame_lowpoly_left),
FrameTileMode.Repeat
),
FrameImageGroup(
ImageSource.create(R.drawable.imgly_frame_lowpoly_right),
FrameTileMode.Repeat
),
FrameImageGroup(
ImageSource.create(R.drawable.imgly_frame_lowpoly_bottom_left),
ImageSource.create(R.drawable.imgly_frame_lowpoly_bottom),
FrameTileMode.Stretch,
ImageSource.create(R.drawable.imgly_frame_lowpoly_bottom_right)
)
),
0.075f
)
// Add assets to AssetConfig
settingsList.config.addAsset(customStaticFrame, customDynamicFrame)
settingsList.configure<UiConfigFrame> {
// Add custom frame to the UI
it.frameList.add(FrameItem("custom_static_frame", "Rainbow", ImageSource.create(R.drawable.imgly_frame_rainbow_thumb)))
it.frameList.add(FrameItem("custom_dynamic_frame", "Dynamic Rainbow", ImageSource.create(R.drawable.imgly_frame_rainbow_thumb)))
}
// Start the photo editor using PhotoEditorBuilder
// The result will be obtained in onActivityResult() corresponding to EDITOR_REQUEST_CODE
PhotoEditorBuilder(activity)
.setSettingsList(settingsList)
.startActivityForResult(activity, EDITOR_REQUEST_CODE)
// Release the SettingsList once done
settingsList.release()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
intent ?: return
if (requestCode == EDITOR_REQUEST_CODE) {
// Wrap the intent into an EditorSDKResult
val result = EditorSDKResult(intent)
when (result.resultStatus) {
EditorSDKResult.Status.CANCELED -> showMessage("Editor cancelled")
EditorSDKResult.Status.EXPORT_DONE -> showMessage("Result saved at ${result.resultUri}")
else -> {
}
}
}
}
}