ImageShrink
简介:一个简单的图片大小缩放工具。 先看效果:
原图: 大小缩小后: 图片前后质量对比:前:
后: 可以看到图片的大小变小了,但是图片的质量并没有下降多少。项目技术概述
采用Electron开发,利用node
生态中的 imagemin
包来实现对图片大小的缩放;利用electron-log
包实现对源文件与目标文件转换的日志记录;渲染进程通过ipcRenderer
将用户上传的图片的地址、将要缩小的倍数发送到主进程,主进程通过ipcMain
接收到对应的opthions
利用imagemin
将文件缩小,将缩小后的文件存在用户的目录下,并自动打开该文件夹。
核心细节
区分环境
process.env.NODE_ENV = 'production'
const isDev = process.env.NODE_ENV !== 'production' ? true : false //区分生产开发环境
const isMac = process.platform === 'darwin' ? true : false // 区分平台
我这里是采用手动的方式区分开发或者是生产环境,虽然有相应的包可以直接判断,但是我觉得这样比较简单点。
创建窗口
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 // 设置渲染进程是否可用node
}
})
// mainWindow.loadURL(`file://${__dirname}/app/index.html`) // 可以采用loadURL的方式,但是会有一个安全的限制 需要在html中加上这一段 meta: <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
if (isDev) {
// 如果是开发环境,就打开开发者菜单
mainWindow.webContents.openDevTools()
}
mainWindow.loadFile(`./app/index.html`)
}
// 关于页面的窗口
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`)
}
设置菜单项
const menu = [
...(isMac ? [{
label: app.name,
submenu: [{
label: 'About',
click: createAboutWindow
}]
}] : []),
{
role: 'fileMenu'
},
...(!isMac ? [{
label: 'Help',
submenu: [{
label: 'About',
click: createAboutWindow
}]
}] : []),
...(isDev ? [{
label: 'Developer', // 开发者菜单,用内置的menu
submenu: [{
role: 'reload'
},
{
role: 'forcereload'
},
{
type: 'separator'
},
{
role: 'toggledevtools'
},
]
}] : [])
]
app.on('ready', () => {
createMainWindow()
const mainMenu = Menu.buildFromTemplate(menu)
Menu.setApplicationMenu(mainMenu)
// 全局快捷键 如果不用开发者菜单 可用自己设置全局快捷键帮助开发
// globalShortcut.register('CmdOrCtrl+R', () => mainWindow.reload()) 刷新页面
// globalShortcut.register(isMac ? 'Command+Alt+I' : 'Ctrl+Shift+I', () => mainWindow.toggleDevTools()) 打开 DevTools
mainWindow.on('ready', () => mainWindow = null)
})
图片缩小逻辑
// 利用 ipcMain ipcRenderer 实现主进程与渲染进程的通信
// options 有两个参数: url 和 quality,分别为图片的路径和缩小倍数
// 这里的dest是指转换后图片存放的地址
ipcMain.on('image:minimize', (e, options) => {
options.dest = path.join(os.homedir(), 'imageshrink')
shrinkImage(options)
})
// 图片缩小的方法
async function shrinkImage({
imgPath,
quality,
dest
}) {
try {
const pngQuality = quality / 100
// 调用方法 实现缩小图片,具体细节可在npm上搜索该包的详细信息
const files = await imagemin([slash(imgPath)], {
destination: dest,
plugins: [
imageminMozjpeg({
quality
}),
imageminPngquant({
quality: [pngQuality, pngQuality]
})
]
})
log.info(files) // 将这个文件写入日志文件中
shell.openPath(dest) // 打开转换后图片的存放的文件夹
mainWindow.webContents.send('image:done') // 主进程 利用webContents 主动向渲染进程发送 渲染已完成的事件
} catch (error) {
// 如果转换出错,将错误信息存入日志文件中
log.error(error)
}
}
// 渲染进程
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
// 向主进程提交缩小图片的事件,并将图片路径和缩小倍数传过去
ipcRenderer.send('image:minimize', {
imgPath,
quality
})
})
// on done
// 图片上传完成 页面提示转换完成
ipcRenderer.on('image:done', () => {
M.toast({
html: `Image resized to ${slider.value}% quality`
})
})
欢迎交流,目前大三,求职中。