zcw-shared 2.18.0 → 2.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/functions/chat/chatMorePageConfig.d.ts +12 -0
- package/dist/functions/chat/chatMorePageConfig.js +61 -0
- package/dist/functions/chat/chatMorePageConfig.js.map +1 -0
- package/dist/functions/chat/chatShellTabConfig.js +26 -5
- package/dist/functions/chat/chatShellTabConfig.js.map +1 -1
- package/dist/functions/image/compressImageToWidthJpgOrWebp.d.ts +8 -0
- package/dist/functions/image/compressImageToWidthJpgOrWebp.js +22 -0
- package/dist/functions/image/compressImageToWidthJpgOrWebp.js.map +1 -0
- package/dist/functions/image/compressJpgToTargetSize.d.ts +13 -0
- package/dist/functions/image/compressJpgToTargetSize.js +132 -0
- package/dist/functions/image/compressJpgToTargetSize.js.map +1 -0
- package/dist/functions/image/compressToTargetSize.d.ts +1 -1
- package/dist/functions/image/compressToTargetSizeJpg.d.ts +13 -0
- package/dist/functions/image/compressToTargetSizeJpg.js +132 -0
- package/dist/functions/image/compressToTargetSizeJpg.js.map +1 -0
- package/dist/functions/image/compressToTargetSizeJpgOrWebp.d.ts +10 -0
- package/dist/functions/image/compressToTargetSizeJpgOrWebp.js +83 -0
- package/dist/functions/image/compressToTargetSizeJpgOrWebp.js.map +1 -0
- package/dist/functions/image/imageJpgOrWebpExport.d.ts +23 -0
- package/dist/functions/image/imageJpgOrWebpExport.js +95 -0
- package/dist/functions/image/imageJpgOrWebpExport.js.map +1 -0
- package/package.json +6 -3
- package/references/browser.d.ts +7 -0
- package/references/dom.d.ts +25 -2
- package/types/chat-more-page-config.d.ts +16 -0
- package/dist/functions/image/compressToTargetSize.js +0 -96
- package/dist/functions/image/compressToTargetSize.js.map +0 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ChatMorePageEntry } from '../../../types/chat-more-page-config';
|
|
2
|
+
export type { ChatMorePageEntry };
|
|
3
|
+
export declare const DEFAULT_CHAT_MORE_ENTRIES: ChatMorePageEntry[];
|
|
4
|
+
export declare class ChatMorePageConfigError extends Error {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
export declare function parseMoreEntriesFromDisplays(displays: unknown): ChatMorePageEntry[];
|
|
8
|
+
export declare function resolveMoreEntryRouteTarget(entry: ChatMorePageEntry): {
|
|
9
|
+
name: string;
|
|
10
|
+
} | {
|
|
11
|
+
path: string;
|
|
12
|
+
} | null;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export const DEFAULT_CHAT_MORE_ENTRIES = [
|
|
2
|
+
{
|
|
3
|
+
key: 'lottery-plaza',
|
|
4
|
+
label: '彩票广场',
|
|
5
|
+
description: '高频投注 · 极速体验',
|
|
6
|
+
icon: 'cai',
|
|
7
|
+
route: '/lottery',
|
|
8
|
+
routeName: 'chat-lottery-plaza',
|
|
9
|
+
},
|
|
10
|
+
];
|
|
11
|
+
export class ChatMorePageConfigError extends Error {
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'ChatMorePageConfigError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function normalizeEntry(raw) {
|
|
18
|
+
if (raw == null || typeof raw !== 'object' || Array.isArray(raw))
|
|
19
|
+
return null;
|
|
20
|
+
const o = raw;
|
|
21
|
+
const key = String(o.key ?? '').trim();
|
|
22
|
+
if (!key)
|
|
23
|
+
return null;
|
|
24
|
+
const label = String(o.label ?? key).trim();
|
|
25
|
+
return {
|
|
26
|
+
key,
|
|
27
|
+
label,
|
|
28
|
+
description: o.description != null ? String(o.description).trim() : undefined,
|
|
29
|
+
icon: o.icon != null ? String(o.icon).trim() : undefined,
|
|
30
|
+
route: o.route != null ? String(o.route).trim() : undefined,
|
|
31
|
+
routeName: o.routeName != null ? String(o.routeName).trim() : undefined,
|
|
32
|
+
badge: o.badge != null ? String(o.badge).trim() : undefined,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export function parseMoreEntriesFromDisplays(displays) {
|
|
36
|
+
if (displays == null || typeof displays !== 'object' || Array.isArray(displays)) {
|
|
37
|
+
throw new ChatMorePageConfigError('page-config displays 缺失,无法解析 more.entries');
|
|
38
|
+
}
|
|
39
|
+
const more = displays.more;
|
|
40
|
+
const fromMore = more?.entries;
|
|
41
|
+
if (!Array.isArray(fromMore) || fromMore.length === 0) {
|
|
42
|
+
throw new ChatMorePageConfigError('displays.more.entries 未配置或为空');
|
|
43
|
+
}
|
|
44
|
+
const parsed = fromMore
|
|
45
|
+
.map((e) => normalizeEntry(e))
|
|
46
|
+
.filter((e) => e != null);
|
|
47
|
+
if (parsed.length === 0) {
|
|
48
|
+
throw new ChatMorePageConfigError('displays.more.entries 无有效项');
|
|
49
|
+
}
|
|
50
|
+
return parsed;
|
|
51
|
+
}
|
|
52
|
+
export function resolveMoreEntryRouteTarget(entry) {
|
|
53
|
+
const routeName = entry.routeName?.trim();
|
|
54
|
+
if (routeName)
|
|
55
|
+
return { name: routeName };
|
|
56
|
+
const path = entry.route?.trim();
|
|
57
|
+
if (!path)
|
|
58
|
+
return null;
|
|
59
|
+
return path.startsWith('/') ? { path } : { path: `/${path}` };
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=chatMorePageConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatMorePageConfig.js","sourceRoot":"","sources":["../../../src/functions/chat/chatMorePageConfig.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,11 +38,17 @@ export const DEFAULT_CHAT_SHELL_TABS = [
|
|
|
38
38
|
mobile: true,
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
|
-
key: '
|
|
42
|
-
label: '
|
|
43
|
-
icon: '
|
|
44
|
-
route: '/
|
|
45
|
-
routeName: 'chat-
|
|
41
|
+
key: 'community',
|
|
42
|
+
label: '社区',
|
|
43
|
+
icon: 'wenzhang',
|
|
44
|
+
route: '/community',
|
|
45
|
+
routeName: 'chat-community',
|
|
46
|
+
relatedRouteNames: [
|
|
47
|
+
'chat-short-video',
|
|
48
|
+
'chat-community-post',
|
|
49
|
+
'chat-community-publish-post',
|
|
50
|
+
'chat-community-publish-video',
|
|
51
|
+
],
|
|
46
52
|
desktopNav: true,
|
|
47
53
|
mobile: true,
|
|
48
54
|
},
|
|
@@ -56,6 +62,21 @@ export const DEFAULT_CHAT_SHELL_TABS = [
|
|
|
56
62
|
desktopNav: true,
|
|
57
63
|
mobile: true,
|
|
58
64
|
},
|
|
65
|
+
{
|
|
66
|
+
key: 'more',
|
|
67
|
+
label: '更多',
|
|
68
|
+
icon: 'gengduo',
|
|
69
|
+
route: '/more',
|
|
70
|
+
routeName: 'chat-more',
|
|
71
|
+
relatedRouteNames: [
|
|
72
|
+
'chat-lottery-plaza',
|
|
73
|
+
'chat-lottery-bjsc',
|
|
74
|
+
'chat-lottery-bjsc-1m',
|
|
75
|
+
'chat-lottery-bjsc-30s',
|
|
76
|
+
],
|
|
77
|
+
desktopNav: true,
|
|
78
|
+
mobile: true,
|
|
79
|
+
},
|
|
59
80
|
{
|
|
60
81
|
key: 'code',
|
|
61
82
|
label: '代码',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chatShellTabConfig.js","sourceRoot":"","sources":["../../../src/functions/chat/chatShellTabConfig.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,uBAAuB,GAAyB;IAC3D;QACE,GAAG,EAAE,UAAU;QACf,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,eAAe;QACrB,UAAU,EAAE,sBAAsB;QAClC,KAAK,EAAE,WAAW;QAClB,SAAS,EAAE,MAAM;QACjB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,IAAI;KACb;IACD;QACE,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,0BAA0B;QAChC,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,KAAK;QACZ,SAAS,EAAE,SAAS;QACpB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,IAAI;KACb;IACD;QACE,GAAG,EAAE,UAAU;QACf,KAAK,EAAE,KAAK;QACZ,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,WAAW;QAClB,SAAS,EAAE,eAAe;QAC1B,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,IAAI;KACb;IACD;QACE,GAAG,EAAE,KAAK;QACV,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,MAAM;QACb,SAAS,EAAE,UAAU;QACrB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,IAAI;KACb;IACD;QACE,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"chatShellTabConfig.js","sourceRoot":"","sources":["../../../src/functions/chat/chatShellTabConfig.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { File } from '../../../references/browser.d';
|
|
2
|
+
import { type CompressOutputFormat, type ImageJpgOrWebpExportDeps } from './imageJpgOrWebpExport';
|
|
3
|
+
export type { CompressOutputFormat };
|
|
4
|
+
export type CompressImageToWidthJpgOrWebpDeps = ImageJpgOrWebpExportDeps;
|
|
5
|
+
export declare function compressImageToWidthJpgOrWebp(file: File, targetWidth: number, options: {
|
|
6
|
+
quality?: number;
|
|
7
|
+
outputFormat?: CompressOutputFormat;
|
|
8
|
+
} | undefined, deps: CompressImageToWidthJpgOrWebpDeps): Promise<File>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { getImageDimensions } from './getImageDimensions';
|
|
2
|
+
import { fileMatchesOutputFormat, rasterizeImageToJpgOrWebp, } from './imageJpgOrWebpExport';
|
|
3
|
+
export async function compressImageToWidthJpgOrWebp(file, targetWidth, options = {}, deps) {
|
|
4
|
+
const { quality = 0.9, outputFormat = 'jpeg' } = options;
|
|
5
|
+
if (targetWidth <= 0) {
|
|
6
|
+
throw new Error('targetWidth 必须大于 0');
|
|
7
|
+
}
|
|
8
|
+
const dimensions = await getImageDimensions(file, {
|
|
9
|
+
Image: deps.Image,
|
|
10
|
+
createObjectURL: deps.createObjectURL,
|
|
11
|
+
});
|
|
12
|
+
const originalWidth = dimensions.width;
|
|
13
|
+
const originalHeight = dimensions.height;
|
|
14
|
+
const targetHeight = Math.round((targetWidth / originalWidth) * originalHeight);
|
|
15
|
+
if (originalWidth === targetWidth &&
|
|
16
|
+
originalHeight === targetHeight &&
|
|
17
|
+
fileMatchesOutputFormat(file, outputFormat)) {
|
|
18
|
+
return file;
|
|
19
|
+
}
|
|
20
|
+
return rasterizeImageToJpgOrWebp(file, { width: targetWidth, height: targetHeight, quality, outputFormat }, deps);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=compressImageToWidthJpgOrWebp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compressImageToWidthJpgOrWebp.js","sourceRoot":"","sources":["../../../src/functions/image/compressImageToWidthJpgOrWebp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAGL,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAA;AAU/B,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,IAAU,EACV,WAAmB,EACnB,UAII,EAAE,EACN,IAAuC;IAEvC,MAAM,EAAE,OAAO,GAAG,GAAG,EAAE,YAAY,GAAG,MAAM,EAAE,GAAG,OAAO,CAAA;IAExD,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;IACvC,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,IAAI,EAAE;QAChD,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,eAAe,EAAE,IAAI,CAAC,eAAe;KACtC,CAAC,CAAA;IAEF,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,CAAA;IACtC,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAA;IACxC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAC7B,CAAC,WAAW,GAAG,aAAa,CAAC,GAAG,cAAc,CAC/C,CAAA;IAED,IACE,aAAa,KAAK,WAAW;QAC7B,cAAc,KAAK,YAAY;QAC/B,uBAAuB,CAAC,IAAI,EAAE,YAAY,CAAC,EAC3C,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,yBAAyB,CAC9B,IAAI,EACJ,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,EACnE,IAAI,CACL,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { File, Window } from '../../../references/browser.d';
|
|
2
|
+
import type { Document } from '../../../references/dom.d';
|
|
3
|
+
export interface CompressJpgToTargetSizeDeps {
|
|
4
|
+
Image: Window['Image'];
|
|
5
|
+
File: Window['File'];
|
|
6
|
+
createObjectURL: (blob: File) => string;
|
|
7
|
+
createElement: Document['createElement'];
|
|
8
|
+
}
|
|
9
|
+
export declare function compressJpgToTargetSize(file: File, options: {
|
|
10
|
+
targetSize?: number;
|
|
11
|
+
maxIterations?: number;
|
|
12
|
+
strictTarget?: boolean;
|
|
13
|
+
} | undefined, deps: CompressJpgToTargetSizeDeps): Promise<File>;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { getImageDimensions } from './getImageDimensions';
|
|
2
|
+
const OUTPUT_MIME = 'image/jpeg';
|
|
3
|
+
function buildOutputFileName(originalName) {
|
|
4
|
+
const trimmed = (originalName || 'image').trim() || 'image';
|
|
5
|
+
const base = trimmed.replace(/\.[^./\\]+$/i, '') || 'image';
|
|
6
|
+
return `${base}.jpg`;
|
|
7
|
+
}
|
|
8
|
+
export async function compressJpgToTargetSize(file, options = {}, deps) {
|
|
9
|
+
const { targetSize = 30 * 1024, maxIterations = 30, strictTarget = false, } = options;
|
|
10
|
+
const isJpeg = (file.type || '').toLowerCase() === OUTPUT_MIME ||
|
|
11
|
+
/\.jpe?g$/i.test(file.name || '');
|
|
12
|
+
if (isJpeg && file.size <= targetSize) {
|
|
13
|
+
return file;
|
|
14
|
+
}
|
|
15
|
+
const dimensions = await getImageDimensions(file, {
|
|
16
|
+
Image: deps.Image,
|
|
17
|
+
createObjectURL: deps.createObjectURL,
|
|
18
|
+
});
|
|
19
|
+
let currentWidth = dimensions.width;
|
|
20
|
+
let currentHeight = dimensions.height;
|
|
21
|
+
let currentQuality = 0.9;
|
|
22
|
+
const minSide = 16;
|
|
23
|
+
let bestResult = null;
|
|
24
|
+
let iteration = 0;
|
|
25
|
+
while (iteration < maxIterations) {
|
|
26
|
+
iteration++;
|
|
27
|
+
const result = await compressImageToJpeg(file, {
|
|
28
|
+
quality: currentQuality,
|
|
29
|
+
maxWidth: currentWidth,
|
|
30
|
+
maxHeight: currentHeight,
|
|
31
|
+
}, deps);
|
|
32
|
+
if (!bestResult || result.size < bestResult.size) {
|
|
33
|
+
bestResult = result;
|
|
34
|
+
}
|
|
35
|
+
if (result.size <= targetSize) {
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
const ratio = targetSize / result.size;
|
|
39
|
+
const prevWidth = currentWidth;
|
|
40
|
+
const prevHeight = currentHeight;
|
|
41
|
+
if (ratio < 0.05) {
|
|
42
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.5));
|
|
43
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.5));
|
|
44
|
+
currentQuality = Math.max(0.05, currentQuality * 0.5);
|
|
45
|
+
}
|
|
46
|
+
else if (ratio < 0.15) {
|
|
47
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.6));
|
|
48
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.6));
|
|
49
|
+
currentQuality = Math.max(0.08, currentQuality * 0.6);
|
|
50
|
+
}
|
|
51
|
+
else if (ratio < 0.3) {
|
|
52
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.7));
|
|
53
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.7));
|
|
54
|
+
currentQuality = Math.max(0.1, currentQuality * 0.8);
|
|
55
|
+
}
|
|
56
|
+
else if (ratio < 0.7) {
|
|
57
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.85));
|
|
58
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.85));
|
|
59
|
+
currentQuality = Math.max(0.1, currentQuality * 0.85);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
currentQuality = Math.max(0.1, currentQuality * 0.9);
|
|
63
|
+
if (currentQuality <= 0.12) {
|
|
64
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.9));
|
|
65
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.9));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (currentWidth <= minSide &&
|
|
69
|
+
currentHeight <= minSide &&
|
|
70
|
+
prevWidth === currentWidth &&
|
|
71
|
+
prevHeight === currentHeight) {
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (bestResult) {
|
|
76
|
+
if (bestResult.size <= targetSize || !strictTarget) {
|
|
77
|
+
return bestResult;
|
|
78
|
+
}
|
|
79
|
+
if (bestResult.size < file.size) {
|
|
80
|
+
return bestResult;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const bestKb = bestResult ? (bestResult.size / 1024).toFixed(1) : '?';
|
|
84
|
+
const targetKb = (targetSize / 1024).toFixed(1);
|
|
85
|
+
throw new Error(`压缩失败:${maxIterations} 次尝试后最小约 ${bestKb}KB,目标 ${targetKb}KB。请提高目标大小或缩小原图。`);
|
|
86
|
+
}
|
|
87
|
+
function fitDimensions(naturalWidth, naturalHeight, maxWidth, maxHeight) {
|
|
88
|
+
let width = naturalWidth;
|
|
89
|
+
let height = naturalHeight;
|
|
90
|
+
if (width > maxWidth || height > maxHeight) {
|
|
91
|
+
const ratio = Math.min(maxWidth / width, maxHeight / height);
|
|
92
|
+
width = Math.floor(width * ratio);
|
|
93
|
+
height = Math.floor(height * ratio);
|
|
94
|
+
}
|
|
95
|
+
return { width, height };
|
|
96
|
+
}
|
|
97
|
+
function loadImageElement(file, deps) {
|
|
98
|
+
return new Promise((resolve, reject) => {
|
|
99
|
+
const img = new deps.Image();
|
|
100
|
+
img.onload = () => resolve(img);
|
|
101
|
+
img.onerror = () => reject(new Error('图片加载失败'));
|
|
102
|
+
img.src = deps.createObjectURL(file);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
async function compressImageToJpeg(file, options, deps) {
|
|
106
|
+
const { quality, maxWidth, maxHeight } = options;
|
|
107
|
+
const img = await loadImageElement(file, deps);
|
|
108
|
+
const canvas = deps.createElement('canvas');
|
|
109
|
+
const { width, height } = fitDimensions(img.naturalWidth, img.naturalHeight, maxWidth, maxHeight);
|
|
110
|
+
canvas.width = width;
|
|
111
|
+
canvas.height = height;
|
|
112
|
+
const ctx = canvas.getContext('2d', { alpha: false });
|
|
113
|
+
if (!ctx) {
|
|
114
|
+
throw new Error('无法创建 canvas 上下文');
|
|
115
|
+
}
|
|
116
|
+
ctx.fillStyle = '#ffffff';
|
|
117
|
+
ctx.fillRect(0, 0, width, height);
|
|
118
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
119
|
+
return new Promise((resolve, reject) => {
|
|
120
|
+
canvas.toBlob((blob) => {
|
|
121
|
+
if (!blob) {
|
|
122
|
+
reject(new Error('图片压缩失败'));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
resolve(new deps.File([blob], buildOutputFileName(file.name), {
|
|
126
|
+
type: OUTPUT_MIME,
|
|
127
|
+
lastModified: file.lastModified ?? Date.now(),
|
|
128
|
+
}));
|
|
129
|
+
}, OUTPUT_MIME, quality);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=compressJpgToTargetSize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compressJpgToTargetSize.js","sourceRoot":"","sources":["../../../src/functions/image/compressJpgToTargetSize.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,5 +9,5 @@ export interface CompressToTargetSizeDeps {
|
|
|
9
9
|
export declare function compressToTargetSize(file: File, options: {
|
|
10
10
|
targetSize?: number;
|
|
11
11
|
maxIterations?: number;
|
|
12
|
-
|
|
12
|
+
strictTarget?: boolean;
|
|
13
13
|
} | undefined, deps: CompressToTargetSizeDeps): Promise<File>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { File, Window } from '../../../references/browser.d';
|
|
2
|
+
import type { Document } from '../../../references/dom.d';
|
|
3
|
+
export interface CompressToTargetSizeJpgDeps {
|
|
4
|
+
Image: Window['Image'];
|
|
5
|
+
File: Window['File'];
|
|
6
|
+
createObjectURL: (blob: File) => string;
|
|
7
|
+
createElement: Document['createElement'];
|
|
8
|
+
}
|
|
9
|
+
export declare function compressToTargetSizeJpg(file: File, options: {
|
|
10
|
+
targetSize?: number;
|
|
11
|
+
maxIterations?: number;
|
|
12
|
+
strictTarget?: boolean;
|
|
13
|
+
} | undefined, deps: CompressToTargetSizeJpgDeps): Promise<File>;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { getImageDimensions } from './getImageDimensions';
|
|
2
|
+
const OUTPUT_MIME = 'image/jpeg';
|
|
3
|
+
function buildOutputFileName(originalName) {
|
|
4
|
+
const trimmed = (originalName || 'image').trim() || 'image';
|
|
5
|
+
const base = trimmed.replace(/\.[^./\\]+$/i, '') || 'image';
|
|
6
|
+
return `${base}.jpg`;
|
|
7
|
+
}
|
|
8
|
+
export async function compressToTargetSizeJpg(file, options = {}, deps) {
|
|
9
|
+
const { targetSize = 30 * 1024, maxIterations = 30, strictTarget = false, } = options;
|
|
10
|
+
const isJpeg = (file.type || '').toLowerCase() === OUTPUT_MIME ||
|
|
11
|
+
/\.jpe?g$/i.test(file.name || '');
|
|
12
|
+
if (isJpeg && file.size <= targetSize) {
|
|
13
|
+
return file;
|
|
14
|
+
}
|
|
15
|
+
const dimensions = await getImageDimensions(file, {
|
|
16
|
+
Image: deps.Image,
|
|
17
|
+
createObjectURL: deps.createObjectURL,
|
|
18
|
+
});
|
|
19
|
+
let currentWidth = dimensions.width;
|
|
20
|
+
let currentHeight = dimensions.height;
|
|
21
|
+
let currentQuality = 0.9;
|
|
22
|
+
const minSide = 16;
|
|
23
|
+
let bestResult = null;
|
|
24
|
+
let iteration = 0;
|
|
25
|
+
while (iteration < maxIterations) {
|
|
26
|
+
iteration++;
|
|
27
|
+
const result = await compressImageToJpeg(file, {
|
|
28
|
+
quality: currentQuality,
|
|
29
|
+
maxWidth: currentWidth,
|
|
30
|
+
maxHeight: currentHeight,
|
|
31
|
+
}, deps);
|
|
32
|
+
if (!bestResult || result.size < bestResult.size) {
|
|
33
|
+
bestResult = result;
|
|
34
|
+
}
|
|
35
|
+
if (result.size <= targetSize) {
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
const ratio = targetSize / result.size;
|
|
39
|
+
const prevWidth = currentWidth;
|
|
40
|
+
const prevHeight = currentHeight;
|
|
41
|
+
if (ratio < 0.05) {
|
|
42
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.5));
|
|
43
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.5));
|
|
44
|
+
currentQuality = Math.max(0.05, currentQuality * 0.5);
|
|
45
|
+
}
|
|
46
|
+
else if (ratio < 0.15) {
|
|
47
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.6));
|
|
48
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.6));
|
|
49
|
+
currentQuality = Math.max(0.08, currentQuality * 0.6);
|
|
50
|
+
}
|
|
51
|
+
else if (ratio < 0.3) {
|
|
52
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.7));
|
|
53
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.7));
|
|
54
|
+
currentQuality = Math.max(0.1, currentQuality * 0.8);
|
|
55
|
+
}
|
|
56
|
+
else if (ratio < 0.7) {
|
|
57
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.85));
|
|
58
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.85));
|
|
59
|
+
currentQuality = Math.max(0.1, currentQuality * 0.85);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
currentQuality = Math.max(0.1, currentQuality * 0.9);
|
|
63
|
+
if (currentQuality <= 0.12) {
|
|
64
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.9));
|
|
65
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.9));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (currentWidth <= minSide &&
|
|
69
|
+
currentHeight <= minSide &&
|
|
70
|
+
prevWidth === currentWidth &&
|
|
71
|
+
prevHeight === currentHeight) {
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (bestResult) {
|
|
76
|
+
if (bestResult.size <= targetSize || !strictTarget) {
|
|
77
|
+
return bestResult;
|
|
78
|
+
}
|
|
79
|
+
if (bestResult.size < file.size) {
|
|
80
|
+
return bestResult;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const bestKb = bestResult ? (bestResult.size / 1024).toFixed(1) : '?';
|
|
84
|
+
const targetKb = (targetSize / 1024).toFixed(1);
|
|
85
|
+
throw new Error(`压缩失败:${maxIterations} 次尝试后最小约 ${bestKb}KB,目标 ${targetKb}KB。请提高目标大小或缩小原图。`);
|
|
86
|
+
}
|
|
87
|
+
function fitDimensions(naturalWidth, naturalHeight, maxWidth, maxHeight) {
|
|
88
|
+
let width = naturalWidth;
|
|
89
|
+
let height = naturalHeight;
|
|
90
|
+
if (width > maxWidth || height > maxHeight) {
|
|
91
|
+
const ratio = Math.min(maxWidth / width, maxHeight / height);
|
|
92
|
+
width = Math.floor(width * ratio);
|
|
93
|
+
height = Math.floor(height * ratio);
|
|
94
|
+
}
|
|
95
|
+
return { width, height };
|
|
96
|
+
}
|
|
97
|
+
function loadImageElement(file, deps) {
|
|
98
|
+
return new Promise((resolve, reject) => {
|
|
99
|
+
const img = new deps.Image();
|
|
100
|
+
img.onload = () => resolve(img);
|
|
101
|
+
img.onerror = () => reject(new Error('图片加载失败'));
|
|
102
|
+
img.src = deps.createObjectURL(file);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
async function compressImageToJpeg(file, options, deps) {
|
|
106
|
+
const { quality, maxWidth, maxHeight } = options;
|
|
107
|
+
const img = await loadImageElement(file, deps);
|
|
108
|
+
const canvas = deps.createElement('canvas');
|
|
109
|
+
const { width, height } = fitDimensions(img.naturalWidth, img.naturalHeight, maxWidth, maxHeight);
|
|
110
|
+
canvas.width = width;
|
|
111
|
+
canvas.height = height;
|
|
112
|
+
const ctx = canvas.getContext('2d', { alpha: false });
|
|
113
|
+
if (!ctx) {
|
|
114
|
+
throw new Error('无法创建 canvas 上下文');
|
|
115
|
+
}
|
|
116
|
+
ctx.fillStyle = '#ffffff';
|
|
117
|
+
ctx.fillRect(0, 0, width, height);
|
|
118
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
119
|
+
return new Promise((resolve, reject) => {
|
|
120
|
+
canvas.toBlob((blob) => {
|
|
121
|
+
if (!blob) {
|
|
122
|
+
reject(new Error('图片压缩失败'));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
resolve(new deps.File([blob], buildOutputFileName(file.name), {
|
|
126
|
+
type: OUTPUT_MIME,
|
|
127
|
+
lastModified: file.lastModified ?? Date.now(),
|
|
128
|
+
}));
|
|
129
|
+
}, OUTPUT_MIME, quality);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=compressToTargetSizeJpg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compressToTargetSizeJpg.js","sourceRoot":"","sources":["../../../src/functions/image/compressToTargetSizeJpg.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { File } from '../../../references/browser.d';
|
|
2
|
+
import { type CompressOutputFormat, type ImageJpgOrWebpExportDeps } from './imageJpgOrWebpExport';
|
|
3
|
+
export type { CompressOutputFormat };
|
|
4
|
+
export type CompressToTargetSizeJpgOrWebpDeps = ImageJpgOrWebpExportDeps;
|
|
5
|
+
export declare function compressToTargetSizeJpgOrWebp(file: File, options: {
|
|
6
|
+
targetSize?: number;
|
|
7
|
+
maxIterations?: number;
|
|
8
|
+
outputFormat?: CompressOutputFormat;
|
|
9
|
+
strictTarget?: boolean;
|
|
10
|
+
} | undefined, deps: CompressToTargetSizeJpgOrWebpDeps): Promise<File>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { getImageDimensions } from './getImageDimensions';
|
|
2
|
+
import { OUTPUT_MIME, fileMatchesOutputFormat, fitWithinBox, rasterizeImageToJpgOrWebp, } from './imageJpgOrWebpExport';
|
|
3
|
+
export async function compressToTargetSizeJpgOrWebp(file, options = {}, deps) {
|
|
4
|
+
const { targetSize = 30 * 1024, maxIterations = 30, outputFormat = 'jpeg', strictTarget = false, } = options;
|
|
5
|
+
const mimeType = OUTPUT_MIME[outputFormat];
|
|
6
|
+
if (fileMatchesOutputFormat(file, outputFormat) && file.size <= targetSize) {
|
|
7
|
+
return file;
|
|
8
|
+
}
|
|
9
|
+
const dimensions = await getImageDimensions(file, {
|
|
10
|
+
Image: deps.Image,
|
|
11
|
+
createObjectURL: deps.createObjectURL,
|
|
12
|
+
});
|
|
13
|
+
let currentWidth = dimensions.width;
|
|
14
|
+
let currentHeight = dimensions.height;
|
|
15
|
+
let currentQuality = 0.9;
|
|
16
|
+
const minSide = 16;
|
|
17
|
+
let bestResult = null;
|
|
18
|
+
let iteration = 0;
|
|
19
|
+
while (iteration < maxIterations) {
|
|
20
|
+
iteration++;
|
|
21
|
+
const { width, height } = fitWithinBox(dimensions.width, dimensions.height, currentWidth, currentHeight);
|
|
22
|
+
const result = await rasterizeImageToJpgOrWebp(file, {
|
|
23
|
+
width,
|
|
24
|
+
height,
|
|
25
|
+
quality: currentQuality,
|
|
26
|
+
outputFormat,
|
|
27
|
+
}, deps);
|
|
28
|
+
if (!bestResult || result.size < bestResult.size) {
|
|
29
|
+
bestResult = result;
|
|
30
|
+
}
|
|
31
|
+
if (result.size <= targetSize) {
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
const ratio = targetSize / result.size;
|
|
35
|
+
const prevWidth = currentWidth;
|
|
36
|
+
const prevHeight = currentHeight;
|
|
37
|
+
if (ratio < 0.05) {
|
|
38
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.5));
|
|
39
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.5));
|
|
40
|
+
currentQuality = Math.max(0.05, currentQuality * 0.5);
|
|
41
|
+
}
|
|
42
|
+
else if (ratio < 0.15) {
|
|
43
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.6));
|
|
44
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.6));
|
|
45
|
+
currentQuality = Math.max(0.08, currentQuality * 0.6);
|
|
46
|
+
}
|
|
47
|
+
else if (ratio < 0.3) {
|
|
48
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.7));
|
|
49
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.7));
|
|
50
|
+
currentQuality = Math.max(0.1, currentQuality * 0.8);
|
|
51
|
+
}
|
|
52
|
+
else if (ratio < 0.7) {
|
|
53
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.85));
|
|
54
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.85));
|
|
55
|
+
currentQuality = Math.max(0.1, currentQuality * 0.85);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
currentQuality = Math.max(0.1, currentQuality * 0.9);
|
|
59
|
+
if (currentQuality <= 0.12) {
|
|
60
|
+
currentWidth = Math.max(minSide, Math.floor(currentWidth * 0.9));
|
|
61
|
+
currentHeight = Math.max(minSide, Math.floor(currentHeight * 0.9));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (currentWidth <= minSide &&
|
|
65
|
+
currentHeight <= minSide &&
|
|
66
|
+
prevWidth === currentWidth &&
|
|
67
|
+
prevHeight === currentHeight) {
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (bestResult) {
|
|
72
|
+
if (bestResult.size <= targetSize || !strictTarget) {
|
|
73
|
+
return bestResult;
|
|
74
|
+
}
|
|
75
|
+
if (bestResult.size < file.size) {
|
|
76
|
+
return bestResult;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const bestKb = bestResult ? (bestResult.size / 1024).toFixed(1) : '?';
|
|
80
|
+
const targetKb = (targetSize / 1024).toFixed(1);
|
|
81
|
+
throw new Error(`压缩失败:${maxIterations} 次尝试后最小约 ${bestKb}KB,目标 ${targetKb}KB(${mimeType})。请提高目标大小或缩小原图。`);
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=compressToTargetSizeJpgOrWebp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compressToTargetSizeJpgOrWebp.js","sourceRoot":"","sources":["../../../src/functions/image/compressToTargetSizeJpgOrWebp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { File, Window } from '../../../references/browser.d';
|
|
2
|
+
import type { Document } from '../../../references/dom.d';
|
|
3
|
+
export type CompressOutputFormat = 'jpeg' | 'webp';
|
|
4
|
+
export declare const OUTPUT_MIME: Record<CompressOutputFormat, string>;
|
|
5
|
+
export interface ImageJpgOrWebpExportDeps {
|
|
6
|
+
Image: Window['Image'];
|
|
7
|
+
File: Window['File'];
|
|
8
|
+
createObjectURL: (blob: File) => string;
|
|
9
|
+
createElement: Document['createElement'];
|
|
10
|
+
createImageBitmap?: Window['createImageBitmap'];
|
|
11
|
+
}
|
|
12
|
+
export declare function buildOutputFileName(originalName: string, format: CompressOutputFormat): string;
|
|
13
|
+
export declare function fileMatchesOutputFormat(file: File, format: CompressOutputFormat): boolean;
|
|
14
|
+
export declare function rasterizeImageToJpgOrWebp(file: File, params: {
|
|
15
|
+
width: number;
|
|
16
|
+
height: number;
|
|
17
|
+
quality: number;
|
|
18
|
+
outputFormat: CompressOutputFormat;
|
|
19
|
+
}, deps: ImageJpgOrWebpExportDeps): Promise<File>;
|
|
20
|
+
export declare function fitWithinBox(naturalWidth: number, naturalHeight: number, maxWidth: number, maxHeight: number): {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export const OUTPUT_MIME = {
|
|
2
|
+
jpeg: 'image/jpeg',
|
|
3
|
+
webp: 'image/webp',
|
|
4
|
+
};
|
|
5
|
+
export function buildOutputFileName(originalName, format) {
|
|
6
|
+
const ext = format === 'webp' ? 'webp' : 'jpg';
|
|
7
|
+
const trimmed = (originalName || 'image').trim() || 'image';
|
|
8
|
+
const base = trimmed.replace(/\.[^./\\]+$/i, '') || 'image';
|
|
9
|
+
return `${base}.${ext}`;
|
|
10
|
+
}
|
|
11
|
+
export function fileMatchesOutputFormat(file, format) {
|
|
12
|
+
const type = (file.type || '').toLowerCase();
|
|
13
|
+
const name = file.name || '';
|
|
14
|
+
if (format === 'jpeg') {
|
|
15
|
+
return type === 'image/jpeg' || /\.jpe?g$/i.test(name);
|
|
16
|
+
}
|
|
17
|
+
return type === 'image/webp' || /\.webp$/i.test(name);
|
|
18
|
+
}
|
|
19
|
+
function loadImageElement(file, deps) {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const img = new deps.Image();
|
|
22
|
+
img.onload = () => resolve(img);
|
|
23
|
+
img.onerror = () => reject(new Error('图片加载失败'));
|
|
24
|
+
img.src = deps.createObjectURL(file);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
async function decodeImageSource(file, preserveAlpha, deps) {
|
|
28
|
+
if (preserveAlpha && deps.createImageBitmap) {
|
|
29
|
+
try {
|
|
30
|
+
const bitmap = await deps.createImageBitmap(file, {
|
|
31
|
+
premultiplyAlpha: 'none',
|
|
32
|
+
});
|
|
33
|
+
return { source: bitmap, release: () => bitmap.close() };
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const img = await loadImageElement(file, deps);
|
|
39
|
+
return { source: img, release: () => { } };
|
|
40
|
+
}
|
|
41
|
+
function paintCanvas(canvas, source, width, height, preserveAlpha) {
|
|
42
|
+
canvas.width = width;
|
|
43
|
+
canvas.height = height;
|
|
44
|
+
const ctx = canvas.getContext('2d', { alpha: preserveAlpha });
|
|
45
|
+
if (!ctx) {
|
|
46
|
+
throw new Error('无法创建 canvas 上下文');
|
|
47
|
+
}
|
|
48
|
+
ctx.clearRect(0, 0, width, height);
|
|
49
|
+
if (preserveAlpha) {
|
|
50
|
+
ctx.globalCompositeOperation = 'copy';
|
|
51
|
+
ctx.drawImage(source, 0, 0, width, height);
|
|
52
|
+
ctx.globalCompositeOperation = 'source-over';
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
ctx.fillStyle = '#ffffff';
|
|
56
|
+
ctx.fillRect(0, 0, width, height);
|
|
57
|
+
ctx.drawImage(source, 0, 0, width, height);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export async function rasterizeImageToJpgOrWebp(file, params, deps) {
|
|
61
|
+
const { width, height, quality, outputFormat } = params;
|
|
62
|
+
const mimeType = OUTPUT_MIME[outputFormat];
|
|
63
|
+
const preserveAlpha = outputFormat === 'webp' && !!deps.createImageBitmap;
|
|
64
|
+
const { source, release } = await decodeImageSource(file, preserveAlpha, deps);
|
|
65
|
+
try {
|
|
66
|
+
const canvas = deps.createElement('canvas');
|
|
67
|
+
paintCanvas(canvas, source, width, height, preserveAlpha);
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
canvas.toBlob((blob) => {
|
|
70
|
+
if (!blob) {
|
|
71
|
+
reject(new Error('图片压缩失败'));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
resolve(new deps.File([blob], buildOutputFileName(file.name, outputFormat), {
|
|
75
|
+
type: mimeType,
|
|
76
|
+
lastModified: file.lastModified ?? Date.now(),
|
|
77
|
+
}));
|
|
78
|
+
}, mimeType, quality);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
release();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export function fitWithinBox(naturalWidth, naturalHeight, maxWidth, maxHeight) {
|
|
86
|
+
let width = naturalWidth;
|
|
87
|
+
let height = naturalHeight;
|
|
88
|
+
if (width > maxWidth || height > maxHeight) {
|
|
89
|
+
const ratio = Math.min(maxWidth / width, maxHeight / height);
|
|
90
|
+
width = Math.floor(width * ratio);
|
|
91
|
+
height = Math.floor(height * ratio);
|
|
92
|
+
}
|
|
93
|
+
return { width, height };
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=imageJpgOrWebpExport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imageJpgOrWebpExport.js","sourceRoot":"","sources":["../../../src/functions/image/imageJpgOrWebpExport.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zcw-shared",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.19.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"references",
|
|
6
6
|
"dist",
|
|
@@ -115,6 +115,7 @@
|
|
|
115
115
|
"./functions/browser/isMobile": "./dist/functions/browser/isMobile.js",
|
|
116
116
|
"./functions/browser/isWeChat": "./dist/functions/browser/isWeChat.js",
|
|
117
117
|
"./functions/browser/shortcutModKeyHint": "./dist/functions/browser/shortcutModKeyHint.js",
|
|
118
|
+
"./functions/chat/chatMorePageConfig": "./dist/functions/chat/chatMorePageConfig.js",
|
|
118
119
|
"./functions/chat/chatShellTabConfig": "./dist/functions/chat/chatShellTabConfig.js",
|
|
119
120
|
"./functions/chat/chatShellTabEditor": "./dist/functions/chat/chatShellTabEditor.js",
|
|
120
121
|
"./functions/code/getLanguageFromExtension": "./dist/functions/code/getLanguageFromExtension.js",
|
|
@@ -192,8 +193,8 @@
|
|
|
192
193
|
"./functions/im/getActiveMentionQuery": "./dist/functions/im/getActiveMentionQuery.js",
|
|
193
194
|
"./functions/im/imRichClipboardPlain": "./dist/functions/im/imRichClipboardPlain.js",
|
|
194
195
|
"./functions/im/imRichContentHtml": "./dist/functions/im/imRichContentHtml.js",
|
|
195
|
-
"./functions/image/
|
|
196
|
-
"./functions/image/
|
|
196
|
+
"./functions/image/compressImageToWidthJpgOrWebp": "./dist/functions/image/compressImageToWidthJpgOrWebp.js",
|
|
197
|
+
"./functions/image/compressToTargetSizeJpgOrWebp": "./dist/functions/image/compressToTargetSizeJpgOrWebp.js",
|
|
197
198
|
"./functions/image/generateFavIcon": "./dist/functions/image/generateFavIcon.js",
|
|
198
199
|
"./functions/image/generateMacIcons": "./dist/functions/image/generateMacIcons.js",
|
|
199
200
|
"./functions/image/generateMacTrayIcon": "./dist/functions/image/generateMacTrayIcon.js",
|
|
@@ -202,6 +203,7 @@
|
|
|
202
203
|
"./functions/image/generatePwaIcons": "./dist/functions/image/generatePwaIcons.js",
|
|
203
204
|
"./functions/image/generateRoundedImage": "./dist/functions/image/generateRoundedImage.js",
|
|
204
205
|
"./functions/image/getImageDimensions": "./dist/functions/image/getImageDimensions.js",
|
|
206
|
+
"./functions/image/imageJpgOrWebpExport": "./dist/functions/image/imageJpgOrWebpExport.js",
|
|
205
207
|
"./functions/image/renderBankCard": "./dist/functions/image/renderBankCard.js",
|
|
206
208
|
"./functions/image/renderBusinessLicense": "./dist/functions/image/renderBusinessLicense.js",
|
|
207
209
|
"./functions/image/renderDrivingLicense": "./dist/functions/image/renderDrivingLicense.js",
|
|
@@ -427,6 +429,7 @@
|
|
|
427
429
|
"./types/android-build": "./types/android-build.d.ts",
|
|
428
430
|
"./types/assets": "./types/assets.d.ts",
|
|
429
431
|
"./types/auth": "./types/auth.d.ts",
|
|
432
|
+
"./types/chat-more-page-config": "./types/chat-more-page-config.d.ts",
|
|
430
433
|
"./types/chat-shell-tab-config": "./types/chat-shell-tab-config.d.ts",
|
|
431
434
|
"./types/checkin-config": "./types/checkin-config.d.ts",
|
|
432
435
|
"./types/cloud-disk-config": "./types/cloud-disk-config.d.ts",
|
package/references/browser.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { WorkerConstructor } from './worker.d'
|
|
|
7
7
|
import type { Document, HTMLElement, Element, HTMLImageElement, CSSStyleDeclaration } from './dom.d'
|
|
8
8
|
import type { IDBFactory } from './indexeddb.d'
|
|
9
9
|
import type { Blob, BlobPart, BlobPropertyBag, MediaSource, ReadableStream } from './blob.d'
|
|
10
|
+
import type { ImageBitmap } from './dom.d'
|
|
10
11
|
import type { TextDecoderConstructor, TextEncoderConstructor } from './encoding.d'
|
|
11
12
|
import type { Location } from './location.d'
|
|
12
13
|
import type { ArrayBufferConstructor, Uint8ArrayConstructor, DataViewConstructor } from './arraybuffer.d'
|
|
@@ -88,6 +89,12 @@ export interface Window {
|
|
|
88
89
|
Image: {
|
|
89
90
|
new (width?: number, height?: number): HTMLImageElement
|
|
90
91
|
}
|
|
92
|
+
|
|
93
|
+
/** 解码图片为 ImageBitmap(透明 PNG 需 premultiplyAlpha: 'none' 避免黑底) */
|
|
94
|
+
createImageBitmap?: (
|
|
95
|
+
image: File,
|
|
96
|
+
options?: { premultiplyAlpha?: 'none' | 'premultiply' | 'default' }
|
|
97
|
+
) => Promise<ImageBitmap>
|
|
91
98
|
|
|
92
99
|
// ArrayBuffer API
|
|
93
100
|
ArrayBuffer: ArrayBufferConstructor
|
package/references/dom.d.ts
CHANGED
|
@@ -110,14 +110,37 @@ export interface FileList {
|
|
|
110
110
|
[index: number]: File
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
export interface ImageBitmap {
|
|
114
|
+
readonly width: number
|
|
115
|
+
readonly height: number
|
|
116
|
+
close(): void
|
|
117
|
+
}
|
|
118
|
+
|
|
113
119
|
export interface CanvasRenderingContext2D {
|
|
114
|
-
|
|
120
|
+
fillStyle: string
|
|
121
|
+
globalCompositeOperation: string
|
|
122
|
+
drawImage(
|
|
123
|
+
image: HTMLImageElement | ImageBitmap,
|
|
124
|
+
dx: number,
|
|
125
|
+
dy: number,
|
|
126
|
+
dWidth: number,
|
|
127
|
+
dHeight: number
|
|
128
|
+
): void
|
|
129
|
+
fillRect(x: number, y: number, w: number, h: number): void
|
|
130
|
+
clearRect(x: number, y: number, w: number, h: number): void
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface CanvasRenderingContext2DSettings {
|
|
134
|
+
alpha?: boolean
|
|
115
135
|
}
|
|
116
136
|
|
|
117
137
|
export interface HTMLCanvasElement extends HTMLElement {
|
|
118
138
|
width: number
|
|
119
139
|
height: number
|
|
120
|
-
getContext(
|
|
140
|
+
getContext(
|
|
141
|
+
contextId: '2d',
|
|
142
|
+
options?: CanvasRenderingContext2DSettings
|
|
143
|
+
): CanvasRenderingContext2D | null
|
|
121
144
|
toBlob(callback: (blob: Blob | null) => void, type?: string, quality?: number): void
|
|
122
145
|
}
|
|
123
146
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Chat「更多」页入口(page-config displays.more.entries) */
|
|
2
|
+
export interface ChatMorePageEntry {
|
|
3
|
+
key: string
|
|
4
|
+
label: string
|
|
5
|
+
description?: string
|
|
6
|
+
/** iconfont 名(不含 icon- 前缀) */
|
|
7
|
+
icon?: string
|
|
8
|
+
route?: string
|
|
9
|
+
routeName?: string
|
|
10
|
+
/** 角标文案,如 Hot */
|
|
11
|
+
badge?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ChatMorePageDisplaysConfig {
|
|
15
|
+
entries?: ChatMorePageEntry[]
|
|
16
|
+
}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { getImageDimensions } from './getImageDimensions';
|
|
2
|
-
export async function compressToTargetSize(file, options = {}, deps) {
|
|
3
|
-
const { targetSize = 30 * 1024, maxIterations = 30, mimeType = 'image/jpeg' } = options;
|
|
4
|
-
if (file.size <= targetSize) {
|
|
5
|
-
return file;
|
|
6
|
-
}
|
|
7
|
-
const dimensions = await getImageDimensions(file, {
|
|
8
|
-
Image: deps.Image,
|
|
9
|
-
createObjectURL: deps.createObjectURL
|
|
10
|
-
});
|
|
11
|
-
let currentWidth = dimensions.width;
|
|
12
|
-
let currentHeight = dimensions.height;
|
|
13
|
-
let currentQuality = 0.9;
|
|
14
|
-
let iteration = 0;
|
|
15
|
-
async function attemptCompress() {
|
|
16
|
-
iteration++;
|
|
17
|
-
if (iteration > maxIterations) {
|
|
18
|
-
throw new Error(`压缩失败:达到最大尝试次数(${maxIterations}),仍未达到目标大小`);
|
|
19
|
-
}
|
|
20
|
-
const result = await compressImage(file, {
|
|
21
|
-
quality: currentQuality,
|
|
22
|
-
maxWidth: currentWidth,
|
|
23
|
-
maxHeight: currentHeight,
|
|
24
|
-
mimeType
|
|
25
|
-
}, deps);
|
|
26
|
-
if (result.size <= targetSize) {
|
|
27
|
-
return result;
|
|
28
|
-
}
|
|
29
|
-
const ratio = targetSize / result.size;
|
|
30
|
-
if (ratio < 0.05) {
|
|
31
|
-
currentWidth = Math.max(50, Math.floor(currentWidth * 0.5));
|
|
32
|
-
currentHeight = Math.max(50, Math.floor(currentHeight * 0.5));
|
|
33
|
-
currentQuality = Math.max(0.05, currentQuality * 0.5);
|
|
34
|
-
}
|
|
35
|
-
else if (ratio < 0.15) {
|
|
36
|
-
currentWidth = Math.max(80, Math.floor(currentWidth * 0.6));
|
|
37
|
-
currentHeight = Math.max(80, Math.floor(currentHeight * 0.6));
|
|
38
|
-
currentQuality = Math.max(0.08, currentQuality * 0.6);
|
|
39
|
-
}
|
|
40
|
-
else if (ratio < 0.3) {
|
|
41
|
-
currentWidth = Math.max(100, Math.floor(currentWidth * 0.7));
|
|
42
|
-
currentHeight = Math.max(100, Math.floor(currentHeight * 0.7));
|
|
43
|
-
currentQuality = Math.max(0.1, currentQuality * 0.8);
|
|
44
|
-
}
|
|
45
|
-
else if (ratio < 0.7) {
|
|
46
|
-
currentWidth = Math.max(100, Math.floor(currentWidth * 0.85));
|
|
47
|
-
currentHeight = Math.max(100, Math.floor(currentHeight * 0.85));
|
|
48
|
-
currentQuality = Math.max(0.1, currentQuality * 0.85);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
currentQuality = Math.max(0.1, currentQuality * 0.9);
|
|
52
|
-
}
|
|
53
|
-
return attemptCompress();
|
|
54
|
-
}
|
|
55
|
-
return attemptCompress();
|
|
56
|
-
}
|
|
57
|
-
async function compressImage(file, options, deps) {
|
|
58
|
-
const { quality, maxWidth, maxHeight, mimeType } = options;
|
|
59
|
-
return new Promise((resolve, reject) => {
|
|
60
|
-
const img = new deps.Image();
|
|
61
|
-
img.onload = () => {
|
|
62
|
-
const canvas = deps.createElement('canvas');
|
|
63
|
-
let width = img.naturalWidth;
|
|
64
|
-
let height = img.naturalHeight;
|
|
65
|
-
if (width > maxWidth || height > maxHeight) {
|
|
66
|
-
const ratio = Math.min(maxWidth / width, maxHeight / height);
|
|
67
|
-
width = Math.floor(width * ratio);
|
|
68
|
-
height = Math.floor(height * ratio);
|
|
69
|
-
}
|
|
70
|
-
canvas.width = width;
|
|
71
|
-
canvas.height = height;
|
|
72
|
-
const ctx = canvas.getContext('2d');
|
|
73
|
-
if (!ctx) {
|
|
74
|
-
reject(new Error('无法创建canvas上下文'));
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
ctx.drawImage(img, 0, 0, width, height);
|
|
78
|
-
canvas.toBlob((blob) => {
|
|
79
|
-
if (!blob) {
|
|
80
|
-
reject(new Error('图片压缩失败'));
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
const newFile = new deps.File([blob], file.name, {
|
|
84
|
-
type: mimeType,
|
|
85
|
-
lastModified: Date.now()
|
|
86
|
-
});
|
|
87
|
-
resolve(newFile);
|
|
88
|
-
}, mimeType, quality);
|
|
89
|
-
};
|
|
90
|
-
img.onerror = () => {
|
|
91
|
-
reject(new Error('图片加载失败'));
|
|
92
|
-
};
|
|
93
|
-
img.src = deps.createObjectURL(file);
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
//# sourceMappingURL=compressToTargetSize.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compressToTargetSize.js","sourceRoot":"","sources":["../../../src/functions/image/compressToTargetSize.ts"],"names":[],"mappings":"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"}
|