Skip to content

Commit

Permalink
v1.5.2: 🛠 🎨 : Refactor and optimize the code about compress
Browse files Browse the repository at this point in the history
  • Loading branch information
supine0703 committed Aug 7, 2024
1 parent 04c555e commit e74dc30
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 165 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "picgo-plugin-compress-next",
"version": "1.5.1",
"version": "1.5.2",
"description": "Image compression plugin for PicGo(>=^2.3.0). Update, adapt and optimize. Better support and richer features",
"main": "dist/index.js",
"type": "commonjs",
Expand Down
52 changes: 52 additions & 0 deletions src/compress/compress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { IPicGo } from 'picgo';
import { CommonParams, ImageInfo } from '../interface';
import { getImageBuffer, getImageInfo } from '../utils';
import { getOption, OptionModule } from './option';

interface CompressFn {
module: OptionModule;
optionType: 'object' | 'string';
toCompressBuffer: (buffer: Buffer, option: any) => Promise<Buffer>;
toWebP?: boolean;
}

/**
* Compresses an image to WebP format using cwebp from webp-converter plugin.
* @param ctx The PicGo instance.
* @param imageUrl The URL of the image to be compressed.
* @returns A Promise that resolves to an ImageInfo object containing information about the compressed image.
*/
export function Compress(ctx: IPicGo, imageUrl: string, fn: CompressFn): Promise<ImageInfo> {
ctx.log.info(`The ${fn.module} compression started`);

return (async () => {
const buffer = await getImageBuffer(ctx, imageUrl);

let getInfo = getImageInfo;
if (fn.toWebP) {
ctx.log.info('Converting image to WebP');
getInfo = (url: string, buffer: Buffer) => {
const info = getImageInfo(url, buffer);
const extname = '.webp';
const fileName = info.fileName.replace(info.extname, extname);
return { ...info, fileName, extname };
};
}

const result = await getOption(fn.module).then((option) => {
if (typeof option !== fn.optionType) {
throw new TypeError(`The option is not a ${fn.optionType}`);
}
ctx.log.info(fn.module, JSON.stringify(option));
return fn.toCompressBuffer(buffer, option);
});

if (buffer.length <= result.length) {
ctx.log.warn('The compressed image is larger than the original image. Skipping compression');
return getImageInfo(imageUrl, buffer, result.length / buffer.length);
}

ctx.log.info(`The ${fn.module} compression successful`);
return getInfo(imageUrl, result);
})();
}
39 changes: 7 additions & 32 deletions src/compress/imagemin/gif2webp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import imagemin from 'imagemin';
import imageminGif2webp from 'imagemin-gif2webp';
import { IPicGo } from 'picgo';
import { CommonParams, ImageInfo } from '../../interface';
import { getImageBuffer, getImageInfo } from '../../utils';
import { getOption } from '../option';
import { Compress } from '../compress';

/**
* Compresses an Gif to WebP format using imagemin-webp plugin.
Expand All @@ -12,34 +11,10 @@ import { getOption } from '../option';
* @returns A Promise that resolves to an ImageInfo object containing information about the compressed image.
*/
export function Gif2WebP(ctx: IPicGo, { imageUrl }: CommonParams): Promise<ImageInfo> {
ctx.log.info('The imagemin-gif2webp compression started');

return (async () => {
const buffer = await getImageBuffer(ctx, imageUrl);
ctx.log.info('Converting image to WebP');

const module = 'imagemin-gif2webp';
const result = await getOption(module).then((option) => {
if (typeof option !== 'object') {
throw new TypeError('The option is not a object');
}
ctx.log.info(module, JSON.stringify(option));
return imagemin.buffer(buffer, { plugins: [imageminGif2webp(option)] });
});

if (buffer.length <= result.length) {
ctx.log.warn('The compressed image is larger than the original image. Skipping compression');
return getImageInfo(imageUrl, buffer, result.length / buffer.length);
}

ctx.log.info('The imagemin-gif2webp compression successful');
const info = getImageInfo(imageUrl, result);
const extname = '.webp';
const fileName = info.fileName.replace(info.extname, extname);
return {
...info,
fileName,
extname,
};
})();
return Compress(ctx, imageUrl, {
module: 'imagemin-gif2webp',
optionType: 'object',
toCompressBuffer: (buffer: Buffer, option: {}) => imagemin.buffer(buffer, { plugins: [imageminGif2webp(option)] }),
toWebP: true,
});
}
32 changes: 8 additions & 24 deletions src/compress/imagemin/mozjpeg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import imagemin from 'imagemin';
import mozjpeg from 'imagemin-mozjpeg';
import upng from 'imagemin-upng';
import { IPicGo } from 'picgo';
import { extname as getExtname } from 'path';
import { extname } from 'path';
import { CommonParams, ImageInfo } from '../../interface';
import { getImageBuffer, getImageInfo } from '../../utils';
import { getOption } from '../option';
import { Compress } from '../compress';

/**
* Compresses an image using imagemin library with MozJPEG and UPNG plugins.
Expand All @@ -15,7 +14,7 @@ import { getOption } from '../option';
*/
export function Image(ctx: IPicGo, { imageUrl }: CommonParams): Promise<ImageInfo> {
const [module, plugin]: ['imagemin-mozjpeg' | 'imagemin-upng', any] = (() => {
switch (getExtname(imageUrl).toLowerCase()) {
switch (extname(imageUrl).toLowerCase()) {
case '.jpg':
case '.jpeg':
return ['imagemin-mozjpeg', mozjpeg];
Expand All @@ -25,25 +24,10 @@ export function Image(ctx: IPicGo, { imageUrl }: CommonParams): Promise<ImageInf
throw new TypeError('The image type can be only jpg/jpeg or png');
}
})();
ctx.log.info(`The ${module} compression started`);

return (async () => {
const buffer = await getImageBuffer(ctx, imageUrl);

const result = await getOption(module).then((option) => {
if (typeof option !== 'object') {
throw new TypeError('The option is not a object');
}
ctx.log.info(module, JSON.stringify(option));
return imagemin.buffer(buffer, { plugins: [plugin(option)] });
});

if (buffer.length <= result.length) {
ctx.log.warn('The compressed image is larger than the original image. Skipping compression');
return getImageInfo(imageUrl, buffer, result.length / buffer.length);
}

ctx.log.info(`The ${module} compression successful`);
return getImageInfo(imageUrl, result);
})();
return Compress(ctx, imageUrl, {
module: module,
optionType: 'object',
toCompressBuffer: (buffer: Buffer, option: {}) => imagemin.buffer(buffer, { plugins: [plugin(option)] }),
});
}
41 changes: 8 additions & 33 deletions src/compress/imagemin/webp.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { IPicGo } from 'picgo';
import imagemin from 'imagemin';
import imageminWebp from 'imagemin-webp';
import { IPicGo } from 'picgo';
import { CommonParams, ImageInfo } from '../../interface';
import { getImageBuffer, getImageInfo } from '../../utils';
import { getOption } from '../option';
import { Compress } from '../compress';

/**
* Compresses an image to WebP format using imagemin-gif2webp plugin.
Expand All @@ -12,34 +11,10 @@ import { getOption } from '../option';
* @returns A Promise that resolves to an ImageInfo object containing information about the compressed image.
*/
export function Webp(ctx: IPicGo, { imageUrl }: CommonParams): Promise<ImageInfo> {
ctx.log.info('The imagemin-webp compression started');

return (async () => {
const buffer = await getImageBuffer(ctx, imageUrl);
ctx.log.info('Converting image to WebP');

const module = 'imagemin-webp';
const result = await getOption(module).then((option) => {
if (typeof option !== 'object') {
throw new TypeError('The option is not a object');
}
ctx.log.info(module, JSON.stringify(option));
return imagemin.buffer(buffer, { plugins: [imageminWebp(option)] });
});

if (buffer.length <= result.length) {
ctx.log.warn('The compressed image is larger than the original image. Skipping compression');
return getImageInfo(imageUrl, buffer, result.length / buffer.length);
}

ctx.log.info('The imagemin-webp compression successful');
const info = getImageInfo(imageUrl, result);
const extname = '.webp';
const fileName = info.fileName.replace(info.extname, extname);
return {
...info,
fileName,
extname,
};
})();
return Compress(ctx, imageUrl, {
module: 'imagemin-webp',
optionType: 'object',
toCompressBuffer: (buffer: Buffer, option: {}) => imagemin.buffer(buffer, { plugins: [imageminWebp(option)] }),
toWebP: true,
});
}
9 changes: 4 additions & 5 deletions src/compress/option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,15 @@ const defaultOption = {
'webp-converter-gwebp': {
url: 'https://developers.google.com/speed/webp/docs/gif2webp',
option: '-q 80 -m 6 -lossy -min_size',
recommend: [
'-q 70 -m 6 -lossy',
'-q 60 -m 6 -lossy'
],
recommend: ['-q 70 -m 6 -lossy', '-q 60 -m 6 -lossy'],
},
},
};

const filePath = join(__dirname, 'option.json');

export type OptionModule = keyof typeof defaultOption.module;

export async function resetOption(): Promise<void> {
await fs.writeJSON(filePath, defaultOption);
}
Expand All @@ -109,7 +108,7 @@ export async function getOptionFilePath(): Promise<string> {
});
}

export async function getOption(module: keyof typeof defaultOption.module): Promise<{} | string> {
export async function getOption(module: OptionModule): Promise<{} | string> {
if (await fs.pathExists(filePath)) {
const option: Option = await fs.readJSON(filePath);
if (option?.reset === 'not' && option?.module?.[module]?.option) {
Expand Down
44 changes: 10 additions & 34 deletions src/compress/webp-converter/cwebp.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Buffer2WebPBuffer } from './utils';
import { IPicGo } from 'picgo';
import { cwebp } from 'webp-converter';
import { extname as getExtname } from 'path';
import { extname } from 'path';
import { Buffer2WebPBuffer } from './utils';
import { CommonParams, ImageInfo } from '../../interface';
import { getImageBuffer, getImageInfo } from '../../utils';
import { getOption } from '../option';
import { Compress } from '../compress';

/**
* Compresses an image to WebP format using cwebp from webp-converter plugin.
Expand All @@ -13,34 +12,11 @@ import { getOption } from '../option';
* @returns A Promise that resolves to an ImageInfo object containing information about the compressed image.
*/
export function CWebP(ctx: IPicGo, { imageUrl }: CommonParams): Promise<ImageInfo> {
ctx.log.info('The webp-converter compression started');

return (async () => {
const buffer = await getImageBuffer(ctx, imageUrl);
ctx.log.info('Converting image to WebP');

const module = 'webp-converter-cwebp';
const result = await getOption(module).then((option) => {
if (typeof option !== 'string') {
throw new TypeError('The option is not a string');
}
ctx.log.info(module, option);
return Buffer2WebPBuffer(buffer, getExtname(imageUrl), cwebp, option);
});

if (buffer.length <= result.length) {
ctx.log.warn('The compressed image is larger than the original image. Skipping compression');
return getImageInfo(imageUrl, buffer, result.length / buffer.length);
}

ctx.log.info('The webp-converter compression successful');
const info = getImageInfo(imageUrl, result);
const extname = '.webp';
const fileName = info.fileName.replace(info.extname, extname);
return {
...info,
fileName,
extname,
};
})();
return Compress(ctx, imageUrl, {
module: 'webp-converter-cwebp',
optionType: 'string',
toCompressBuffer: (buffer: Buffer, option: string) =>
Buffer2WebPBuffer(buffer, extname(imageUrl), cwebp, option),
toWebP: true,
});
}
44 changes: 10 additions & 34 deletions src/compress/webp-converter/gwebp.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { CommonParams, ImageInfo } from '../../interface';
import { getImageBuffer, getImageInfo } from '../../utils';
import { Buffer2WebPBuffer } from './utils';
import { IPicGo } from 'picgo';
import { gwebp } from 'webp-converter';
import { getOption } from '../option';
import { Buffer2WebPBuffer } from './utils';
import { CommonParams, ImageInfo } from '../../interface';
import { Compress } from '../compress';

/**
* Compresses an Gif to WebP format using gwebp from webp-converter plugin.
Expand All @@ -12,34 +11,11 @@ import { getOption } from '../option';
* @returns A Promise that resolves to an ImageInfo object containing information about the compressed image.
*/
export function GWebP(ctx: IPicGo, { imageUrl }: CommonParams): Promise<ImageInfo> {
ctx.log.info('The webp-converter (gif 2 webp) compression started');

return (async () => {
const buffer = await getImageBuffer(ctx, imageUrl);
ctx.log.info('Converting Gif to WebP');

const module = 'webp-converter-gwebp';
const result = await getOption(module).then((option) => {
if (typeof option !== 'string') {
throw new TypeError('The option is not a string');
}
ctx.log.info(module, option);
return Buffer2WebPBuffer(buffer, '.gif', gwebp, option);
});

if (buffer.length <= result.length) {
ctx.log.warn('The compressed image is larger than the original image. Skipping compression');
return getImageInfo(imageUrl, buffer, result.length / buffer.length);
}

ctx.log.info('The webp-converter (gif 2 webp) compression successful');
const info = getImageInfo(imageUrl, result);
const webpExtname = '.webp';
const fileName = info.fileName.replace(info.extname, webpExtname);
return {
...info,
fileName,
webpExtname,
};
})();
return Compress(ctx, imageUrl, {
module: 'webp-converter-gwebp',
optionType: 'string',
toCompressBuffer: (buffer: Buffer, option: string) =>
Buffer2WebPBuffer(buffer, '.gif', gwebp, option),
toWebP: true,
});
}

0 comments on commit e74dc30

Please sign in to comment.