Setting up Pintura Image Editor with FilePond

For a quick start use the FilePond example project included in the product package as a guideline.

To set up the editor with FilePond we need to use the FilePondPluginImageEditor plugin which is included in the product package.

This plugin is different from the FilePondPluginImageEdit plugin that is described in the FilePond documentation.

When using Pintura Image Editor with FilePond the following plugins are no longer needed and thus have to be removed:

  • FilePondPluginImageExifOrientation
  • FilePondPluginImageTransform
  • FilePondPluginImageCrop
  • FilePondPluginImageFilter
  • FilePondPluginImagePreview
  • FilePondPluginImageResize
  • FilePondPluginImageEdit

We can use the FilePondPluginFilePoster plugin to show a preview of the image and the FilePondPluginFileValidateType plugin to only allow images.

Before continuing it's highly recommended to read the JavaScript installation guide as it clarifies important internal functionality of the image editor.

If we're using FilePond with a framework like React, Vue, Angular, or Svelte we don't need the framework specific image editor components, we can use the JavaScript version instead.

FilePondPluginImageEditor properties

The FilePondPluginImageEditor plugin adds the following properties to FilePond.

Some of the properties below look similar to the FilePondPluginImageEdit plugin. Pintura Image Editor v8 won't work in combination with the old plugin. Please remove the old plugin and replace it with FilePondPluginImageEditor.

Property Default value Description
allowImageEditor
true
Enable or disable the image editor plugin for this FilePond instance.
imageEditorInstantEdit
false
When true the editor will open immediately when an image is added to FilePond.
imageEditorAllowEdit
true
Enable or disable editing images for this FilePond instance.
imageEditorWriteImage
true
Enable or disable image writing for this FilePond instance. If set to false no image is generated.
imageEditorSupportEdit
isBrowser() &&
isModernBrowser() &&
supportsWebGL()
When true the browser supports editing images and the edit button will be rendered.
imageEditorSupportWriteImage
isModernBrowser()
When true the browser can process images, for example, when the browser doesn't support WebGL it might still be able to process an image.
imageEditorIconEdit
<svg>
The icon used for the edit button.
styleImageEditorButtonEditItemPosition
'bottom center'
The position of the edit button on the file item.
imageEditorAfterWriteImage
(res) => res.dest
Called after the output image is written and before it's returned to FilePond. Use for generating more than one output image, additionally uploading the original source image, and/or renaming the output file.
imageEditor
null
The image editor configuration to use.

imageEditorAfterWriteImage

This method is called when the output image is created by the image editor. It will receive the output of the image editor and will return it to FilePond.

This is the default implementation. It selects the output image and returns it to FilePond.

FilePond.create(document.querySelector('input'), {
    imageEditorAfterWriteImage: (res) => {
        return res.dest;
    },
});

The example below will return the original input image and the output image to FilePond for processing.

The value of the name property is automatically prepended to the name of the file during upload, if set to null the original file name is used.

FilePond.create(document.querySelector('input'), {
    imageEditorAfterWriteImage: (res) => {
        return [
            { name: 'input_', file: res.src },
            { name: 'output_', file: res.dest },
        ];
    },
});

This example uses the output image state and original image to create an additional thumbnail version of the output image.

FilePond.create(document.querySelector('input'), {
    imageEditorAfterWriteImage: ({ src, dest, imageState }) =>
        new Promise((resolve, reject) => {
            // use Pintura Image Editor to process the source image again
            processImage(src, {
                imageReader: createDefaultImageReader(),
                imageWriter: createDefaultImageWriter({
                    targetSize: {
                        width: 128,
                        height: 128,
                        fit: 'cover',
                    },
                }),
                imageState,
            })
                // we get the thumbnail and add it to the files
                .then((thumb) =>
                    resolve([
                        { name: 'input_', file: src },
                        { name: 'output_', file: dest },
                        { name: 'thumb_', file: thumb.dest },
                    ])
                )
                .catch(reject);
        }),
});

imageEditor

This property takes an image editor configuration object.

Property Description
legacyDataToImageState Set to legacyDataToImageState function to automatically map legacy Pintura Image Editor v6 objects to imageState objects.
createEditor Called by the ImageEditor plugin to open the image editor. Receives editor configuration, should return an editor instance.
imageReader Set to an array with two indexes. First index takes the imageReader configuration and the second index takes the optional imageReader options object.
imageWriter Set to an array with two indexes. First index takes the imageWriter configuration and the second index takes the optional imageWriter options object.
imageProcessor Used to generate images, runs an editor in the background, should be set to processImage, can be omitted if no output images are generated.
editorOptions Options to pass to the editor. For example the default imageCropAspectRatio and the locale object.

Default implementation example

In the default example below we'll use the getEditorDefaults method to quickly create an image editor.

This creates a "default" editor that has all available plugins loaded and comes preset with all plugin default options and English locale. Each of these settings can be adjusted freely.

<!DOCTYPE html>

<!-- FilePond styles -->
<link href="./filepond/filepond.css" rel="stylesheet" type="text/css" />
<link
    href="./filepond/filepond-plugin-file-poster.css"
    rel="stylesheet"
    type="text/css"
/>

<!-- Pintura Image Editor styles -->
<link href="./pintura/pintura.css" rel="stylesheet" />

<!-- File upload field -->
<input type="file" multiple />

<!-- FilePond scripts -->
<script src="./filepond/filepond.js"></script>
<script src="./filepond/filepond-plugin-file-poster.js"></script>
<script src="./filepond/filepond-plugin-file-validate-type.js"></script>

<!-- FilePond image editor plugin -->
<script src="./filepond-plugin-image-editor/FilePondPluginImageEditor.js"></script>

<script type="module">
    // import Pintura Image Editor modules
    import {
        // Image editor
        openEditor,
        processImage,
        createDefaultImageReader,
        createDefaultImageWriter,
        createDeafultImageOrienter,

        // Only needed if loading legacy image editor data
        legacyDataToImageState,

        // Import the editor default configuration
        getEditorDefaults,
    } from './pintura/pintura.js';

    FilePond.registerPlugin(
        FilePondPluginFileValidateType,
        FilePondPluginImageEditor,
        FilePondPluginFilePoster
    );

    var pond = FilePond.create(document.querySelector('input'), {
        // FilePond generic properties
        filePosterMaxHeight: 256,

        // FilePond Image Editor plugin properties
        imageEditor: {
            // Maps legacy data objects to new imageState objects (optional)
            legacyDataToImageState: legacyDataToImageState,

            // Used to create the editor (required)
            createEditor: openEditor,

            // Used for reading the image data. See JavaScript installation for details on the `imageReader` property (required)
            imageReader: [
                createDefaultImageReader,
                {
                    // createDefaultImageReader options here
                },
            ],

            // Can leave out when not generating a preview thumbnail and/or output image (required)
            imageWriter: [
                createDefaultImageWriter,
                {
                    // We'll resize images to fit a 512 × 512 square
                    targetSize: {
                        width: 512,
                        height: 512,
                    },
                },
            ],

            // Used to poster and output images, runs an invisible "headless" editor instance.
            imageProcessor: processImage,

            // Pintura Image Editor options
            editorOptions: {
                // Pass the editor default configuration options
                ...getEditorDefaults(),

                // This will set a square crop aspect ratio
                imageCropAspectRatio: 1,
            },
        },
    });
</script>

Advanced implementation example

In this example we'll create a custom editor, using a custom set of plugins, locale, and available options.

While this example is a lot more verbose it does allow us to create a more optimal editor package. The build process will tree-shake unused functionality resulting in a smaller build target.

<!DOCTYPE html>

<!-- FilePond styles -->
<link href="./filepond/filepond.css" rel="stylesheet" type="text/css" />
<link
    href="./filepond/filepond-plugin-file-poster.css"
    rel="stylesheet"
    type="text/css"
/>

<!-- Pintura Image Editor styles -->
<link href="./pintura/pintura.css" rel="stylesheet" />

<!-- File upload field -->
<input type="file" multiple />

<!-- FilePond scripts -->
<script src="./filepond/filepond.js"></script>
<script src="./filepond/filepond-plugin-file-poster.js"></script>
<script src="./filepond/filepond-plugin-file-validate-type.js"></script>

<!-- FilePond image editor plugin -->
<script src="./filepond-plugin-image-editor/FilePondPluginImageEditor.js"></script>

<script type="module">
    // import Pintura Image Editor modules
    import {
        // Image editor
        openEditor,
        processImage,
        createDefaultImageReader,
        createDefaultImageWriter,
        createDeafultImageOrienter,

        // Only needed if loading legacy image editor data
        legacyDataToImageState,

        // Import the editor default configuration
        getEditorDefaults,

        // The method used to register the plugins
        setPlugins,

        // The plugins we want to use
        plugin_crop,
        plugin_finetune,
        plugin_annotate,

        // The user interface and plugin locale objects
        locale_en_gb,
        plugin_crop_locale_en_gb,
        plugin_finetune_locale_en_gb,
        plugin_annotate_locale_en_gb,

        // Because we use the annotate plugin we also need
        // to import the markup editor locale
        markup_editor_locale_en_gb,

        // Import the default configuration for the markup editor and finetune plugins
        markup_editor_defaults,
        plugin_finetune_defaults,
    } from './pintura/pintura.js';

    FilePond.registerPlugin(
        FilePondPluginFileValidateType,
        FilePondPluginImageEditor,
        FilePondPluginFilePoster
    );

    // This registers the plugins with Pintura Image Editor
    setPlugins(plugin_crop, plugin_finetune, plugin_filter);

    var pond = FilePond.create(document.querySelector('input'), {
        // FilePond generic properties
        filePosterMaxHeight: 256,

        // FilePond Image Editor plugin properties
        imageEditor: {
            // Maps legacy data objects to new imageState objects (optional)
            legacyDataToImageState: legacyDataToImageState,

            // Used to create the editor (required)
            createEditor: openEditor,

            // Used for reading the image data. See JavaScript installation for details on the `imageReader` property (required)
            imageReader: [
                createDefaultImageReader,
                {
                    // createDefaultImageReader options here
                },
            ],

            // Can leave out when not generating a preview thumbnail and/or output image (required)
            imageWriter: [
                createDefaultImageWriter,
                {
                    // We'll resize images to fit a 512 × 512 square
                    targetSize: {
                        width: 512,
                        height: 512,
                    },
                },
            ],

            // Used to generate poster images, runs an invisible "headless" editor instance. (optional)
            imageProcessor: processImage,

            // Pintura Image Editor options
            editorOptions: {
                // The markup editor default options, tools, shape style controls
                ...markup_editor_defaults,

                // The finetune util controls
                ...plugin_finetune_defaults,

                // This will set a square crop aspect ratio
                imageCropAspectRatio: 1,

                // The icons and labels to use in the user interface (required)
                locale: {
                    ...locale_en_gb,
                    ...plugin_crop_locale_en_gb,
                    ...plugin_finetune_locale_en_gb,
                    ...plugin_annotate_locale_en_gb,
                    ...markup_editor_locale_en_gb,
                },
            },
        },
    });
</script>

Next steps

With the editor set up, we can continue to configure the editor to our liking by adjusting the available configuration options