In one of the previous blog posts, we gave you a quick overview of how to use RadImageEditorUI to add a basic image editor to your application in a few simple steps. However, there is often a need for more customized image editing capabilities, in which case you can use the bare-bone RadImageEditor control. It doesn’t force a specific UI, so you can choose one that will best integrate in your application.
Whereas RadImageEditorUI contains all the UI you need from a basic image editor, RadImageEditor consists only of the image that is being edited. It has an API that you can use to load/save images, perform operations on the image and bind other controls to it (zoom settings for example). In this online demo we will describe how you can create your own UI, instead of using RadImageEditorUI.
For starters, let’s take a look at the commands of the image editor. They reside in the Commands property of RadImageEditor. For example, you can trigger the open command, which shows a dialog for the user to choose an image, by using
In the same way, you can execute all kinds of commands, such as Undo, Redo, Save, InvertColors, etc. However, there is more to RadImageEditor than plain commands, which simply execute an action on the image. There are tools, which enable the user to modify the settings of the effect and get a live preview for it before actually committing the change. There are a number of tools that work out-of-the-box, namely:
- Canvas Resize
- Round Corners (including border)
- Hue Shift
- Contrast (and brightness)
- Sharpen and Blur
Image Format Support
By default, RadImageEditor supports opening JPEG, PNG and BMP images and saving to PNG and BMP. One way to load an image file is by using the OpenCommand as shown previously, which will open a dialog box to the user and let him/her choose an image from the local drives. Alternatively, there are format providers (classes implementing the IImageFormatProvider interface), which you can utilize to import/export images from/to RadBitmap. Currently, we have BmpFormatProvider (import & export), PngFormatProvider (import & export) and JpegFormatProvider (import only). They are available as standalone classes and through the ImageFormatProviderManager class. The ImageFormatProviderManager is used by OpenCommand and SaveCommand and can return a format provider by extension. You can also register your format provider by using the RegisterFormatProvider method, so that it will get used by the open and save commands.
Image editing is quite memory intensive – consider the fact that a 3960px x 2160px image (Quad HD, about the maximum size for which the RadImageEditor is designed) is well over 34MB when stored in memory. As RadImageEditor contains undo/redo functionality, keeping every step in the history stack as a copy of the image can get quite heavy. In order to make memory requirements manageable, RadImageEditor uses an adaptive cache scheme – it retains images along with the commands and their arguments in the history stack. When memory depletes, it can delete some images, but can recreate them later from previous history points. You have control over the maximum amount of memory taken by the image history through the RadImageEditor.History.MaximumMemoryBufferSize property. The default value is 256MB for Silverlight and 512MB for WPF.
Most of the effects in RadImageEditor are implemented using pixel shaders, enabling the use of hardware acceleration whenever the platform supports it. This results in most effects being applied almost instantly, thus enabling realtime preview with sliders for the parameter values. You can easily implement a command using your own custom shader by implementing EffectCommandBase.
Here is an example of how a BlurCommand can be implemented, making it directly usable with the ExecuteCommand method of RadImageEditor:
.Radius = radius;
MyBlurCommand : EffectCommandBase
MyBlurCommandContext myContext = (MyBlurCommandContext)context;
Radius = myContext.Radius
You can create your own custom tool for RadImageEditor quite easily, too. You have to implement the ITool interface, which will give you the ability to setup your own preview, settings UI and attach to any events of RadImageEditor that are relevant to your tool. This offers you the full freedom to implement virtually any behavior you want within your tool. We have highlighted this in the following online demo, where a custom tool for watermarking is available along with its source code. The source code is available when you click the “Code” button in the top right corner of the application.
Implementing a custom format provider
Introducing a custom format provider is very easy with RadImageEditor. All you have to do is implement the IImageFormatProvider interface.
As JPEG encoding capabilities are missing in Silverlight, we have prepared a small demo on how to achieve this using FJCore (an open-source JPEG encoding and decoding library). It shows how a format provider that supports both importing and exporting of JPEGs can be implemented and plugged in the RadImageEditor architecture.
Image Editor JPEG CustomFormatProvider.zip