Custom usage of edited image

This sample demonstrates a usage of a new Flmngr API. The sample of legacy API usage can be found here.

Play on CodePen External link All samples on CodePen External link

Demo
HTML
JavaScript
CSS
<h1 class="h5 mb-3">Flmngr 2: custom image editing</h1>

<p>
  <img id="image" src="https://fm.n1ed.com/files/paper.png" alt="Some image">
</p>

<div id="btn" class="btn btn-primary" style="opacity:0.2;cursor:default">Edit image...</div>
<div id="loading" style="font-size:12px">Loading file manager...</div>
// In real app replace with:
// import Flmngr from "flmngr";
import Flmngr from "https://cdn.skypack.dev/flmngr";

Flmngr.load({
  apiKey: "FLMNFLMN",
  urlFileManager: 'https://fm.n1ed.com/fileManager',
  urlFiles: 'https://fm.n1ed.com/files'
}, {
  onImgPenLoaded: () => {
    attachOnClickListenerToButton();
  }
});

function attachOnClickListenerToButton() {
  let elBtn = document.getElementById("btn");

  // Style button as ready to be pressed
  elBtn.style.opacity = 1;
  elBtn.style.cursor = "pointer";
  let elLoading = document.getElementById("loading");
  elLoading.parentElement.removeChild(elLoading);

  // Add a listener for editing currently shown image
  elBtn.addEventListener("click", () => {
    editImage();
  });
}

function editImage() {

  Flmngr.edit({
    url: decodeURI(document.getElementById("image").getAttribute("src")),

    onSave: (onExport, onClose) => {
      // You can use "onExport" function to export the canvas as many times as you need.
      // Call "onClose" function to close the image editor.
      onExport(
        "new_name",
        "jpg",
        95,
        (imageBlob) => {

          // Convert image (Blob object) into Base64
          let reader = new FileReader();
          reader.onloadend = () => {
            let base64 = reader.result;                

            // Append a new image onto the document
            let elImg = document.getElementById("image");
            let elImgNew = document.createElement("img");
            elImgNew.src = base64;
            elImg.parentElement.appendChild(elImgNew); 

            onClose();
          }
          reader.readAsDataURL(imageBlob); 

        }
      );

    },
    onFail: (error) => {
      alert("Error: " + error);
    }
  });
}
body {
  padding: 20px;
  background-color: #F4F4F4;
}

img {
  max-width: 500px;
}

@-webkit-keyframes loading-animation {
  50% {
    opacity: 0.3;
  }
}
@keyframes loading-animation {
  50% {
    opacity: 0.3;
  }
}
.loading {
  animation: loading-animation 1s infinite;
}

A more tricky way to use image editor (which is a part of Flmngr file manager) is to avoid uploading the image result image and implement your own logic for using it. You also can pass into image editor image other than a file from Flmngr storage: image editor will act as an independent image editor and then you will decide what to do with the final file: open some custom saved dialog, pass it into the app, or something else.

This custom logic can be reached by using Flmngr.edit({params}) method.

url parameter for specifying the local or external (hosted on the 3rd party server) URL of an image. If this URL has another host (proto + domain + port) than one you run your app from, please be sure that CORS headers are configured correctly on the host with the image, this is a part of the security model of browsers.

onSave(onExport, onClose) callback will let you a space to make a decision on what to do with the edited image when he presses "Save" button, but the dialog is not closed yet. Use its onExport(...) method to get the output image and onClose() if you have done everything and are ready to close the dialog.

If you have some error while manipulating the image (or in your custom save dialog user cancelled process, or something like that) and do not want to close the image editor dialog, just do not call onClose() method, so you can wait until the edited image was really processed correctly or user cancels whole the editing process manually.

NPM

React

Snippet

TinyMCE

CKEditor 4

CKEditor 5

import Flmngr from "flmngr";

let elImg = document.getElementById("img"); // your own image

Flmngr.edit({
    apiKey: "FLMNFLMN",                                  // default free key
    urlFileManager: 'https://fm.flmngr.com/fileManager', // demo server
    urlFiles: 'https://fm.flmngr.com/files',             // demo file storage

    url: elImg.src,
    onSave: (onExport, onClose) => {
        onExport(
            "new_name",
            "jpg",
            95,
            (imageBlob) => {

                // Convert image (Blob object) into Base64
                let reader = new FileReader();
                reader.onloadend = () => {
                    var base64 = reader.result;                

                    // Append a new image onto the document
                    elImg.src = base64;

                    // Close image editor dialog
                    onClose();
                }
                reader.readAsDataURL(imageBlob); 

            }
        );
    },
    onFail: function(error) {
      alert(error);
    }
});
import Flmngr from "@flmngr/flmngr-react";
import * as React from "react";

export class MyButton extends React.Component {

    render() {
        return <button 
            onClick={() => {

                Flmngr.edit({
                    apiKey: "FLMNFLMN",                                  // default free key
                    urlFileManager: 'https://fm.flmngr.com/fileManager', // demo server
                    urlFiles: 'https://fm.flmngr.com/files',             // demo file storage

                    url: this.state.urlImage,
                    onSave: (onExport, onClose) => {
                        onExport(
                            "new_name",
                            "jpg",
                            95,
                            (imageBlob) => {

                                // Convert image (Blob object) into Base64
                                let reader = new FileReader();
                                reader.onloadend = () => {
                                    var base64 = reader.result;                

                                    // Append a new image onto the document
                                    this.setState({
                                        urlImage: base64
                                    }, () => {
                                        // Close image editor dialog
                                        onClose();
                                    });

                                }
                                reader.readAsDataURL(imageBlob); 

                            }
                        );
                    },
                    onFail: function(error) {
                      alert(error);
                    }
                });
            }}
        >
            Edit image
        </button>
    }

}
<script src="https://unpkg.com/flmngr"></script>
<script>
    window.onFlmngrAPILoaded = function() {
        window.Flmngr.edit({
            apiKey: "FLMNFLMN",                                  // default free key
            urlFileManager: 'https://fm.flmngr.com/fileManager', // demo server
            urlFiles: 'https://fm.flmngr.com/files',             // demo file storage

            url: elImg.src,
            onSave: (onExport, onClose) => {
                onExport(
                    "new_name",
                    "jpg",
                    95,
                    (imageBlob) => {

                        // Convert image (Blob object) into Base64
                        let reader = new FileReader();
                        reader.onloadend = () => {
                            var base64 = reader.result;                

                            // Append a new image onto the document
                            elImg.src = base64;

                            // Close image editor dialog
                            onClose();
                        }
                        reader.readAsDataURL(imageBlob); 

                    }
                );
            },
            onFail: function(error) {
              alert(error);
            }
        });
    }
</script>
// TinyMCE was initialized somewhere before
tinymce.activeEditor.getFlmngr(
    (Flmngr) => {
        Flmngr.edit({
            // Do not specify here 'apiKey', 'urlFileManager' and 'urlFiles' again
            // (it was passed in initialization code)
            url: elImg.src,
            onSave: (onExport, onClose) => {
                onExport(
                    "new_name",
                    "jpg",
                    95,
                    (imageBlob) => {

                        // Convert image (Blob object) into Base64
                        let reader = new FileReader();
                        reader.onloadend = () => {
                            var base64 = reader.result;                

                            // Append a new image onto the document
                            elImg.src = base64;

                            // Close image editor dialog
                            onClose();
                        }
                        reader.readAsDataURL(imageBlob); 

                    }
                );
            },
            onFail: function(error) {
              alert(error);
            }
        });
    }
);
// CKEditor was initialized somewhere before
CKEDITOR.instances["editor"].getFlmngr(
    (Flmngr) => {
        Flmngr.edit({
            // Do not specify here 'apiKey' again
            // (it was passed in initialization code or in 'config.js')
            url: elImg.src,
            onSave: (onExport, onClose) => {
                onExport(
                    "new_name",
                    "jpg",
                    95,
                    (imageBlob) => {

                        // Convert image (Blob object) into Base64
                        let reader = new FileReader();
                        reader.onloadend = () => {
                            var base64 = reader.result;                

                            // Append a new image onto the document
                            elImg.src = base64;

                            // Close image editor dialog
                            onClose();
                        }
                        reader.readAsDataURL(imageBlob); 

                    }
                );
            },
            onFail: function(error) {
              alert(error);
            }
        });
    }
);
ClassicEditor.create(
    document.querySelector('#editorId'), 
    {
        Flmngr: {
            apiKey: "FLMNFLMN",                                  // default free key
            urlFileManager: 'https://fm.flmngr.com/fileManager', // demo server
            urlFiles: 'https://fm.flmngr.com/files',             // demo file storage
        }
    } 
).then( 
    (editor) => {
        editor.getFlmngr(
            (Flmngr) => {
                Flmngr.edit({
                    // There is no need to set 'apiKey' here
                    // due to you already set it in the config of CKEditor.
                    url: elImg.src,
                    onSave: (onExport, onClose) => {
                        onExport(
                            "new_name",
                            "jpg",
                            95,
                            (imageBlob) => {

                                // Convert image (Blob object) into Base64
                                let reader = new FileReader();
                                reader.onloadend = () => {
                                    var base64 = reader.result;                

                                    // Append a new image onto the document
                                    elImg.src = base64;

                                    // Close image editor dialog
                                    onClose();
                                }
                                reader.readAsDataURL(imageBlob); 

                            }
                        );
                    },
                    onFail: function(error) {
                      alert(error);
                    }
                });
            }
        );
    } 
).catch((error) => {});