- Supported image formats
- Open an image
- Save as image
- Events to handle save actions
Contact Support
Open and save in the Vue Image Editor component
25 Apr 202524 minutes to read
To import an image into the canvas, it must first be converted into a blob object. The Uploader
component can be used to facilitate the process of uploading an image from the user interface. Once the image has been uploaded, it can then be converted into a blob and drawn onto the canvas.
To save an edited image in the Image Editor component, use the toBlob method to convert it to a blob object. This will save the image with any annotations or filters that have been applied during the editing process. The saved image can be stored as raw image data or as an image file.
Supported image formats
The Image Editor control supports four common image formats: PNG, JPEG, SVG, and WEBP. These formats allow you to work with a wide range of image files within the Image Editor.
When it comes to saving the edited image, the default file type is set as PNG. This means that when you save the edited image without specifying a different file type, it will be saved as a PNG file. However, it’s important to note that the Image Editor typically provides options or methods to specify a different file type if desired. This allows you to save the edited image in formats other than the default PNG, such as JPEG, SVG, or WEBP, based on your specific requirements or preferences.
Open an image
The open
method in the Image Editor control offers the capability to open an image by providing it in different formats. This method accepts various types of arguments, such as a base64-encoded string, raw image data, or a hosted/online URL. You can pass either the file name or the actual image data as an argument to the open
method, and it will load the specified image into the Image Editor control. This flexibility allows you to work with images from different sources and formats, making it easier to integrate and manipulate images within the Image Editor control.
Opening local images in the Image Editor
Users can easily open local images in the Image Editor. Simply place the image in the same folder as the sample. By specifying the local file name directly in the open
method, the image will be loaded seamlessly into the editor.
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px" :toolbar="toolbar">
</ejs-imageeditor>
<ejs-button id="open-btn" cssClass="e-primary" @click="openImage">Open Image</ejs-button>
</div>
</template>
<script setup>
import { ref } from "vue";
import { ImageEditorComponent as EjsImageeditor } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent as EjsButton } from "@syncfusion/ej2-vue-buttons";
const imageEditorObj = ref(null);
const toolbar = ref([]);
const openImage = () => {
if (imageEditorObj.value) {
imageEditorObj.value.open('https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png');
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px" :toolbar="toolbar">
</ejs-imageeditor>
<ejs-button id="open-btn" cssClass="e-primary" @click="openImage">Open Image</ejs-button>
</div>
</template>
<script>
import { ImageEditorComponent } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent } from "@syncfusion/ej2-vue-buttons";
import { Browser } from "@syncfusion/ej2-base";
export default {
name: "App",
components: {
"ejs-imageeditor": ImageEditorComponent,
"ejs-button": ButtonComponent
},
data() {
return {
toolbar: []
};
},
methods: {
openImage() {
this.$refs.imageEditorObj.open('https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png');
}
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
Open an image from base64 format
Users can easily open images in the Image Editor using a Base64-encoded string. This method allows you to load images directly from their Base64 representation, ensuring seamless integration and flexibility in your application. Simply pass the Base64 string to the open
method, and the image will be loaded into the editor.
Note:
You can obtain the Base64 representation of an image from the Image Editor using the getImageData
method. This process will be explained in the upcoming section.
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"
:created="created"></ejs-imageeditor>
<ejs-button cssClass="e-img-button" :isPrimary="true" @click="saveImage">Save Base64</ejs-button>
<ejs-button cssClass="e-img-button" :isPrimary="true" @click="setImage">Load Base64</ejs-button>
</div>
</template>
<script setup>
import { ref } from "vue";
import { ImageEditorComponent as EjsImageeditor } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent as EjsButton } from "@syncfusion/ej2-vue-buttons";
import { Browser } from "@syncfusion/ej2-base";
const imageEditorObj = ref(null);
const base64String = ref("");
const created = () => {
const imageEditor = imageEditorObj.value?.ej2Instances;
if (!imageEditor) return;
const imageUrl = Browser.isDevice
? "https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png"
: "https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png";
imageEditor.open(imageUrl);
};
const saveImage = () => {
if (imageEditorObj.value) {
const instance = imageEditorObj.value.ej2Instances;
const imageData = instance.getImageData();
const canvas = document.createElement("canvas");
canvas.width = imageData.width;
canvas.height = imageData.height;
const context = canvas.getContext("2d");
if (context) {
context.putImageData(imageData, 0, 0);
base64String.value = canvas.toDataURL();
}
}
};
const setImage = () => {
if (imageEditorObj.value && base64String.value) {
imageEditorObj.value.ej2Instances.open(base64String.value);
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"
:created="onCreated"></ejs-imageeditor>
<ejs-button cssClass="e-img-button" :isPrimary="true" v-on:click="saveImage">Save Base64</ejs-button>
<ejs-button cssClass="e-img-button" :isPrimary="true" v-on:click="setImage">Load Base64</ejs-button>
</div>
</template>
<script>
import { ImageEditorComponent } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent } from '@syncfusion/ej2-vue-buttons';
import { Browser } from "@syncfusion/ej2-base";
var base64String = '';
export default {
name: "App",
components: {
"ejs-imageeditor": ImageEditorComponent,
"ejs-button": ButtonComponent
},
data: function () {
return {
base64String
};
},
methods: {
onCreated() {
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!imageEditor) return;
let imageUrl = Browser.isDevice
? 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png'
: 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png';
imageEditor.open(imageUrl);
},
saveImage: function () {
let imageData = this.$refs.imageEditorObj.ej2Instances.getImageData();
const canvas = document.createElement('canvas');
canvas.width = imageData.width;
canvas.height = imageData.height;
const context = canvas.getContext('2d');
context.putImageData(imageData, 0, 0);
base64String = canvas.toDataURL();
},
setImage: function () {
if (base64String) {
this.$refs.imageEditorObj.ej2Instances.open(base64String);
}
}
}
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
Open an image from Blob storage
User can easily open images in the Image Editor from Blob storage. This method allows you to load images directly from Blob storage, ensuring seamless integration and flexibility in your application. Simply retrieve the image Blob from storage and pass it to the open
method, and the image will be loaded into the editor.
Note:
You can obtain the Blob URL representation of an image from the Image Editor using the getImageData
method. This process will be explained in the upcoming section.
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"
:created="created"></ejs-imageeditor>
<ejs-button cssClass="e-img-button" :isPrimary="true" v-on:click="getBlob">Save Blob</ejs-button>
<ejs-button cssClass="e-img-button" :isPrimary="true" v-on:click="setImage">Load Blob</ejs-button>
</div>
</template>
<script setup>
import { ImageEditorComponent as EjsImageeditor } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent as EjsButton } from '@syncfusion/ej2-vue-buttons';
import { Browser } from "@syncfusion/ej2-base";
import { ref } from "vue";
const imageEditorObj = ref(null);
let blobUrl;
const created = () => {
const imageEditor = imageEditorObj.value?.ej2Instances;
if (!imageEditor) return;
const imageUrl = Browser.isDevice
? "https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png"
: "https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png";
imageEditor.open(imageUrl);
};
const getBlob = () => {
let imageData = imageEditorObj.value.ej2Instances.getImageData();
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
canvas.width = imageData.width;
canvas.height = imageData.height;
ctx.putImageData(imageData, 0, 0);
canvas.toBlob((blob) => {
blobUrl = URL.createObjectURL(blob);
});
};
const setImage = () => {
if (blobUrl) {
imageEditorObj.value.ej2Instances.open(blobUrl);
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px" :created="created"></ejs-imageeditor>
<ejs-button cssClass="e-img-button" :isPrimary="true" v-on:click="saveBlob">Save Blob</ejs-button>
<ejs-button cssClass="e-img-button" :isPrimary="true" v-on:click="setImage">Open Blob</ejs-button>
</div>
</template>
<script>
import { ImageEditorComponent } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent } from '@syncfusion/ej2-vue-buttons';
import { Browser } from "@syncfusion/ej2-base";
var blobUrl;
export default {
name: "App",
components: {
"ejs-imageeditor": ImageEditorComponent,
"ejs-button": ButtonComponent
},
data: function () {
return {
blobUrl
};
},
methods: {
created() {
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!imageEditor) return;
let imageUrl = Browser.isDevice
? 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png'
: 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png';
imageEditor.open(imageUrl);
},
saveBlob: function () {
let imageData = this.$refs.imageEditorObj.ej2Instances.getImageData();
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
canvas.width = imageData.width;
canvas.height = imageData.height;
ctx.putImageData(imageData, 0, 0);
canvas.toBlob((blob) => {
blobUrl = URL.createObjectURL(blob);
});
},
setImage: function () {
if (blobUrl) {
this.$refs.imageEditorObj.ej2Instances.open(blobUrl);
}
}
}
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
Open an image from File Uploader
User can easily open images in the Image Editor using a file uploader. This method allows users to upload an image file from their device and load it directly into the editor. Once the image is selected through the file uploader, pass the file to the open
method, and the image will be seamlessly loaded into the editor.
<template>
<div>
<ejs-uploader ref="uploadObj" id='defaultfileupload' name="UploadFiles" :selected="onSelect"
:showFileList="false"></ejs-uploader>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"></ejs-imageeditor>
</div>
</template>
<script setup>
import { ImageEditorComponent as EjsImageeditor } from "@syncfusion/ej2-vue-image-editor";
import { UploaderComponent as EjsUploader } from '@syncfusion/ej2-vue-inputs';
import { ref } from "vue";
const imageEditorObj = ref(null);
const onSelect = (args) => {
if (args.filesData.length > 0) {
const reader = new FileReader();
reader.onload = () => {
imageEditorObj.value.open(reader.result);
};
reader.readAsDataURL(args.filesData[0].rawFile);
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 330px !important;
}
</style>
<template>
<div>
<ejs-uploader ref="uploadObj" id='defaultfileupload' name="UploadFiles" :selected="onSelect"
:showFileList="false"></ejs-uploader>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"></ejs-imageeditor>
</div>
</template>
<script>
import { ImageEditorComponent } from "@syncfusion/ej2-vue-image-editor";
import { UploaderComponent } from '@syncfusion/ej2-vue-inputs';
export default {
name: "App",
components: {
"ejs-imageeditor": ImageEditorComponent,
"ejs-uploader": UploaderComponent
},
data: function () {
return {};
},
methods: {
onSelect: function (args) {
if (args.filesData.length > 0) {
const reader = new FileReader();
reader.onload = () => {
this.$refs.imageEditorObj.ej2Instances.open(reader.result);
};
reader.readAsDataURL(args.filesData[0].rawFile);
}
},
}
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-vue-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 330px !important;
}
</style>
Open an image from File Manager
User can easily open images in the Image Editor using the File Manager. This method allows you to browse and select an image file directly from the File Manager and load it into the editor. Once the image is selected, pass the file to the open
method, and the image will be seamlessly loaded into the editor.
<template>
<div>
<div class="control-section">
<div class="sample-container">
<ejs-filemanager id="flat_data" :fileSystemData="fileSystemData" height="200px" @fileOpen="fileOpen"></ejs-filemanager>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"></ejs-imageeditor>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { FileManagerComponent as EjsFilemanager } from "@syncfusion/ej2-vue-filemanager";
import { ImageEditorComponent as EjsImageeditor} from "@syncfusion/ej2-vue-image-editor";
const fileSystemData = ref([
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\",
hasChild: true,
id: "0",
isFile: false,
name: "Pictures",
parentId: "0",
size: 228465,
type: "folder",
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\Pictures\\",
hasChild: false,
id: "1",
isFile: true,
name: "Flower",
parentId: "0",
size: 69632,
type: ".png",
imageUrl:
"https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png",
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\Pictures\\",
hasChild: false,
id: "2",
isFile: true,
name: "Bridge",
parentId: "0",
size: 48951,
type: ".png",
imageUrl:
"https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png",
},
]);
const imageEditorObj = ref(null);
const fileOpen = (args) => {
let file = args.fileDetails;
if (file.isFile && file.imageUrl) {
args.cancel = true;
imageEditorObj.value?.ej2Instances.open(file.imageUrl);
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
@import "../node_modules/@syncfusion/ej2-filemanager/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
<template>
<div>
<div class="control-section">
<div class="sample-container">
<ejs-filemanager id="flat_data" :fileSystemData="fileSystemData" height="200px" @fileOpen="fileOpen"></ejs-filemanager>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"
:toolbar="toolbar"></ejs-imageeditor>
</div>
</div>
</div>
</template>
<script>
import { FileManagerComponent } from "@syncfusion/ej2-vue-filemanager";
import { ImageEditorComponent } from "@syncfusion/ej2-vue-image-editor";
export default {
components: {
"ejs-filemanager": FileManagerComponent,
"ejs-imageeditor": ImageEditorComponent
},
data() {
return {
fileSystemData: [
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\",
hasChild: true,
id: "0",
isFile: false,
name: "Pictures",
parentId: "0",
size: 228465,
type: "folder"
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\Pictures\\",
hasChild: false,
id: "1",
isFile: true,
name: "Flower",
parentId: "0",
size: 69632,
type: ".png",
imageUrl:
"https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png"
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\Pictures\\",
hasChild: false,
id: "2",
isFile: true,
name: "Bridge",
parentId: "0",
size: 48951,
type: ".png",
imageUrl:
"https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png"
}
]
};
},
methods: {
fileOpen(args) {
let file = args.fileDetails;
if (file.isFile && file.imageUrl) {
args.cancel = true;
this.$refs.imageEditorObj.ej2Instances.open(file.imageUrl);
}
}
},
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
@import "../node_modules/@syncfusion/ej2-filemanager/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
Open an image from Treeview
Users can open images in the Syncfusion® Image Editor by selecting a node from a tree view. When a user clicks on an image node, the corresponding image is loaded into the editor using the open
method. This allows for a seamless image editing experience directly from the TreeView component.
<template>
<div>
<ejs-treeview id="treeview" ref="treeViewObj" :fields="fields" @nodeClicked="onNodeClick"></ejs-treeview>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"></ejs-imageeditor>
</div>
</template>
<script setup>
import { ref } from "vue";
import { ImageEditorComponent as EjsImageeditor } from "@syncfusion/ej2-vue-image-editor";
import { TreeViewComponent as EjsTreeview } from "@syncfusion/ej2-vue-navigations";
const imageEditorObj = ref(null);
const treeViewObj = ref(null);
const fields = ref({
dataSource: [
{
nodeId: "01",
nodeText: "Videos",
icon: "folder",
nodeChild: [
{ nodeId: "01-01", nodeText: "Naturals.mp4", icon: "video" },
{ nodeId: "01-02", nodeText: "Wild.mpeg", icon: "video" },
],
},
{
nodeId: "02",
nodeText: "Documents",
icon: "folder",
nodeChild: [
{ nodeId: "02-01", nodeText: "Environment Pollution.docx", icon: "docx" },
{ nodeId: "02-02", nodeText: "Global Water, Sanitation, & Hygiene.docx", icon: "docx" },
{ nodeId: "02-03", nodeText: "Global Warming.ppt", icon: "ppt" },
{ nodeId: "02-04", nodeText: "Social Network.pdf", icon: "pdf" },
{ nodeId: "02-05", nodeText: "Youth Empowerment.pdf", icon: "pdf" },
],
},
{
nodeId: "03",
nodeText: "Pictures",
icon: "folder",
expanded: true,
nodeChild: [
{
nodeId: "03-01",
nodeText: "Camera Roll",
icon: "folder",
expanded: true,
nodeChild: [
{
nodeId: "03-01-01",
nodeText: "Flower",
image: "https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png",
},
{
nodeId: "03-01-02",
nodeText: "Bridge",
image: "https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png",
},
],
},
],
},
],
id: "nodeId",
text: "nodeText",
child: "nodeChild",
});
const onNodeClick = (args) => {
let nodeId = args.node.getAttribute("data-uid");
let nodeData = treeViewObj.value.getTreeData(nodeId)[0];
if (nodeData && nodeData.image) {
imageEditorObj.value.ej2Instances.open(nodeData.image);
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
<template>
<div>
<ejs-treeview id="treeview" ref="treeViewObj" :fields="fields" @nodeClicked="onNodeClick"></ejs-treeview>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"></ejs-imageeditor>
</div>
</template>
<script>
import { ImageEditorComponent } from "@syncfusion/ej2-vue-image-editor";
import { TreeViewComponent } from "@syncfusion/ej2-vue-navigations";
export default {
name: "App",
components: {
"ejs-imageeditor": ImageEditorComponent,
"ejs-treeview": TreeViewComponent,
},
data() {
return {
fields: {
dataSource: [
{
nodeId: "03",
nodeText: "Pictures",
icon: "folder",
expanded: true,
nodeChild: [
{
nodeId: "03-01",
nodeText: "Camera Roll",
icon: "folder",
expanded: true,
nodeChild: [
{
nodeId: "03-01-01",
nodeText: "Flower",
image: "https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png",
},
{
nodeId: "03-01-02",
nodeText: "Bridge",
image: "https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png",
},
],
},
],
},
],
id: "nodeId",
text: "nodeText",
child: "nodeChild",
},
};
},
methods: {
onNodeClick(args) {
let treeView = this.$refs.treeViewObj?.ej2Instances;
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!treeView || !imageEditor) return;
let nodeId = args.node.getAttribute("data-uid");
let nodeData = treeView.getTreeData(nodeId)[0];
if (nodeData?.image) {
imageEditor.open(nodeData.image);
}
},
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
Add watermarks while opening an image
You can utilize the fileOpened
event, which triggers once the image is loaded into the image editor. After this event, you can use the drawText
method to add a watermark. This approach allows the watermark to be automatically drawn on the canvas every time an image is opened in the editor, making it useful for handling copyright-related content.
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px" :created="created"
@fileOpened="fileOpened"></ejs-imageeditor>
</div>
</template>
<script setup>
import { ref } from "vue";
import { ImageEditorComponent as EjsImageeditor } from "@syncfusion/ej2-vue-image-editor";
import { Browser } from "@syncfusion/ej2-base";
const imageEditorObj = ref(null);
const created = () => {
const imageEditor = imageEditorObj.value?.ej2Instances;
if (!imageEditor) return;
let imageUrl = Browser.isDevice
? "https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png"
: "https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png";
imageEditor.open(imageUrl);
};
const fileOpened = () => {
const imageEditor = imageEditorObj.value?.ej2Instances;
if (!imageEditor) return;
let dimension = imageEditor.getImageDimension();
imageEditor.drawText(dimension.x, dimension.y, "Syncfusion", "Arial", 40, false, false, "#80330075");
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px" :toolbar="toolbar" @fileOpened="fileOpened" :created="created"></ejs-imageeditor>
</div>
</template>
<script>
import { ImageEditorComponent } from '@syncfusion/ej2-vue-image-editor';
import { Browser } from '@syncfusion/ej2-base';
export default {
name: 'App',
components: {
'ejs-imageeditor': ImageEditorComponent,
},
data() {
return {};
},
methods: {
created() {
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!imageEditor) return;
let imageUrl = Browser.isDevice
? 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png'
: 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png';
imageEditor.open(imageUrl);
},
fileOpened() {
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!imageEditor) return;
let dimension = imageEditor.getImageDimension();
imageEditor.drawText(dimension.x, dimension.y, 'Syncfusion', 'Arial', 40, false, false, '#80330075');
},
},
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
Save as image
The export
method in the Image Editor component enables you to save the modified image as a file on the local device. This method accepts two parameters: the file name and the file type.
By providing a file name, you can specify the desired name for the saved image file. Additionally, you can also specify the file type to determine the format in which the image should be saved. This allows you to save the image according to your specific requirements or preferences, such as PNG, JPEG, SVG, and WEBP. Users are allowed to save an image with a specified file name, file type, and image quality. This enhancement provides more control over the output, ensuring that users can save their work exactly as they need it.
By utilizing the export
method with the appropriate file name and file type, you can conveniently save the modified image as a file on the local device, ensuring that it is easily accessible and shareable
In the following example, the export
method is used in the button click event.
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px" :toolbar="toolbar"
:created="created"></ejs-imageeditor>
<ejs-button cssClass="e-img-button" :isPrimary="true" v-on:click="btnClick">Save</ejs-button>
</div>
</template>
<script setup>
import { ImageEditorComponent as EjsImageeditor } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent as EjsButton } from '@syncfusion/ej2-vue-buttons';
import { Browser } from "@syncfusion/ej2-base";
import { ref } from "vue";
const imageEditorObj = ref(null);
const toolbar = [];
const created = () => {
const imageEditor = imageEditorObj.value?.ej2Instances;
if (!imageEditor) return;
let imageUrl = Browser.isDevice
? "https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png"
: "https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png";
imageEditor.open(imageUrl);
};
const btnClick = () => {
const imageEditor = imageEditorObj.value?.ej2Instances;
if (!imageEditor) return;
imageEditor.export("PNG", "Syncfusion"); // File type, file name
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"
:toolbar="toolbar" :created="created"></ejs-imageeditor>
<ejs-button cssClass="e-img-button" :isPrimary="true" v-on:click="btnClick">Save</ejs-button>
</div>
</template>
<script>
import { ImageEditorComponent } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent } from '@syncfusion/ej2-vue-buttons';
import { Browser } from "@syncfusion/ej2-base";
export default {
name: "App",
components: {
"ejs-imageeditor": ImageEditorComponent,
"ejs-button": ButtonComponent
},
data: function () {
return {
toolbar: []
};
},
methods: {
created() {
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!imageEditor) return;
let imageUrl = Browser.isDevice
? 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png'
: 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png';
imageEditor.open(imageUrl);
},
btnClick: function () {
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!imageEditor) return;
imageEditor.export("PNG", "Syncfusion"); // File type, file name
}
}
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
Save the image as base64 format
To save an image as a base64 format, use the getImageData
method of the editor to retrieve the image data and convert it into a Data URL, which contains the base64-encoded string. By invoking the open
method on the Syncfusion® Image Editor instance, you can load this Data URL into the editor. The resulting base64 string can then be embedded directly in HTML or CSS or transmitted over data channels without requiring an external file.
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"
:created="created"></ejs-imageeditor>
<ejs-button cssClass="e-img-button" :isPrimary="true" @click="saveImage">Save Image</ejs-button>
<ejs-button cssClass="e-img-button" :isPrimary="true" @click="setImage" v-if="false">Load Base64</ejs-button>
</div>
</template>
<script setup>
import { ref } from "vue";
import { ImageEditorComponent as EjsImageeditor } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent as EjsButton } from "@syncfusion/ej2-vue-buttons";
import { Browser } from "@syncfusion/ej2-base";
const imageEditorObj = ref(null);
const base64String = ref("");
const created = () => {
if (imageEditorObj.value) {
const instance = imageEditorObj.value.ej2Instances;
const imageUrl = Browser.isDevice
? "https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png"
: "https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png";
instance.open(imageUrl);
}
};
const saveImage = () => {
if (imageEditorObj.value) {
const instance = imageEditorObj.value.ej2Instances;
const imageData = instance.getImageData();
const canvas = document.createElement("canvas");
canvas.width = imageData.width;
canvas.height = imageData.height;
const context = canvas.getContext("2d");
if (context) {
context.putImageData(imageData, 0, 0);
base64String.value = canvas.toDataURL();
}
}
};
const setImage = () => {
if (imageEditorObj.value && base64String.value) {
imageEditorObj.value.ej2Instances.open(base64String.value);
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"
:created="created"></ejs-imageeditor>
<ejs-button cssClass="e-img-button" :isPrimary="true" v-on:click="saveImage">Save base64</ejs-button>
</div>
</template>
<script>
import { ImageEditorComponent } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent } from '@syncfusion/ej2-vue-buttons';
import { Browser } from "@syncfusion/ej2-base";
var base64String = '';
export default {
name: "App",
components: {
"ejs-imageeditor": ImageEditorComponent,
"ejs-button": ButtonComponent
},
data: function () {
return {
base64String
};
},
methods: {
created() {
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!imageEditor) return;
let imageUrl = Browser.isDevice
? 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png'
: 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png';
imageEditor.open(imageUrl);
},
saveImage: function () {
let imageData = this.$refs.imageEditorObj.ej2Instances.getImageData();
const canvas = document.createElement('canvas');
canvas.width = imageData.width;
canvas.height = imageData.height;
const context = canvas.getContext('2d');
context.putImageData(imageData, 0, 0);
base64String = canvas.toDataURL();
}
}
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
Save the image as byte[]
To save an image as a byte array, use the getImageData
method of the editor to retrieve the image data and convert it into a byte array. You can then invoke the open
method on the Syncfusion® Image Editor instance to load this byte array into the editor. The resulting byte array can be stored in a database for data management and maintenance.
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"
@created="created"></ejs-imageeditor>
<ejs-button cssClass="e-img-button" :isPrimary="true" @click="saveAsByteArray">
Save as Byte Array
</ejs-button>
<ejs-button cssClass="e-img-button" :isPrimary="true" @click="loadFromByteArray">
Load from Byte Array
</ejs-button>
</div>
</template>
<script setup>
import { ref } from "vue";
import { ImageEditorComponent as EjsImageeditor } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent as EjsButton } from "@syncfusion/ej2-vue-buttons";
import { Browser } from "@syncfusion/ej2-base";
const imageEditorObj = ref(null);
const byteArray = ref(null);
const created = () => {
const imageEditor = imageEditorObj.value?.ej2Instances;
if (!imageEditor) return;
const imageUrl = Browser.isDevice
? "https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png"
: "https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png";
imageEditor.open(imageUrl);
};
const saveAsByteArray = () => {
const imageEditor = imageEditorObj.value?.ej2Instances;
if (!imageEditor) return;
const imageData = imageEditor.getImageData();
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
if (!ctx) return;
canvas.width = imageData.width;
canvas.height = imageData.height;
ctx.putImageData(imageData, 0, 0);
canvas.toBlob((blob) => {
if (blob) {
const reader = new FileReader();
reader.readAsArrayBuffer(blob);
reader.onloadend = () => {
byteArray.value = new Uint8Array(reader.result);
};
}
}, "image/png");
};
const loadFromByteArray = () => {
if (!byteArray.value) return;
const blob = new Blob([byteArray.value], { type: "image/png" });
const url = URL.createObjectURL(blob);
imageEditorObj.value.ej2Instances.open(url);
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"
:created="created"></ejs-imageeditor>
<ejs-button cssClass="e-img-button" :isPrimary="true" v-on:click="saveAsByteArray">Save as Byte Array</ejs-button>
</div>
</template>
<script>
import { ImageEditorComponent } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent } from '@syncfusion/ej2-vue-buttons';
import { Browser } from "@syncfusion/ej2-base";
export default {
name: "App",
components: {
"ejs-imageeditor": ImageEditorComponent,
"ejs-button": ButtonComponent
},
data() {
return {
byteArray: null
};
},
methods: {
created() {
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!imageEditor) return;
let imageUrl = Browser.isDevice
? 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png'
: 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png';
imageEditor.open(imageUrl);
},
saveAsByteArray() {
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!imageEditor) return;
let imageData = imageEditor.getImageData();
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
if (!ctx) return;
canvas.width = imageData.width;
canvas.height = imageData.height;
ctx.putImageData(imageData, 0, 0);
canvas.toBlob((blob) => {
if (blob) {
const reader = new FileReader();
reader.readAsArrayBuffer(blob);
reader.onloadend = () => {
this.byteArray = new Uint8Array(reader.result);
};
}
}, 'image/png');
},
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
Save the image as Blob
To save an image as a blob, use the getImageData
method of the editor to retrieve the image data and convert it into a blob. You can then invoke the open
method on the Syncfusion® Image Editor instance to load this byte array into the editor. The resulting byte array can be stored in a database for data management and maintenance.
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"
:created="created"></ejs-imageeditor>
<ejs-button cssClass="e-img-button" :isPrimary="true" v-on:click="getBlob">Save blob</ejs-button>
<ejs-button cssClass="e-img-button" :isPrimary="true" v-on:click="setImage" v-if="false">Load base64</ejs-button>
</div>
</template>
<script setup>
import { ImageEditorComponent as EjsImageeditor } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent as EjsButton } from '@syncfusion/ej2-vue-buttons';
import { Browser } from "@syncfusion/ej2-base";
import { ref } from "vue";
const imageEditorObj = ref(null);
let blobUrl;
const created = () => {
const imageEditor = imageEditorObj.value?.ej2Instances;
if (!imageEditor) return;
const imageUrl = Browser.isDevice
? "https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png"
: "https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png";
imageEditor.open(imageUrl);
};
const getBlob = () => {
let imageData = imageEditorObj.value.ej2Instances.getImageData();
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
canvas.width = imageData.width;
canvas.height = imageData.height;
ctx.putImageData(imageData, 0, 0);
canvas.toBlob((blob) => {
blobUrl = URL.createObjectURL(blob);
});
};
const setImage = () => {
if (blobUrl) {
imageEditorObj.value.ej2Instances.open(blobUrl);
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px"
:created="created"></ejs-imageeditor>
<ejs-button cssClass="e-img-button" :isPrimary="true" v-on:click="getBlob">Save blob</ejs-button>
</div>
</template>
<script>
import { ImageEditorComponent } from "@syncfusion/ej2-vue-image-editor";
import { ButtonComponent } from '@syncfusion/ej2-vue-buttons';
import { Browser } from "@syncfusion/ej2-base";
var blobUrl = '';
export default {
name: "App",
components: {
"ejs-imageeditor": ImageEditorComponent,
"ejs-button": ButtonComponent
},
data: function () {
return {
blobUrl
};
},
methods: {
created() {
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!imageEditor) return;
let imageUrl = Browser.isDevice
? 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png'
: 'https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png';
imageEditor.open(imageUrl);
},
getBlob: function () {
let imageData = this.$refs.imageEditorObj.ej2Instances.getImageData();
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
canvas.width = imageData.width;
canvas.height = imageData.height;
ctx.putImageData(imageData, 0, 0);
canvas.toBlob((blob) => {
blobUrl = URL.createObjectURL(blob);
});
}
}
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
Add watermarks while saving the image
User can utilize the beforeSave
event, which triggers just before the image is downloaded, to apply a text annotation as a watermark. After the image is downloaded, the saved
event is triggered, allowing you to remove the watermark using the deleteShape
method. This ensures that the watermark is only visible in the downloaded image and not in the editor.
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px" :created="created"
@beforeSave="beforeSaved" @saved="saved"></ejs-imageeditor>
</div>
</template>
<script setup>
import { ref } from "vue";
import { ImageEditorComponent as EjsImageeditor } from "@syncfusion/ej2-vue-image-editor";
import { Browser } from "@syncfusion/ej2-base";
const imageEditorObj = ref(null);
const created = () => {
const imageEditor = imageEditorObj.value?.ej2Instances;
if (!imageEditor) return;
const imageUrl = Browser.isDevice
? "https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png"
: "https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png";
imageEditor.open(imageUrl);
};
const beforeSaved = () => {
const imageEditor = imageEditorObj.value?.ej2Instances;
if (!imageEditor) return;
const dimension = imageEditor.getImageDimension();
imageEditor.drawText(dimension.x, dimension.y, "Syncfusion", "Arial", 40, false, false, "#80330075");
};
const saved = () => {
const imageEditor = imageEditorObj.value?.ej2Instances;
if (!imageEditor) return;
const objects = imageEditor.getShapeSettings();
if (objects.length > 0) {
imageEditor.deleteShape(objects[objects.length - 1].id);
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
<template>
<div>
<ejs-imageeditor id="image-editor" ref="imageEditorObj" height="350px" width="550px" :beforeSave="beforeSaved"
:saved="saved" :created="created"></ejs-imageeditor>
</div>
</template>
<script>
import { ImageEditorComponent } from "@syncfusion/ej2-vue-image-editor";
import { Browser } from "@syncfusion/ej2-base";
export default {
name: "App",
components: {
"ejs-imageeditor": ImageEditorComponent
},
methods: {
created() {
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!imageEditor) return;
let imageUrl = Browser.isDevice
? "https://ej2.syncfusion.com/react/demos/src/image-editor/images/flower.png"
: "https://ej2.syncfusion.com/react/demos/src/image-editor/images/bridge.png";
imageEditor.open(imageUrl);
},
beforeSaved() {
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!imageEditor) return;
let dimension = imageEditor.getImageDimension();
imageEditor.drawText(dimension.x, dimension.y, "Syncfusion", "Arial", 40, false, false, "#80330075");
},
saved() {
let imageEditor = this.$refs.imageEditorObj?.ej2Instances;
if (!imageEditor) return;
let objects = imageEditor.getShapeSettings();
if (objects.length > 0) {
imageEditor.deleteShape(objects[objects.length - 1].id);
}
}
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-image-editor/styles/material.css";
#image-editor {
width: 550px !important;
height: 350px !important;
}
</style>
Remove default save button and add custom button to save the image to server
User can leverage the toolbar
property to replace the default save button with a custom one. By doing so, you can use the getImageData
method to retrieve the image data, convert it to base64 format, and then save it to the server. This approach gives you more control over the image-saving process.
Prevent default save option and save the image to specific location
User can make use of the beforeSave
event, which triggers just before the image is downloaded, to override the default save option by setting args.cancel
to true. Afterward, you can utilize the getImageData
method to retrieve the current image data and convert it into a format like byte[]
, blob
, or base64
for further processing. This gives you greater flexibility in handling the image data.
Events to handle save actions
The Image Editor provides several events related to opening and saving images. These events offer detailed control over the image handling process. For comprehensive information about these events, including their triggers and usage, please refer to the dedicated section on open and save support. This section will provide you with the specifics needed to effectively utilize these events in your application.
File opened event
The fileOpened
event is triggered in the Image Editor component after an image is successfully loaded. It provides the OpenEventArgs
as the event argument, which contains two specific arguments:
-
FileName: This argument is a string that contains the file name of the opened image. It represents the name of the file that was selected or provided when loading the image into the Image Editor.
-
FileType: This argument is a string that contains the type of the opened image. It specifies the format or file type of the image that was loaded, such as PNG, JPEG, SVG, or WEBP.
By accessing these arguments within the fileOpened
event handler, you can retrieve information about the loaded image, such as its file name and file type. This can be useful for performing additional actions or implementing logic based on the specific image that was opened in the Image Editor component.
Saving event
The saving
event is triggered in the Image Editor component when an image is being saved to the local disk. It provides the SaveEventArgs
as the event argument, which includes the following specific arguments:
-
FileName: This argument is a string that holds the file name of the saved image. It represents the name of the file that will be used when saving the image to the local disk.
-
FileType: This argument is a string indicating the type or format of the saved image. It specifies the desired file type in which the image will be saved, such as PNG, JPEG, SVG, or WEBP.
-
Cancel: This argument is a boolean value that can be set to true in order to cancel the saving action. By default, it is set to false, allowing the saving process to proceed. However, if you want to prevent the saving action from occurring, you can set Cancel to true within the event handler.
By accessing these arguments within the Saving event handler, you can retrieve information about the file name and file type of the image being saved. Additionally, you have the option to cancel the saving action if necessary.
Created event
The created
event is triggered once the Image Editor component is created. This event serves as a notification that the component has been fully initialized and is ready to be used. It provides a convenient opportunity to render the Image Editor with a predefined set of initial settings, including the image, annotations, and transformations.
Destroyed event
The destroyed
event is triggered once the Image Editor component is destroyed or removed from the application. This event serves as a notification that the component and its associated resources have been successfully cleaned up and are no longer active.