Skip to content

Commit

Permalink
✨ Feature(custom): optimize upload progress event
Browse files Browse the repository at this point in the history
  • Loading branch information
Kuingsmile committed Jun 27, 2024
1 parent a9ac4cd commit 048b338
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 101 deletions.
24 changes: 11 additions & 13 deletions src/core/Lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import {
import {
getURLFile,
handleUrlEncode,
imageProcess,
imageCompress,
isUrl,
needCompress,
needAddWatermark,
isNeedCompress,
isNeedAddWatermark,
imageAddWaterMark,
removeExif,
renameFileNameWithCustomString,
Expand All @@ -48,8 +48,7 @@ export class Lifecycle extends EventEmitter {
}

async downloadTTF(): Promise<boolean> {
const outputDir = path.dirname(this.ttfPath)
ensureDirSync(outputDir)
ensureDirSync(path.dirname(this.ttfPath))
if (fs.existsSync(this.ttfPath)) return true
this.ctx.log.info('Download ttf file.')
try {
Expand Down Expand Up @@ -100,7 +99,9 @@ export class Lifecycle extends EventEmitter {
ctx.rawInput = cloneDeep(input)
ctx.output = [] as IImgInfo[]
const { compressOptions, watermarkOptions } = this.helpGetOption(ctx)

ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 0)
ctx.emit(IBuildInEvent.BEFORE_TRANSFORM, ctx)
ctx.log.info('Before transform')
if (compressOptions || watermarkOptions) {
const tempFilePath = path.join(ctx.baseDir, 'piclistTemp')

Expand All @@ -115,7 +116,7 @@ export class Lifecycle extends EventEmitter {
ctx.rawInputPath![index] = item
const extention = itemIsUrl ? info.extname || '' : path.extname(item)
const fileBuffer: Buffer = itemIsUrl ? info.buffer! : fs.readFileSync(item)
if (needAddWatermark(watermarkOptions, extention)) {
if (isNeedAddWatermark(watermarkOptions, extention)) {
if (!(watermarkOptions?.watermarkFontPath || watermarkOptions?.watermarkType === 'image')) {
const downloadTTFRet = await this.downloadTTF()
if (!downloadTTFRet) {
Expand All @@ -128,7 +129,7 @@ export class Lifecycle extends EventEmitter {
transformedBuffer = await imageAddWaterMark(fileBuffer, watermarkOptions!, this.ttfPath, ctx.log)
}
}
if (needCompress(compressOptions, extention)) {
if (isNeedCompress(compressOptions, extention)) {
ctx.log.info(compressMsg)
if (!itemIsUrl && (extention === '.heic' || extention === '.heif')) {
const heicResult = await heicConvert({
Expand All @@ -138,14 +139,14 @@ export class Lifecycle extends EventEmitter {
})
const tempHeicConvertFile = path.join(tempFilePath, `${path.basename(item, extention)}.jpg`)
fs.writeFileSync(tempHeicConvertFile, Buffer.from(heicResult))
transformedBuffer = await imageProcess(
transformedBuffer = await imageCompress(
fs.readFileSync(tempHeicConvertFile),
compressOptions!,
'.jpg',
ctx.log
)
} else {
transformedBuffer = await imageProcess(
transformedBuffer = await imageCompress(
transformedBuffer ?? fileBuffer,
compressOptions!,
extention,
Expand Down Expand Up @@ -226,9 +227,6 @@ export class Lifecycle extends EventEmitter {
}

private async beforeTransform(ctx: IPicGo): Promise<IPicGo> {
ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 0)
ctx.emit(IBuildInEvent.BEFORE_TRANSFORM, ctx)
ctx.log.info('Before transform')
await this.handlePlugins(ctx.helper.beforeTransformPlugins, ctx)
return ctx
}
Expand Down
138 changes: 50 additions & 88 deletions src/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,32 +426,11 @@ export function safeParse<T>(str: string): T | string {
}
}

// hold...
// export const configWhiteList: RegExp[] = [
// /^picBed/,
// /^picgoPlugins/,
// /^@[^/]+\/picgo-plugin-/,
// /debug/,
// /silent/,
// /configPath/,
// /^settings/,
// ]

// export const isConfigKeyInWhiteList = (key: string): boolean => {
// return configWhiteList.some(whiteItem => whiteItem.test(key))
// }

export const forceNumber = (num: string | number = 0): number => {
return isNaN(Number(num)) ? 0 : Number(num)
}

export const isDev = (): boolean => {
return process.env.NODE_ENV === 'development'
}

export const isProd = (): boolean => {
return process.env.NODE_ENV === 'production'
}
export const isDev = (): boolean => process.env.NODE_ENV === 'development'

async function text2SVG(
defaultWatermarkFontPath: string,
Expand All @@ -470,8 +449,7 @@ async function text2SVG(
}
}
const textSVG = text2SVG.getSVG(text, options)
const svg = Buffer.from(textSVG)
return svg
return Buffer.from(textSVG)
}

const defaultWatermarkImagePath = path.join(__dirname, 'assets', 'piclist.png')
Expand Down Expand Up @@ -504,7 +482,7 @@ export async function AddWatermark(
imgWidth,
watermarkDegree
)
const composited = await image
return await image
.composite([
{
input: watermark,
Expand All @@ -513,7 +491,6 @@ export async function AddWatermark(
}
])
.toBuffer()
return composited
}

async function createWatermark(
Expand Down Expand Up @@ -559,22 +536,17 @@ async function getSize(image: Buffer): Promise<{ width: number; height: number }

const validParam = (...params: any[]): boolean => {
return params.every(param => {
if (param === undefined || param === null) {
return false
}
if (typeof param === 'string') {
return param !== ''
}
if (typeof param === 'number') {
return param > 0
}
if (typeof param === 'object') {
return Object.keys(param).length > 0
}
if (param === undefined || param === null) return false
if (typeof param === 'string') return param !== ''
if (typeof param === 'number') return param > 0
if (typeof param === 'object') return Object.keys(param).length > 0
return true
})
}

/**
* 转换后可以输出的格式列表
*/
const availableConvertFormatList = [
'avif',
'dz',
Expand All @@ -599,11 +571,26 @@ const availableConvertFormatList = [
'webp'
]

const validOutputFormat = (format: string): boolean => {
return availableConvertFormatList.includes(format)
}
/**
* 可以处理的图片格式列表
*/
const imageFormatList = [
'jpg',
'jpeg',
'png',
'webp',
'bmp',
'tiff',
'tif',
'svg',
'ico',
'avif',
'heif',
'heic',
'gif'
]

const imageExtList = ['jpg', 'jpeg', 'png', 'webp', 'bmp', 'tiff', 'tif', 'svg', 'ico', 'avif', 'heif', 'heic']
const validOutputFormat = (format: string): boolean => availableConvertFormatList.includes(format)

export async function imageAddWaterMark(
img: Buffer,
Expand Down Expand Up @@ -658,18 +645,16 @@ function formatOptions(options: IBuildInCompressOptions): IBuildInCompressOption
}
}

export async function imageProcess(
export async function imageCompress(
img: Buffer,
options: IBuildInCompressOptions,
rawFormat: string,
logger: ILogger
): Promise<Buffer> {
options = formatOptions(options)
try {
rawFormat = rawFormat.toLowerCase().replace('.', '')
if (!imageExtList.includes(rawFormat)) {
return img
}
rawFormat = normalizeImageExt(rawFormat)
if (!imageFormatList.includes(rawFormat) || rawFormat === 'gif') return img
let image: sharp.Sharp = sharp(img, { animated: true })
let quality = 100
if (validParam(options.quality) && options.quality! < 100) {
Expand Down Expand Up @@ -770,9 +755,13 @@ export async function imageProcess(
}
}

const normalizeImageExt = (ext: string): string => {
return ext.toLowerCase().replace('.', '')
}

export function getConvertedFormat(options: IBuildInCompressOptions | undefined, rawFormat: string): string {
options = formatOptions(options || {})
rawFormat = rawFormat.toLowerCase().replace('.', '')
rawFormat = normalizeImageExt(rawFormat)
if (rawFormat === 'gif') return 'gif'
let newFormat = options?.convertFormat || 'jpg'
if (options?.formatConvertObj && Object.keys(options.formatConvertObj).length > 0) {
Expand All @@ -791,35 +780,18 @@ export function getConvertedFormat(options: IBuildInCompressOptions | undefined,
return newFormat
}

const imageFormatList = [
'jpg',
'jpeg',
'png',
'webp',
'bmp',
'tiff',
'tif',
'svg',
'ico',
'avif',
'heif',
'heic',
'gif'
]

export const needAddWatermark = (watermarkOptions: IBuildInWaterMarkOptions | undefined, fileExt: string): boolean => {
fileExt = fileExt.toLowerCase().replace('.', '')
export const isNeedAddWatermark = (
watermarkOptions: IBuildInWaterMarkOptions | undefined,
fileExt: string
): boolean => {
fileExt = normalizeImageExt(fileExt)
return (
!!watermarkOptions && !!watermarkOptions.isAddWatermark && imageFormatList.includes(fileExt) && fileExt !== 'svg'
)
}

export const needCompress = (compressOptions: IBuildInCompressOptions | undefined, fileExt: string): boolean => {
const normalizedExt = fileExt.toLowerCase().replace('.', '')

if (!imageFormatList.includes(normalizedExt) || !compressOptions) {
return false
}
export const isNeedCompress = (compressOptions: IBuildInCompressOptions | undefined, fileExt: string): boolean => {
if (!imageFormatList.includes(normalizeImageExt(fileExt)) || !compressOptions) return false

const {
quality,
Expand All @@ -836,24 +808,16 @@ export const needCompress = (compressOptions: IBuildInCompressOptions | undefine
isFlop
} = formatOptions(compressOptions)

if (validParam(quality) && quality! < 100) {
return true
}
if (isReSizeByPercent && validParam(reSizePercent)) {
return true
}
if (validParam(quality) && quality! < 100) return true
if (isReSizeByPercent && validParam(reSizePercent)) return true
if (
isReSize &&
((typeof reSizeHeight === 'number' && reSizeHeight > 0) || (typeof reSizeWidth === 'number' && reSizeWidth > 0))
) {
return true
}
if (isRotate && rotateDegree) {
return true
}
if (isFlip || isFlop) {
return true
}
if (isRotate && rotateDegree) return true
if (isFlip || isFlop) return true
if (isConvert) {
const newFormat = convertFormat || 'jpg'
return fileExt !== newFormat
Expand All @@ -862,10 +826,8 @@ export const needCompress = (compressOptions: IBuildInCompressOptions | undefine
}

export const removeExif = async (img: Buffer, fileExt: string): Promise<Buffer> => {
fileExt = fileExt.toLowerCase().replace('.', '')
if (!imageFormatList.includes(fileExt) || fileExt === 'svg') {
return img
}
fileExt = normalizeImageExt(fileExt)
if (!imageFormatList.includes(fileExt) || fileExt === 'svg') return img
return await sharp(img, {
animated: true
}).toBuffer()
Expand Down

0 comments on commit 048b338

Please sign in to comment.