ImageShrink

A simple picture sizing tool. First look at the effect:

Before:

Project Technical Overview

Electron development, the use of Node ecological Imagemin package to achieve the size of the image scaling; The electron log packet is used to record the conversion between source file and target file. The renderer sends the address of the image uploaded by the user and the multiple to be reduced to the main process through ipcRenderer. The main process receives the corresponding Opthions through ipcMain to reduce the file using Imagemin, saves the reduced file in the user’s directory, and automatically opens the folder.

Details of the core

To distinguish the environment

process.env.NODE_ENV = 'production'
constisDev = process.env.NODE_ENV ! = ='production' ? true : false // Differentiate the production development environment
const isMac = process.platform === 'darwin' ? true : false // Differentiate platforms
Copy the code

Here I use manual way to distinguish between development and production environment, although there is a corresponding package can directly determine, but I think it is easier.

Create a window

function createMainWindow() {
    mainWindow = new BrowserWindow({
        title: 'ImageShrink'.width: isDev ? 800 : 500.height: 600.icon: './assets/icons/Icon_256x256.png'.resizable: isDev ? true : false.webPreferences: {
            nodeIntegration: true // Set whether node is available for the renderer}})// mainwindow.loadurl (' file://${__dirname}/app/index.html ')  
      

    if (isDev) {
      // In a development environment, open the Developer menu
        mainWindow.webContents.openDevTools() 
    }
    mainWindow.loadFile(`./app/index.html`)}// About the page window
function createAboutWindow() {
    aboutWindow = new BrowserWindow({
        title: 'About ImageShrink'.width: 300.height: 300.icon: './assets/icons/Icon_256x256.png'.resizable: false
    })
    aboutWindow.loadFile(`./app/about.html`)}Copy the code

Set menu items

const menu = [
    ...(isMac ? [{
        label: app.name,
        submenu: [{
            label: 'About'.click: createAboutWindow
        }]
    }] : []),
    {
        role: 'fileMenu'},... (! isMac ? [{label: 'Help'.submenu: [{
            label: 'About'.click: createAboutWindow }] }] : []), ... (isDev ? [{label: 'Developer'.// Developer menu, with built-in menu
        submenu: [{
                role: 'reload'
            },
            {
                role: 'forcereload'
            },
            {
                type: 'separator'
            },
            {
                role: 'toggledevtools'
            },
        ]
    }] : [])
]

app.on('ready', () => {
    createMainWindow()

    const mainMenu = Menu.buildFromTemplate(menu)
    Menu.setApplicationMenu(mainMenu)

    // Global shortcut keys If you do not use the developer menu, you can set your own global shortcut keys to help development
    // globalshortcut.register ('CmdOrCtrl+R', () => mainwindow.reload ()) refresh the page
    // globalShortcut.register(isMac ? 'Command + Alt + I' : 'Ctrl + Shift + I, () = > mainWindow. ToggleDevTools open DevTools ())

    mainWindow.on('ready', () => mainWindow = null)})Copy the code

Picture reduction logic

// Use ipcMain ipcRenderer to implement communication between main process and renderer process
// Options takes two parameters: URL and quality, which are the path and zoom factor of the image, respectively
// Dest refers to the address where the image is stored after conversion
ipcMain.on('image:minimize', (e, options) => {
    options.dest = path.join(os.homedir(), 'imageshrink')
    shrinkImage(options)
})

// The method of image reduction
async function shrinkImage({ imgPath, quality, dest }) {
    try {
        const pngQuality = quality / 100
        // Call the method to zoom out the image. For details, search for the package details on NPM
        const files = await imagemin([slash(imgPath)], {
            destination: dest,
            plugins: [
                imageminMozjpeg({
                    quality
                }),
                imageminPngquant({
                    quality: [pngQuality, pngQuality]
                })
            ]
        })
        log.info(files) // Write this file to a log file
        shell.openPath(dest) // Open the folder where the converted image is stored
        mainWindow.webContents.send('image:done') // The main process uses webContents to actively send rendered events to the renderer process
    } catch (error) {
        // If the conversion fails, save the error information to a log file
        log.error(error)
    }
}

// Render process
document.getElementById('output-path').innerText = path.join(os.homedir(),'imageshrink')

form.addEventListener('submit', e => {
    e.preventDefault()

    const imgPath = img.files[0].path
    const quality = slider.value
				
    // Submit the miniaturization event to the main process, and pass the image path and miniaturization to it
    ipcRenderer.send('image:minimize', {
        imgPath,
        quality
    })
})

// on done
		// The conversion is complete
ipcRenderer.on('image:done', () => {
    M.toast({
        html: `Image resized to ${slider.value}% quality`})})Copy the code

Welcome to exchange. I am a junior and looking for a job.