Skip to content

Commit 79d5c50

Browse files
committed
add avif, jxl
1 parent e7a42aa commit 79d5c50

File tree

23 files changed

+1968
-988
lines changed

23 files changed

+1968
-988
lines changed

.DS_Store

8 KB
Binary file not shown.

components/FileContainer.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import stopButtonHover from "../assets/icons/stop-hover.png"
1616
import stopButton from "../assets/icons/stop.png"
1717
import trashButtonHover from "../assets/icons/trash-hover.png"
1818
import trashButton from "../assets/icons/trash.png"
19-
import {DirectoryContext, QualityContext, OverwriteContext, IgnoreBelowContext, ResizeWidthContext, ResizeHeightContext, PercentageContext, KeepRatioContext, RenameContext, FormatContext} from "../renderer"
19+
import {DirectoryContext, QualityContext, OverwriteContext, IgnoreBelowContext, ResizeWidthContext, ResizeHeightContext,
20+
PercentageContext, KeepRatioContext, RenameContext, FormatContext, ProgressiveContext} from "../renderer"
2021
import functions from "../structures/functions"
2122
import "../styles/filecontainer.less"
2223

@@ -40,6 +41,7 @@ const FileContainer: React.FunctionComponent<FileContainerProps> = (props: FileC
4041
const {keepRatio} = useContext(KeepRatioContext)
4142
const {rename} = useContext(RenameContext)
4243
const {format} = useContext(FormatContext)
44+
const {progressive, setProgressive} = useContext(ProgressiveContext)
4345
const {directory, setDirectory} = useContext(DirectoryContext)
4446
const [hover, setHover] = useState(false)
4547
const [hoverClose, setHoverClose] = useState(false)
@@ -120,11 +122,13 @@ const FileContainer: React.FunctionComponent<FileContainerProps> = (props: FileC
120122
useEffect(() => {
121123
updateRealtime()
122124
updateDimensions()
123-
}, [quality, ignoreBelow, resizeWidth, resizeHeight, percentage, keepRatio, format])
125+
}, [quality, ignoreBelow, resizeWidth, resizeHeight, percentage, keepRatio, format, progressive])
124126

125127
const updateRealtime = async () => {
126128
if (output) return
127-
const {buffer, fileSize} = await ipcRenderer.invoke("compress-realtime", {id: props.id, source: props.source, dest: directory, fileSize: props.fileSize, width: props.width, height: props.height, quality, overwrite, ignoreBelow, resizeWidth, resizeHeight, percentage, keepRatio, rename, format})
129+
const {buffer, fileSize} = await ipcRenderer.invoke("compress-realtime", {id: props.id, source: props.source, dest: directory,
130+
fileSize: props.fileSize, width: props.width, height: props.height, quality, overwrite, ignoreBelow, resizeWidth, resizeHeight,
131+
percentage, keepRatio, rename, format, progressive})
128132
setNewBuffer(buffer)
129133
setNewFileSize(functions.readableFileSize(fileSize))
130134
const type = format === "original" ? path.extname(props.source).replaceAll(".", "") : format
@@ -143,7 +147,8 @@ const FileContainer: React.FunctionComponent<FileContainerProps> = (props: FileC
143147
setStartSignal(false)
144148
webFrame.clearCache()
145149
await functions.timeout(props.id)
146-
ipcRenderer.invoke("compress", {id: props.id, source: props.source, dest: directory, fileSize: props.fileSize, width: props.width, height: props.height, quality, overwrite, ignoreBelow, resizeWidth, resizeHeight, percentage, keepRatio, rename, format}, startAll)
150+
ipcRenderer.invoke("compress", {id: props.id, source: props.source, dest: directory, fileSize: props.fileSize, width: props.width,
151+
height: props.height, quality, overwrite, ignoreBelow, resizeWidth, resizeHeight, percentage, keepRatio, rename, format, progressive}, startAll)
147152
if (!startAll) {
148153
setStarted(true)
149154
props.setStart(props.id)

components/OptionsBar.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import React, {useContext, useEffect, useState} from "react"
44
import {Dropdown, DropdownButton} from "react-bootstrap"
55
import folderButton from "../assets/icons/folder.png"
66
import folderButtonHover from "../assets/icons/folder-hover.png"
7-
import {DirectoryContext, QualityContext, OverwriteContext, IgnoreBelowContext, ResizeWidthContext, ResizeHeightContext, PercentageContext, KeepRatioContext, RenameContext, FormatContext} from "../renderer"
7+
import {DirectoryContext, QualityContext, OverwriteContext, IgnoreBelowContext, ResizeWidthContext,
8+
ResizeHeightContext, PercentageContext, KeepRatioContext, RenameContext, FormatContext, ProgressiveContext} from "../renderer"
89
import Slider from "rc-slider"
910
import functions from "../structures/functions"
1011
import "../styles/optionsbar.less"
@@ -20,6 +21,7 @@ const OptionsBar: React.FunctionComponent = (props) => {
2021
const {rename, setRename} = useContext(RenameContext)
2122
const {format, setFormat} = useContext(FormatContext)
2223
const {directory, setDirectory} = useContext(DirectoryContext)
24+
const {progressive, setProgressive} = useContext(ProgressiveContext)
2325
const [folderHover, setFolderHover] = useState(false)
2426
const [id, setID] = useState(1)
2527

@@ -41,7 +43,8 @@ const OptionsBar: React.FunctionComponent = (props) => {
4143
}, [])
4244

4345
useEffect(() => {
44-
ipcRenderer.invoke("store-settings", {quality, directory, overwrite, ignoreBelow, resizeWidth, resizeHeight, percentage, keepRatio, rename, format})
46+
ipcRenderer.invoke("store-settings", {quality, directory, overwrite, ignoreBelow, resizeWidth, resizeHeight,
47+
percentage, keepRatio, rename, format, progressive})
4548
ipcRenderer.on("on-drop", onDrop)
4649
return () => {
4750
ipcRenderer.removeListener("on-drop", onDrop)
@@ -60,6 +63,7 @@ const OptionsBar: React.FunctionComponent = (props) => {
6063
setKeepRatio(settings.keepRatio)
6164
setRename(settings.rename)
6265
setFormat(settings.format)
66+
setProgressive(settings.progressive)
6367
}
6468
}
6569

@@ -181,8 +185,15 @@ const OptionsBar: React.FunctionComponent = (props) => {
181185
<Dropdown.Item active={format === "png"} onClick={() => setFormat("png")}>png</Dropdown.Item>
182186
<Dropdown.Item active={format === "jpg"} onClick={() => setFormat("jpg")}>jpg</Dropdown.Item>
183187
<Dropdown.Item active={format === "gif"} onClick={() => setFormat("gif")}>gif</Dropdown.Item>
188+
<Dropdown.Item active={format === "webp"} onClick={() => setFormat("webp")}>webp</Dropdown.Item>
189+
<Dropdown.Item active={format === "avif"} onClick={() => setFormat("avif")}>avif</Dropdown.Item>
190+
<Dropdown.Item active={format === "jxl"} onClick={() => setFormat("jxl")}>jxl</Dropdown.Item>
184191
</DropdownButton>
185192
</div>
193+
<div className="options-bar-box">
194+
<input className="options-bar-checkbox" type="checkbox" checked={progressive} onChange={() => setProgressive((prev: boolean) => !prev)}/>
195+
<p className="options-bar-text pointer" onClick={() => setProgressive((prev: boolean) => !prev)}>Progressive</p>
196+
</div>
186197
</div>
187198
</section>
188199
)

main.ts

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,8 @@ const compress = async (info: any) => {
658658
percentage: info.percentage,
659659
keepRatio: info.keepRatio,
660660
rename: info.rename,
661-
format: info.format
661+
format: info.format,
662+
progressive: info.progressive
662663
}
663664
window?.webContents.send("conversion-started", {id: info.id})
664665
const fileSize = functions.parseFileSize(info.fileSize)
@@ -692,15 +693,19 @@ const compress = async (info: any) => {
692693
const resizeCondition = options.keepRatio ? (options.percentage ? options.resizeWidth !== 100 : true) : (options.percentage ? (options.resizeWidth !== 100 && options.resizeHeight !== 100) : true)
693694
if (ext === "gif") {
694695
if (resizeCondition) {
695-
const {frameArray, delayArray} = await functions.getGIFFrames(info.source)
696-
const newFrameArray = [] as Buffer[]
697-
for (let i = 0; i < frameArray.length; i++) {
698-
const newFrame = await sharp(frameArray[i])
699-
.resize(width, height, {fit: "fill"})
700-
.toBuffer()
701-
newFrameArray.push(newFrame)
696+
if (process.platform === "win32") {
697+
const {frameArray, delayArray} = await functions.getGIFFrames(info.source)
698+
const newFrameArray = [] as Buffer[]
699+
for (let i = 0; i < frameArray.length; i++) {
700+
const newFrame = await sharp(frameArray[i])
701+
.resize(width, height, {fit: "fill"})
702+
.toBuffer()
703+
newFrameArray.push(newFrame)
704+
}
705+
buffer = await functions.encodeGIF(newFrameArray, delayArray, width, height)
706+
} else {
707+
buffer = await sharp(buffer, {animated: true}).resize(width, height, {fit: "fill"}).gif().toBuffer()
702708
}
703-
buffer = await functions.encodeGIF(newFrameArray, delayArray, width, height)
704709
if (options.quality !== 100) {
705710
buffer = await imagemin.buffer(buffer, {plugins: [
706711
imageminGifsicle({optimizationLevel: 3})
@@ -719,9 +724,11 @@ const compress = async (info: any) => {
719724
}
720725
if (sourceExt !== ext) {
721726
let s = sharp(buffer, {animated: true})
722-
if (ext === "jpg" || ext === "jpeg") s.jpeg()
723-
if (ext === "png") s.png()
724-
if (ext === "webp") s.webp()
727+
if (ext === "jpg" || ext === "jpeg") s.jpeg({optimiseScans: options.progressive, quality: options.quality})
728+
if (ext === "png") s.png({quality: options.quality})
729+
if (ext === "webp") s.webp({quality: options.quality})
730+
if (ext === "avif") s.avif({quality: options.quality})
731+
if (ext === "jxl") s.jxl({quality: options.quality})
725732
if (ext === "gif") s.gif()
726733
buffer = await s.toBuffer()
727734
}
@@ -781,7 +788,8 @@ ipcMain.handle("compress-realtime", async (event, info: any) => {
781788
percentage: info.percentage,
782789
keepRatio: info.keepRatio,
783790
rename: info.rename,
784-
format: info.format
791+
format: info.format,
792+
progressive: info.progressive
785793
}
786794
const fileSize = functions.parseFileSize(info.fileSize)
787795
const ignoredSize = functions.parseFileSize(options.ignoreBelow)
@@ -797,15 +805,19 @@ ipcMain.handle("compress-realtime", async (event, info: any) => {
797805
const resizeCondition = options.keepRatio ? (options.percentage ? options.resizeWidth !== 100 : true) : (options.percentage ? (options.resizeWidth !== 100 && options.resizeHeight !== 100) : true)
798806
if (ext === "gif") {
799807
if (resizeCondition) {
800-
const {frameArray, delayArray} = await functions.getGIFFrames(info.source)
801-
const newFrameArray = [] as Buffer[]
802-
for (let i = 0; i < frameArray.length; i++) {
803-
const newFrame = await sharp(frameArray[i])
804-
.resize(width, height, {fit: "fill"})
805-
.toBuffer()
806-
newFrameArray.push(newFrame)
808+
if (process.platform === "win32") {
809+
const {frameArray, delayArray} = await functions.getGIFFrames(info.source)
810+
const newFrameArray = [] as Buffer[]
811+
for (let i = 0; i < frameArray.length; i++) {
812+
const newFrame = await sharp(frameArray[i])
813+
.resize(width, height, {fit: "fill"})
814+
.toBuffer()
815+
newFrameArray.push(newFrame)
816+
}
817+
buffer = await functions.encodeGIF(newFrameArray, delayArray, width, height)
818+
} else {
819+
buffer = await sharp(buffer, {animated: true}).resize(width, height, {fit: "fill"}).gif().toBuffer()
807820
}
808-
buffer = await functions.encodeGIF(newFrameArray, delayArray, width, height)
809821
if (options.quality !== 100) {
810822
buffer = await imagemin.buffer(buffer, {plugins: [
811823
imageminGifsicle({optimizationLevel: 3})
@@ -824,9 +836,11 @@ ipcMain.handle("compress-realtime", async (event, info: any) => {
824836
}
825837
if (sourceExt !== ext) {
826838
let s = sharp(buffer, {animated: true})
827-
if (ext === "jpg" || ext === "jpeg") s.jpeg()
828-
if (ext === "png") s.png()
829-
if (ext === "webp") s.webp()
839+
if (ext === "jpg" || ext === "jpeg") s.jpeg({optimiseScans: options.progressive, quality: options.quality})
840+
if (ext === "png") s.png({quality: options.quality})
841+
if (ext === "webp") s.webp({quality: options.quality})
842+
if (ext === "avif") s.avif({quality: options.quality})
843+
if (ext === "jxl") s.jxl({quality: options.quality})
830844
if (ext === "gif") s.gif()
831845
buffer = await s.toBuffer()
832846
}
@@ -839,7 +853,6 @@ ipcMain.handle("compress-realtime", async (event, info: any) => {
839853
]})
840854
}
841855
}
842-
console.log(buffer)
843856
return {buffer, fileSize: Buffer.byteLength(buffer)}
844857
} catch (error) {
845858
console.log(error)
@@ -1011,7 +1024,7 @@ if (!singleLock) {
10111024
})
10121025

10131026
app.on("ready", () => {
1014-
window = new BrowserWindow({width: 800, height: 600, minWidth: 720, minHeight: 450, frame: false, backgroundColor: "#e14952", center: true, webPreferences: {nodeIntegration: true, contextIsolation: false}})
1027+
window = new BrowserWindow({roundedCorners: false, width: 800, height: 600, minWidth: 720, minHeight: 450, frame: false, backgroundColor: "#e14952", center: true, webPreferences: {nodeIntegration: true, contextIsolation: false}})
10151028
window.loadFile(path.join(__dirname, "index.html"))
10161029
window.removeMenu()
10171030
require("@electron/remote/main").enable(window.webContents)

0 commit comments

Comments
 (0)