Skip to content

WebNinjaDeveloper.com

Programming Tutorials




Menu
  • Home
  • Youtube Channel
  • Official Blog
  • Nearby Places Finder
  • Direction Route Finder
  • Distance & Time Calculator
Menu

Build a Electron.js Image Resizer Desktop App in Node.js Using Toastify Library Full Project For Beginners

Posted on October 11, 2022

 

 

Welcome folks today in this blog post we will be building a image resizer desktop app in node.js using electron framework & toastify library. All the full source code of the application will be shown below.

 

 

Get Started

 

 

In order to get started you need to install the below dependencies and packages which are required for this desktop App

 

 

  1. Electron: It is an open source framework used in node.js for developing desktop apps with the use of HTML5 CSS3 and Javascript

 

2) Toastify: This is a alert library where we can show colorful toast alert messages to the user

 

 

Installation

 

 

Now to install these modules we need to first of all start a new electron.js project as shown below in the commands

 

npm init -y

 

 

First of all we have initialized the package.json file for our node.js project. Now it’s time to install the dependencies as shown below

 

 

npm i electron --save-dev

 

 

This will install the electron framework for developing desktop apps. And -dev flag is assigned because it’s a dev dependency because it’s only need in development not in production.

 

 

npm i resize-img

 

 

This is the module which will actually resize the images inside node.js and electron.

 

 

npm i toastify-js

 

 

This is the library for showing colorful alert toast messages to the user whether success and error.

 

 

Starting the Electron App With Hot Reload

 

 

Now guys we will start the electron.js app with hot reload functionality so that whenever we make any kind of changes we don’t need to restart the server. You need to execute the below command as shown below

 

 

npx electronmon .

 

 

Directory Structure of Electronjs Project

 

 

Now we will be showing the directory structure of electronjs project as shown below

 

 

 

 

 

 

As you can see in the above pic we have two sections in electron.js app we have the renderer & main.js (Server-side) Code we need to communicate between them so that we can safely build out the app. For this we use inter process communication which is commonly called as IPC. We have bi-directional communication implemented in electron.js using events.

 

 

Creating a Basic Window in Electron

 

 

Now inside the main.js file we will be creating a basic window first of all of fixed width and height which will be displayed on the screen.

 

 

main.js

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const path = require('path');
const os = require('os');
const fs = require('fs');
const resizeImg = require('resize-img');
const { app, BrowserWindow, Menu, ipcMain, shell } = require('electron');
 
process.env.NODE_ENV = "production"
 
const isDev = process.env.NODE_ENV !== 'production';
const isMac = process.platform === 'darwin';
 
let mainWindow;
 
 
app.on('ready', () => {
  createMainWindow();
 
  // Remove variable from memory
  mainWindow.on('closed', () => (mainWindow = null));
});

 

 

As you can see in the above code we are importing the different methods from electron library. And then we have a simple electron app which have an event listener of ready. This means whenever the app loads and is ready we will calling this simple function of createMainWindow() which will actually renders out a window on the screen.

 

Now we need to define this createWindow() function where we will define how to create a new window in electron.js

 

 

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function createMainWindow() {
  mainWindow = new BrowserWindow({
    width: isDev ? 1000 : 500,
    height: 600,
    resizable: isDev,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js'),
    },
  });
 
  // Show devtools automatically if in development
  if (isDev) {
    mainWindow.webContents.openDevTools();
  }
 
    // mainWindow.loadURL(`file://${__dirname}/renderer/index.html`);
   mainWindow.loadFile(path.join(__dirname, './renderer/index.html'));
}

 

 

As you can see in the above code we are initializing a new window having fixed width and height and also passing some options to it. And also we are including a special file called preload.js which contains the utility based methods. And also after that we are loading a index.html

 

 

Now you need to copy paste some code inside the index.html file inside the renderer folder

 

 

renderer/index.html

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html lang="en">
 
<head>
  <script src="js/renderer.js" defer></script>
  <title>ImageResizer</title>
</head>
 
<body>
 
  <label>
    <span>Select an image to resize</span>
    <input id="img" type="file" />
  </label>
  </div>
 
  <!-- Form -->
  <form id="img-form" class="hidden">
    <div>
      <label>Width</label>
      <input type="number" name="width" id="width" placeholder="Width" />
    </div>
 
    <div>
      <label>Height</label>
      <input type="number" name="height" id="height" placeholder="Height" />
    </div>
 
    <!-- Button -->
    <div>
      <button type="submit">
        Resize
      </button>
 
  </form>
 
  <p><strong>File: </strong><span id="filename"></span></p>
  <p><strong>Output: </strong><span id="output-path"></span></p>
  </div>
</body>
 
</html>

 

 

As you can see we have a simple form where we have input fields for choosing the input file and also input number text fields where the width and height will be auto populated after selecting it. And then we have the simple button to submit the form.

 

 

 

 

As you can see the interface which is shown of the application uptil now. As you can see we are also including the renderer.js file which is the actual javascript code required for this purpose at the frontend.

 

 

Adding the Menu inside Electron

 

 

Now we will look on how to add Menu items inside electron.js. For this you need to add the below code to your main.js file

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// Menu template
const menu = [
  ...(isMac
    ? [
        {
          label: app.name,
          submenu: [
            {
              label: 'About',
              click: createAboutWindow,
            },
          ],
        },
      ]
    : []),
  {
    role: 'fileMenu',
  },
  ...(!isMac
    ? [
        {
          label: 'Help',
          submenu: [
            {
              label: 'About',
              click: createAboutWindow,
            },
          ],
        },
      ]
    : []),
 
  ...(isDev
    ? [
        {
          label: 'Developer',
          submenu: [
            { role: 'reload' },
            { role: 'forcereload' },
            { type: 'separator' },
            { role: 'toggledevtools' },
          ],
        },
      ]
    : []),
];

 

 

As you can see we have the menu template in the form of array inside this menu we have multiple menu items. Depending upon which OS is there we are showing different menu items. As Electron.js is cross platform it can build for different OS at same time.

 

Now we will be adding the menu defined in the earlier step to the electron app. For this you need to go to the app event of ready where you copy paste this line

 

 

JavaScript
1
2
3
4
5
6
7
8
9
app.on('ready', () => {
  createMainWindow();
 
  const mainMenu = Menu.buildFromTemplate(menu);
  Menu.setApplicationMenu(mainMenu);
 
  // Remove variable from memory
  mainWindow.on('closed', () => (mainWindow = null));
});

 

 

As you can see we using building the menu using the template defined in the earlier step. And lastly we are using setApplicationMenu() to set the application menu

 

 

 

 

JavaScript
1
2
3
4
5
6
7
8
9
// Quit when all windows are closed.
app.on('window-all-closed', () => {
  if (!isMac) app.quit();
});
 
// Open a window if none are open (macOS)
app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) createMainWindow();
});

 

 

So guys in the above line of code we are quitting the app when all the windows are closed. That is the first event and in the second event we are activating the window when we open the windows

 

 

Creating the About Window of App

 

 

Now we will see how to create Multiple windows in electron. In that case when the user click the about menu item it should open a new about window as shown below

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
let aboutWindow
 
function createAboutWindow() {
  aboutWindow = new BrowserWindow({
    width: 300,
    height: 300,
    title: 'About Electron',
  });
 
   aboutWindow.loadFile(path.join(__dirname, './renderer/about.html'));
}

 

 

As you can see we are using the BrowserWindow again to create another window and here again we are passing the width and height of the window and the title of the window. And here also we are fetching the contents to be shown inside the window. For this we have created another about.html inside the same directory where index.html is stored

 

So now you also need to copy paste the code inside about.html

 

renderer/about.html

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
 
<head>
  <title>About ImageShrink</title>
</head>
 
<body>
  <div>
    <h2>FileResizer App</h2>
    <p>Version 1.0.0</p>
    <p>MIT License</p>
  </div>
</body>
 
</html>

 

 

So Now if you click about menu item you will see the below about window

 

 

Now you need to make a preload.js file which will contain all the methods that we will expose to the renderer side because we need these methods at the client to use the OS and other modules.

 

 

preload.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const os = require('os');
const path = require('path');
const { contextBridge, ipcRenderer } = require('electron');
const Toastify = require('toastify-js');
 
contextBridge.exposeInMainWorld('os', {
  homedir: () => os.homedir(),
});
 
contextBridge.exposeInMainWorld('path', {
  join: (...args) => path.join(...args),
});
 
contextBridge.exposeInMainWorld('ipcRenderer', {
  send: (channel, data) => ipcRenderer.send(channel, data),
  on: (channel, func) =>
    ipcRenderer.on(channel, (event, ...args) => func(...args)),
});
 
contextBridge.exposeInMainWorld('Toastify', {
  toast: (options) => Toastify(options).showToast(),
});

 

 

Here as you can see at the top we are importing contextBridge and ipcRenderer which allows us to expose methods and also communicate data between the renderer and main process. That’s the point of having this file. In this file we have different methods first of all for showing toast alert messages we are receiving alert options in the function. We are also exposing ipcRenderer process. Also we are exposing the os and path modules inside the client side.

 

 

Now we need to write the javascript code required for this application at the renderer side. So inside the renderer folder make a js folder and inside it make a renderer.js file and copy paste the below code

 

 

 

renderer/js/renderer.js

 

 

1
2
3
4
5
6
const form = document.querySelector('#img-form');
const img = document.querySelector('#img');
const outputPath = document.querySelector('#output-path');
const filename = document.querySelector('#filename');
const heightInput = document.querySelector('#height');
const widthInput = document.querySelector('#width');

 

 

As you can see we are first of all getting all the reference of all the DOM elements inside the html. And then we will accessing these elements in javascript

 

 

Adding Event Listeners to Form & Input Field

 

 

So now we will be attaching the form submit and onChange event handler to the form and the input fields as shown below

 

 

1
2
3
4
// File select listener
img.addEventListener('change', loadImage);
// Form submit listener
form.addEventListener('submit', resizeImage);

 

 

As you can see we have attached the event handlers. So now when the input field  value is changed then this loadImage() function will be executed. So now we need to write the loadImage function as shown below

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function loadImage(e) {
  const file = e.target.files[0];
 
  // Check if file is an image
  if (!isFileImage(file)) {
    alertError('Please select an image');
    return;
  }
 
  // Add current height and width to form using the URL API
  const image = new Image();
  image.src = URL.createObjectURL(file);
  image.onload = function () {
    widthInput.value = this.width;
    heightInput.value = this.height;
  };
 
  // Show form, image name and output path
  form.style.display = 'block';
  filename.innerHTML = img.files[0].name;
  outputPath.innerText = path.join(os.homedir(), 'imageresizer');
}

 

 

As you can see in the above code we are fetching the image which the user has selected. And then we have some validation inside the if condition to check if the selected file is image or not. As you can see if any error takes place we are calling alertError() method which will show toast alert message containing the error. And after that we are initializing a new Image by using the Image() constructor. And then we are using the URL.createObjectURL() method to convert image file to url. And we are getting the width and height of the original image and populating those values inside the input field of width and height. And we will also show the filename and the outputPath as well.

 

Now we will be making the method to show error inside toast alert message which is red in color as shown below

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
function alertError(message) {
  Toastify.toast({
    text: message,
    duration: 5000,
    close: false,
    style: {
      background: 'red',
      color: 'white',
      textAlign: 'center',
    },
  });
}

 

 

 

 

JavaScript
1
2
3
4
5
// Make sure file is an image
function isFileImage(file) {
  const acceptedImageTypes = ['image/gif', 'image/jpeg', 'image/png'];
  return file && acceptedImageTypes.includes(file['type']);
}

 

 

And now inside this above javascript function we are checking whether the given file is image or not. Here we have defined the array of accepted file types which are gif,jpeg and png. So we are checking if the file mimetype matches to them or not. And we are retuning the mimetype from this function.

 

And now guys we will writing the function when we click the submit button of the form. This function will get executed as shown below

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Resize image
function resizeImage(e) {
  e.preventDefault();
 
  if (!img.files[0]) {
    alertError('Please upload an image');
    return;
  }
 
  if (widthInput.value === '' || heightInput.value === '') {
    alertError('Please enter a width and height');
    return;
  }
 
  // Electron adds a bunch of extra properties to the file object including the path
  const imgPath = img.files[0].path;
  const width = widthInput.value;
  const height = heightInput.value;
 
  ipcRenderer.send('image:resize', {
    imgPath,
    height,
    width,
  });
}

 

 

As you can see inside this function we are getting the width and height of the image that the user has entered. If either of the fields are empty then we will be showing error to the user again we are calling alertError() method passing custom error. And then if all fields are good then we will be storing the image path, width and height and then we are calling the method defined inside the main process. Here we are using the ipcRenderer.send() method to send the event which is called image:resize and in the second argument we are passing the information in an object which is path of image, width and height.

 

 

Now we will be responding to this event which is passed from the renderer to main process. Now inside the main.js file we will define the resize:image event which is received in main process as shown below

 

 

main.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
ipcMain.on('image:resize', (e, options) => {
  // console.log(options);
  options.dest = path.join(os.homedir(), 'imageresizer');
  resizeImage(options);
});
 
// Resize and save image
async function resizeImage({ imgPath, height, width, dest }) {
  try {
    // console.log(imgPath, height, width, dest);
 
    // Resize image
    const newPath = await resizeImg(fs.readFileSync(imgPath), {
      width: +width,
      height: +height,
    });
 
    // Get filename
    const filename = path.basename(imgPath);
 
    // Create destination folder if it doesn't exist
    if (!fs.existsSync(dest)) {
      fs.mkdirSync(dest);
    }
 
    // Write the file to the destination folder
    fs.writeFileSync(path.join(dest, filename), newPath);
 
    // Send success to renderer
    mainWindow.webContents.send('image:done');
 
    // Open the folder in the file explorer
    shell.openPath(dest);
  } catch (err) {
    console.log(err);
  }
}

 

 

Here as you can see in the above code we are using ipcMain.on() method to receive the sent event by renderer. In this we are calling resizeImage() function which is async function

 

Now in this async resizeImage() function guys we are resizing the image file using the resize-img module. First of all we are getting the img file path and then we are getting the width and height and then resizing the image to that width and height. And then we are writing the output file to output path. And also we are sending the event called image:done which is sent from main to renderer process. So now we need to handle this event inside renderer.js file And also after that as you can see we are using the shell method to open the outputPath or the outputImage automatically.

 

renderer/js/renderer.js

 

 

JavaScript
1
2
3
4
// When done, show message
ipcRenderer.on('image:done', () =>
  alertSuccess(`Image resized to ${heightInput.value} x ${widthInput.value}`)
);

 

 

Now inside this above code we are receiving image:done event we are showing the alert success toast message which will be in green color. Here we are calling the alertSuccess() method. Now we need to define this method as shown below

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
function alertSuccess(message) {
  Toastify.toast({
    text: message,
    duration: 5000,
    close: false,
    style: {
      background: 'green',
      color: 'white',
      textAlign: 'center',
    },
  });
}

 

 

Here as you can see we are using the Toastify module to show toast message using the toast() method. Inside this we have the style object we have the background color which is green and text color is white and text align is center. Basically this alert message will appear for only 5 seconds then it will disappear after that automatically.

 

 

 

 

 

Full Source Code

 

 

Wrapping it up we will now see the full source code of the application as shown below

 

 

 

 

main.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
const path = require('path');
const os = require('os');
const fs = require('fs');
const resizeImg = require('resize-img');
const { app, BrowserWindow, Menu, ipcMain, shell } = require('electron');
 
process.env.NODE_ENV = "production"
 
const isDev = process.env.NODE_ENV !== 'production';
const isMac = process.platform === 'darwin';
 
let mainWindow;
let aboutWindow;
 
// Main Window
function createMainWindow() {
  mainWindow = new BrowserWindow({
    width: isDev ? 1000 : 500,
    height: 600,
    resizable: isDev,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js'),
    },
  });
 
  // Show devtools automatically if in development
  if (isDev) {
    mainWindow.webContents.openDevTools();
  }
 
    // mainWindow.loadURL(`file://${__dirname}/renderer/index.html`);
   mainWindow.loadFile(path.join(__dirname, './renderer/index.html'));
}
 
// About Window
function createAboutWindow() {
  aboutWindow = new BrowserWindow({
    width: 300,
    height: 300,
    title: 'About Electron',
  });
 
   aboutWindow.loadFile(path.join(__dirname, './renderer/about.html'));
}
 
// When the app is ready, create the window
app.on('ready', () => {
  createMainWindow();
 
  const mainMenu = Menu.buildFromTemplate(menu);
  Menu.setApplicationMenu(mainMenu);
 
  // Remove variable from memory
  mainWindow.on('closed', () => (mainWindow = null));
});
 
// Menu template
const menu = [
  ...(isMac
    ? [
        {
          label: app.name,
          submenu: [
            {
              label: 'About',
              click: createAboutWindow,
            },
          ],
        },
      ]
    : []),
  {
    role: 'fileMenu',
  },
  ...(!isMac
    ? [
        {
          label: 'Help',
          submenu: [
            {
              label: 'About',
              click: createAboutWindow,
            },
          ],
        },
      ]
    : []),
 
  ...(isDev
    ? [
        {
          label: 'Developer',
          submenu: [
            { role: 'reload' },
            { role: 'forcereload' },
            { type: 'separator' },
            { role: 'toggledevtools' },
          ],
        },
      ]
    : []),
];
 
// Respond to the resize image event
ipcMain.on('image:resize', (e, options) => {
  // console.log(options);
  options.dest = path.join(os.homedir(), 'imageresizer');
  resizeImage(options);
});
 
// Resize and save image
async function resizeImage({ imgPath, height, width, dest }) {
  try {
    // console.log(imgPath, height, width, dest);
 
    // Resize image
    const newPath = await resizeImg(fs.readFileSync(imgPath), {
      width: +width,
      height: +height,
    });
 
    // Get filename
    const filename = path.basename(imgPath);
 
    // Create destination folder if it doesn't exist
    if (!fs.existsSync(dest)) {
      fs.mkdirSync(dest);
    }
 
    // Write the file to the destination folder
    fs.writeFileSync(path.join(dest, filename), newPath);
 
    // Send success to renderer
    mainWindow.webContents.send('image:done');
 
    // Open the folder in the file explorer
    shell.openPath(dest);
  } catch (err) {
    console.log(err);
  }
}
 
// Quit when all windows are closed.
app.on('window-all-closed', () => {
  if (!isMac) app.quit();
});
 
// Open a window if none are open (macOS)
app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) createMainWindow();
});

 

 

renderer/js/renderer.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
const form = document.querySelector('#img-form');
const img = document.querySelector('#img');
const outputPath = document.querySelector('#output-path');
const filename = document.querySelector('#filename');
const heightInput = document.querySelector('#height');
const widthInput = document.querySelector('#width');
 
// Load image and show form
function loadImage(e) {
  const file = e.target.files[0];
 
  // Check if file is an image
  if (!isFileImage(file)) {
    alertError('Please select an image');
    return;
  }
 
  // Add current height and width to form using the URL API
  const image = new Image();
  image.src = URL.createObjectURL(file);
  image.onload = function () {
    widthInput.value = this.width;
    heightInput.value = this.height;
  };
 
  // Show form, image name and output path
  form.style.display = 'block';
  filename.innerHTML = img.files[0].name;
  outputPath.innerText = path.join(os.homedir(), 'imageresizer');
}
 
// Make sure file is an image
function isFileImage(file) {
  const acceptedImageTypes = ['image/gif', 'image/jpeg', 'image/png'];
  return file && acceptedImageTypes.includes(file['type']);
}
 
// Resize image
function resizeImage(e) {
  e.preventDefault();
 
  if (!img.files[0]) {
    alertError('Please upload an image');
    return;
  }
 
  if (widthInput.value === '' || heightInput.value === '') {
    alertError('Please enter a width and height');
    return;
  }
 
  // Electron adds a bunch of extra properties to the file object including the path
  const imgPath = img.files[0].path;
  const width = widthInput.value;
  const height = heightInput.value;
 
  ipcRenderer.send('image:resize', {
    imgPath,
    height,
    width,
  });
}
 
// When done, show message
ipcRenderer.on('image:done', () =>
  alertSuccess(`Image resized to ${heightInput.value} x ${widthInput.value}`)
);
 
function alertSuccess(message) {
  Toastify.toast({
    text: message,
    duration: 5000,
    close: false,
    style: {
      background: 'green',
      color: 'white',
      textAlign: 'center',
    },
  });
}
 
function alertError(message) {
  Toastify.toast({
    text: message,
    duration: 5000,
    close: false,
    style: {
      background: 'red',
      color: 'white',
      textAlign: 'center',
    },
  });
}
 
// File select listener
img.addEventListener('change', loadImage);
// Form submit listener
form.addEventListener('submit', resizeImage);

 

 

renderer/about.html

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
 
<head>
  <title>About ImageShrink</title>
</head>
 
<body>
  <div>
    <h2>FileResizer App</h2>
    <p>Version 1.0.0</p>
    <p>MIT License</p>
  </div>
</body>
 
</html>

 

 

renderer/index.html

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html lang="en">
 
<head>
  <script src="js/renderer.js" defer></script>
  <title>ImageResizer</title>
</head>
 
<body>
 
  <label>
    <span>Select an image to resize</span>
    <input id="img" type="file" />
  </label>
  </div>
 
  <!-- Form -->
  <form id="img-form" class="hidden">
    <div>
      <label>Width</label>
      <input type="number" name="width" id="width" placeholder="Width" />
    </div>
 
    <div>
      <label>Height</label>
      <input type="number" name="height" id="height" placeholder="Height" />
    </div>
 
    <!-- Button -->
    <div>
      <button type="submit">
        Resize
      </button>
 
  </form>
 
  <p><strong>File: </strong><span id="filename"></span></p>
  <p><strong>Output: </strong><span id="output-path"></span></p>
  </div>
</body>
 
</html>

Recent Posts

  • Android Java Tutorial to Change Styles & Visibility of System Bars (Top, Action & Status) Full Example
  • Android Java Project to Display & Play Audio Files From Storage inside ListView Using MediaPlayer Class
  • Android Java Project to Build MP4 Video to MP3 Audio Converter Using MediaMuxer Class
  • Android Java Project to Merge Multiple PDF Documents From Gallery Using iTextPDF Library
  • Android Java Project to Detect System Hardware & System CPU Info & Display inside TextView Widget
  • Angular
  • Bunjs
  • C#
  • Deno
  • django
  • Electronjs
  • java
  • javascript
  • Koajs
  • kotlin
  • Laravel
  • meteorjs
  • Nestjs
  • Nextjs
  • Nodejs
  • PHP
  • Python
  • React
  • ReactNative
  • Svelte
  • Tutorials
  • Vuejs




©2023 WebNinjaDeveloper.com | Design: Newspaperly WordPress Theme