diff --git a/assets/simhei.ttf b/assets/simhei.ttf deleted file mode 100644 index 5bd4687..0000000 Binary files a/assets/simhei.ttf and /dev/null differ diff --git a/package.json b/package.json index 7e2734e..ead3200 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,15 @@ "name": "piclist", "version": "0.2.4", "description": "Modified PicGo core, A tool for picture uploading", + "author": { + "name": "Kuingsmile", + "email": "msq@msq.pub" + }, + "homepage": "https://piclist.cn", + "bugs": { + "url": "https://github.com/Kuingsmile/PicList/issues", + "email": "msq@msq.pub" + }, "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "typings": "dist/index.d.ts", @@ -46,7 +55,6 @@ "./node_modules/@picgo/bump-version/commitlint-picgo" ] }, - "author": "Kuingsmile", "license": "MIT", "devDependencies": { "@picgo/bump-version": "^1.1.2", @@ -88,10 +96,10 @@ "husky": "^1.3.1", "pre-commit": "^1.2.2", "rollup": "^2.58.0", + "rollup-plugin-copy": "^3.4.0", "rollup-plugin-string": "^3.0.0", "rollup-plugin-terser": "^7.0.2", "rollup-plugin-typescript2": "^0.30.0", - "rollup-plugin-copy": "^3.4.0", "typescript": "^4.8.2" }, "dependencies": { diff --git a/src/core/Lifecycle.ts b/src/core/Lifecycle.ts index 38620ae..e7c910f 100644 --- a/src/core/Lifecycle.ts +++ b/src/core/Lifecycle.ts @@ -5,15 +5,40 @@ import { IBuildInEvent } from '../utils/enum' import { createContext } from '../utils/createContext' import path from 'path' import fs from 'fs-extra' +import axios from 'axios' export class Lifecycle extends EventEmitter { private readonly ctx: IPicGo + private readonly ttfLink: string = 'https://release.piclist.cn/simhei.ttf' + ttfPath: string constructor (ctx: IPicGo) { super() this.ctx = ctx const tempFilePath = path.join(ctx.baseDir, 'piclistTemp') fs.emptyDirSync(tempFilePath) + this.ttfPath = path.join(ctx.baseDir, 'assets', 'simhei.ttf') + } + + async downloadTTF (): Promise { + const outputDir = path.dirname(this.ttfPath) + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }) + } + if (!fs.existsSync(this.ttfPath)) { + this.ctx.log.info('Download ttf file.') + try { + const res = await axios.get(this.ttfLink, { responseType: 'arraybuffer' }) + fs.writeFileSync(this.ttfPath, res.data) + this.ctx.log.info('Download ttf file success.') + return true + } catch (e: any) { + this.ctx.log.error('Download ttf file failed.') + return false + } + } else { + return true + } } async start (input: any[]): Promise { @@ -41,9 +66,14 @@ export class Lifecycle extends EventEmitter { info = await getURLFile(item, ctx) if (info.success && info.buffer) { let transformedBuffer - if (needAddWatermark(watermarkOptions)) { - ctx.log.info(watermarkMsg) - transformedBuffer = await imageAddWaterMark(info.buffer, watermarkOptions) + if (needAddWatermark(watermarkOptions, info.extname ?? '')) { + const downloadTTFRet = await this.downloadTTF() + if (!downloadTTFRet) { + this.ctx.log.warn('Download ttf file failed, skip add watermark.') + } else { + ctx.log.info(watermarkMsg) + transformedBuffer = await imageAddWaterMark(info.buffer, watermarkOptions, this.ttfPath) + } } if (needCompress(compressOptions, info.extname ?? '')) { ctx.log.info(compressMsg) @@ -68,9 +98,14 @@ export class Lifecycle extends EventEmitter { } } else { let transformedBuffer - if (needAddWatermark(watermarkOptions)) { - ctx.log.info(watermarkMsg) - transformedBuffer = await imageAddWaterMark(fs.readFileSync(item), watermarkOptions) + if (needAddWatermark(watermarkOptions, path.extname(item))) { + const downloadTTFRet = await this.downloadTTF() + if (!downloadTTFRet) { + this.ctx.log.warn('Download ttf file failed, skip add watermark.') + } else { + ctx.log.info(watermarkMsg) + transformedBuffer = await imageAddWaterMark(fs.readFileSync(item), watermarkOptions, this.ttfPath) + } } if (needCompress(compressOptions, path.extname(item))) { ctx.log.info(compressMsg) diff --git a/src/utils/common.ts b/src/utils/common.ts index 28d5094..495c60e 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -371,6 +371,7 @@ export const isProd = (): boolean => { } async function text2SVG ( + defaultWatermarkFontPath: string, text?: string, color?: string, fontFamily?: string @@ -391,11 +392,11 @@ async function text2SVG ( } const defaultWatermarkImagePath = `${__dirname}/assets/piclist.png` -const defaultWatermarkFontPath = `${__dirname}/assets/simhei.ttf` export async function AddWatermark ( img: Buffer, watermarkType: 'text' | 'image', + defaultWatermarkFontPath: string, isFullScreenWatermark?: boolean, watermarkDegree?: number, text?: string, @@ -411,6 +412,7 @@ export async function AddWatermark ( const watermark = await createWatermark( watermarkType, watermarkDegree, + defaultWatermarkFontPath, text, watermarkFontPath, watermarkScaleRatio, @@ -433,6 +435,7 @@ export async function AddWatermark ( async function createWatermark ( watermarkType: 'text' | 'image', watermarkDegree: number = 0, + defaultWatermarkFontPath: string, text?: string, watermarkFontPath?: string, watermarkScaleRatio?: number, @@ -446,6 +449,7 @@ async function createWatermark ( watermark = await sharp(watermarkImagePath).toBuffer() } else { watermark = await text2SVG( + defaultWatermarkFontPath, text, watermarkColor, watermarkFontPath || defaultWatermarkFontPath @@ -519,13 +523,14 @@ const validOutputFormat = (format: string): boolean => { const imageExtList = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'tiff', 'tif', 'svg', 'ico', 'avif', 'heif', 'heic'] -export async function imageAddWaterMark (img: Buffer, options: IBuildInWaterMarkOptions): Promise { +export async function imageAddWaterMark (img: Buffer, options: IBuildInWaterMarkOptions, defaultWatermarkFontPath: string): Promise { try { let image: sharp.Sharp = sharp(img) if (validParam(options.watermarkText)) { image = sharp(await AddWatermark( img, options.watermarkType || 'text', + defaultWatermarkFontPath, options.isFullScreenWatermark, forceNumber(options.watermarkDegree), options.watermarkText, @@ -620,12 +625,18 @@ export async function imageProcess (img: Buffer, options: IBuildInCompressOption } } -export const needAddWatermark = (watermarkOptions: IBuildInWaterMarkOptions | undefined): boolean => { - return !!watermarkOptions && !!watermarkOptions.isAddWatermark +const imageFormatList = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'tiff', 'tif', 'svg', 'ico', 'avif', 'heif', 'heic'] + +export const needAddWatermark = (watermarkOptions: IBuildInWaterMarkOptions | undefined, fileExt: string): boolean => { + fileExt = fileExt.toLowerCase().replace('.', '') + return !!watermarkOptions && !!watermarkOptions.isAddWatermark && imageFormatList.includes(fileExt) } export const needCompress = (compressOptions: IBuildInCompressOptions | undefined, fileExt: string): boolean => { fileExt = fileExt.toLowerCase().replace('.', '') + if (!imageFormatList.includes(fileExt)) { + return false + } if (compressOptions) { compressOptions = formatOptions(compressOptions) if (validParam(compressOptions.quality) && compressOptions.quality! < 100) { diff --git a/yarn.lock b/yarn.lock index 7d938c9..fdde745 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1021,9 +1021,9 @@ asynckit@^0.4.0: resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= -axios@^1.3.2: +axios@^1.3.4: version "1.3.4" - resolved "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz" + resolved "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz#f5760cefd9cfb51fd2481acf88c05f67c4523024" integrity sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ== dependencies: follow-redirects "^1.15.0"