zcw-shared 2.18.0 → 2.20.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/im/imBubbleSelectionClipboard.d.ts +9 -0
- package/dist/functions/im/imBubbleSelectionClipboard.js +166 -0
- package/dist/functions/im/imBubbleSelectionClipboard.js.map +1 -0
- 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 +20 -16
- 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,9 @@
|
|
|
1
|
+
import type { ImRichContentSegment, MaterializeImRichHtmlOptions } from './imRichContentHtml';
|
|
2
|
+
export type BubbleClipboardFragment = {
|
|
3
|
+
childNodes: ArrayLike<unknown>;
|
|
4
|
+
};
|
|
5
|
+
export declare function parseBubbleClipboardFragment(fragment: BubbleClipboardFragment): ImRichContentSegment[];
|
|
6
|
+
export declare function writeBubbleSelectionClipboard(fragment: BubbleClipboardFragment, options?: MaterializeImRichHtmlOptions): {
|
|
7
|
+
html: string;
|
|
8
|
+
plain: string;
|
|
9
|
+
} | null;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { materializeImRichHtmlToRestorablePlainText } from './imRichClipboardPlain';
|
|
2
|
+
import { IM_RICH_EMOJI_ATTR, IM_RICH_FILE_ATTR, IM_RICH_FILE_PATH_ATTR, IM_RICH_LABEL_ATTR, IM_RICH_MENTION_ATTR, IM_RICH_USER_ID_ATTR, sanitizeImRichContentHtml, serializeImRichContentSegments, } from './imRichContentHtml';
|
|
3
|
+
const INLINE_IMAGE_WRAP_ATTR = 'data-cw-inline-image-wrap';
|
|
4
|
+
const PREVIEW_SRC_ATTR = 'data-preview-src';
|
|
5
|
+
const IMAGE_NAME_ATTR = 'data-image-name';
|
|
6
|
+
const NATURAL_WIDTH_ATTR = 'data-natural-width';
|
|
7
|
+
const NATURAL_HEIGHT_ATTR = 'data-natural-height';
|
|
8
|
+
function appendTextSegment(segments, text) {
|
|
9
|
+
if (!text)
|
|
10
|
+
return;
|
|
11
|
+
const last = segments[segments.length - 1];
|
|
12
|
+
if (last?.type === 'text') {
|
|
13
|
+
last.text += text;
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
segments.push({ type: 'text', text });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function isElement(node) {
|
|
20
|
+
return node.nodeType === 1;
|
|
21
|
+
}
|
|
22
|
+
function normalizeBubbleChipVisibleText(el) {
|
|
23
|
+
return (el.textContent ?? '').replace(/\s+/g, '');
|
|
24
|
+
}
|
|
25
|
+
function isCompleteFileChipInFragment(el) {
|
|
26
|
+
const label = el.getAttribute?.(IM_RICH_LABEL_ATTR)?.trim() ?? '';
|
|
27
|
+
const path = el.getAttribute?.(IM_RICH_FILE_PATH_ATTR)?.trim() ?? '';
|
|
28
|
+
const fullLabel = label || path.split(/[/\\]/).pop() || path;
|
|
29
|
+
if (!fullLabel)
|
|
30
|
+
return false;
|
|
31
|
+
const visible = normalizeBubbleChipVisibleText(el);
|
|
32
|
+
if (!visible)
|
|
33
|
+
return false;
|
|
34
|
+
if (visible === fullLabel)
|
|
35
|
+
return true;
|
|
36
|
+
if (!visible.endsWith(fullLabel))
|
|
37
|
+
return false;
|
|
38
|
+
const prefix = visible.slice(0, visible.length - fullLabel.length);
|
|
39
|
+
return prefix.length <= 2;
|
|
40
|
+
}
|
|
41
|
+
function isCompleteMentionChipInFragment(el) {
|
|
42
|
+
const label = el.getAttribute?.(IM_RICH_LABEL_ATTR)?.trim() ?? '';
|
|
43
|
+
const userId = el.getAttribute?.(IM_RICH_USER_ID_ATTR)?.trim() ?? '';
|
|
44
|
+
const expected = label || userId;
|
|
45
|
+
if (!expected)
|
|
46
|
+
return false;
|
|
47
|
+
const visible = normalizeBubbleChipVisibleText(el).replace(/^@+/, '');
|
|
48
|
+
return visible === expected;
|
|
49
|
+
}
|
|
50
|
+
function readFileSegment(el) {
|
|
51
|
+
if (!el.hasAttribute?.(IM_RICH_FILE_ATTR))
|
|
52
|
+
return null;
|
|
53
|
+
if (!isCompleteFileChipInFragment(el))
|
|
54
|
+
return null;
|
|
55
|
+
const path = el.getAttribute?.(IM_RICH_FILE_PATH_ATTR)?.trim() ?? '';
|
|
56
|
+
const label = el.getAttribute?.(IM_RICH_LABEL_ATTR)?.trim() ?? '';
|
|
57
|
+
if (!path && !label)
|
|
58
|
+
return null;
|
|
59
|
+
return {
|
|
60
|
+
type: 'file',
|
|
61
|
+
path,
|
|
62
|
+
label: label || path.split(/[/\\]/).pop() || path,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function readImageSegment(el) {
|
|
66
|
+
if (!el.hasAttribute?.(INLINE_IMAGE_WRAP_ATTR))
|
|
67
|
+
return null;
|
|
68
|
+
const url = el.getAttribute?.(PREVIEW_SRC_ATTR)?.trim() ?? '';
|
|
69
|
+
if (!url)
|
|
70
|
+
return null;
|
|
71
|
+
const alt = el.getAttribute?.(IMAGE_NAME_ATTR)?.trim() || '图片';
|
|
72
|
+
const w = Number.parseInt(el.getAttribute?.(NATURAL_WIDTH_ATTR) ?? '', 10);
|
|
73
|
+
const h = Number.parseInt(el.getAttribute?.(NATURAL_HEIGHT_ATTR) ?? '', 10);
|
|
74
|
+
return {
|
|
75
|
+
type: 'image',
|
|
76
|
+
url,
|
|
77
|
+
alt,
|
|
78
|
+
...(Number.isFinite(w) && w > 0 && Number.isFinite(h) && h > 0
|
|
79
|
+
? { width: w, height: h }
|
|
80
|
+
: {}),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function readMentionSegment(el) {
|
|
84
|
+
if (!el.hasAttribute?.(IM_RICH_MENTION_ATTR))
|
|
85
|
+
return null;
|
|
86
|
+
if (!isCompleteMentionChipInFragment(el))
|
|
87
|
+
return null;
|
|
88
|
+
const userId = el.getAttribute?.(IM_RICH_USER_ID_ATTR)?.trim() ?? '';
|
|
89
|
+
const label = el.getAttribute?.(IM_RICH_LABEL_ATTR)?.trim() ?? '';
|
|
90
|
+
if (!userId)
|
|
91
|
+
return null;
|
|
92
|
+
return { type: 'mention', userId, label: label || userId };
|
|
93
|
+
}
|
|
94
|
+
function readEmojiSegment(el) {
|
|
95
|
+
if (el.tagName !== 'IMG')
|
|
96
|
+
return null;
|
|
97
|
+
const glyph = el.getAttribute?.(IM_RICH_EMOJI_ATTR)?.trim() ||
|
|
98
|
+
el.getAttribute?.('alt')?.trim() ||
|
|
99
|
+
'';
|
|
100
|
+
if (!glyph)
|
|
101
|
+
return null;
|
|
102
|
+
const src = el.getAttribute?.('src')?.trim() ?? '';
|
|
103
|
+
return { type: 'emoji', glyph, ...(src ? { src } : {}) };
|
|
104
|
+
}
|
|
105
|
+
function isInlineEmojiImg(el) {
|
|
106
|
+
return el.tagName === 'IMG' && !!el.hasAttribute?.(IM_RICH_EMOJI_ATTR);
|
|
107
|
+
}
|
|
108
|
+
function asClipboardNode(node) {
|
|
109
|
+
return node;
|
|
110
|
+
}
|
|
111
|
+
function walkBubbleClipboardNode(node, segments) {
|
|
112
|
+
if (node.nodeType === 3) {
|
|
113
|
+
appendTextSegment(segments, node.textContent ?? '');
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (!isElement(node))
|
|
117
|
+
return;
|
|
118
|
+
const file = readFileSegment(node);
|
|
119
|
+
if (file) {
|
|
120
|
+
segments.push(file);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const image = readImageSegment(node);
|
|
124
|
+
if (image) {
|
|
125
|
+
segments.push(image);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const mention = readMentionSegment(node);
|
|
129
|
+
if (mention) {
|
|
130
|
+
segments.push(mention);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (isInlineEmojiImg(node)) {
|
|
134
|
+
const emoji = readEmojiSegment(node);
|
|
135
|
+
if (emoji) {
|
|
136
|
+
segments.push(emoji);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const children = node.childNodes;
|
|
141
|
+
if (!children)
|
|
142
|
+
return;
|
|
143
|
+
for (let i = 0; i < children.length; i++) {
|
|
144
|
+
walkBubbleClipboardNode(asClipboardNode(children[i]), segments);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
export function parseBubbleClipboardFragment(fragment) {
|
|
148
|
+
const segments = [];
|
|
149
|
+
for (let i = 0; i < fragment.childNodes.length; i++) {
|
|
150
|
+
walkBubbleClipboardNode(asClipboardNode(fragment.childNodes[i]), segments);
|
|
151
|
+
}
|
|
152
|
+
return segments.filter((seg) => seg.type !== 'text' || seg.text.length > 0);
|
|
153
|
+
}
|
|
154
|
+
export function writeBubbleSelectionClipboard(fragment, options) {
|
|
155
|
+
const segments = parseBubbleClipboardFragment(fragment);
|
|
156
|
+
if (segments.length === 0)
|
|
157
|
+
return null;
|
|
158
|
+
if (segments.every((seg) => seg.type === 'text' && !seg.text.trim())) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
const wireHtml = serializeImRichContentSegments(segments);
|
|
162
|
+
const html = sanitizeImRichContentHtml(wireHtml);
|
|
163
|
+
const plain = materializeImRichHtmlToRestorablePlainText(wireHtml, options);
|
|
164
|
+
return { html, plain };
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=imBubbleSelectionClipboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imBubbleSelectionClipboard.js","sourceRoot":"","sources":["../../../src/functions/im/imBubbleSelectionClipboard.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.20.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"references",
|
|
6
6
|
"dist",
|
|
@@ -12,6 +12,19 @@
|
|
|
12
12
|
"license": "ISC",
|
|
13
13
|
"type": "module",
|
|
14
14
|
"description": "",
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc -p tsconfig.build.json && tsx scripts/generate-exports.ts",
|
|
17
|
+
"publish:patch": "npx tsx scripts/publish.ts patch",
|
|
18
|
+
"publish:minor": "npx tsx scripts/publish.ts minor",
|
|
19
|
+
"publish:major": "npx tsx scripts/publish.ts major",
|
|
20
|
+
"publish:prerelease": "npx tsx scripts/publish.ts prerelease",
|
|
21
|
+
"docs:dev": "vitepress dev docs",
|
|
22
|
+
"docs:build": "NODE_OPTIONS=--max-old-space-size=4096 vitepress build docs",
|
|
23
|
+
"docs:preview": "vitepress preview docs",
|
|
24
|
+
"deploy:cos:build": "NODE_OPTIONS=--max-old-space-size=4096 vitepress build docs",
|
|
25
|
+
"deploy:tcb": "npx tsx scripts/deploy-tcb.ts",
|
|
26
|
+
"deploy:cos": "npx tsx scripts/deploy-cos.ts"
|
|
27
|
+
},
|
|
15
28
|
"dependencies": {
|
|
16
29
|
"zod": "^3.23.8"
|
|
17
30
|
},
|
|
@@ -115,6 +128,7 @@
|
|
|
115
128
|
"./functions/browser/isMobile": "./dist/functions/browser/isMobile.js",
|
|
116
129
|
"./functions/browser/isWeChat": "./dist/functions/browser/isWeChat.js",
|
|
117
130
|
"./functions/browser/shortcutModKeyHint": "./dist/functions/browser/shortcutModKeyHint.js",
|
|
131
|
+
"./functions/chat/chatMorePageConfig": "./dist/functions/chat/chatMorePageConfig.js",
|
|
118
132
|
"./functions/chat/chatShellTabConfig": "./dist/functions/chat/chatShellTabConfig.js",
|
|
119
133
|
"./functions/chat/chatShellTabEditor": "./dist/functions/chat/chatShellTabEditor.js",
|
|
120
134
|
"./functions/code/getLanguageFromExtension": "./dist/functions/code/getLanguageFromExtension.js",
|
|
@@ -190,10 +204,11 @@
|
|
|
190
204
|
"./functions/im/formatImChatConversationListTime": "./dist/functions/im/formatImChatConversationListTime.js",
|
|
191
205
|
"./functions/im/forwardBundlePayload": "./dist/functions/im/forwardBundlePayload.js",
|
|
192
206
|
"./functions/im/getActiveMentionQuery": "./dist/functions/im/getActiveMentionQuery.js",
|
|
207
|
+
"./functions/im/imBubbleSelectionClipboard": "./dist/functions/im/imBubbleSelectionClipboard.js",
|
|
193
208
|
"./functions/im/imRichClipboardPlain": "./dist/functions/im/imRichClipboardPlain.js",
|
|
194
209
|
"./functions/im/imRichContentHtml": "./dist/functions/im/imRichContentHtml.js",
|
|
195
|
-
"./functions/image/
|
|
196
|
-
"./functions/image/
|
|
210
|
+
"./functions/image/compressImageToWidthJpgOrWebp": "./dist/functions/image/compressImageToWidthJpgOrWebp.js",
|
|
211
|
+
"./functions/image/compressToTargetSizeJpgOrWebp": "./dist/functions/image/compressToTargetSizeJpgOrWebp.js",
|
|
197
212
|
"./functions/image/generateFavIcon": "./dist/functions/image/generateFavIcon.js",
|
|
198
213
|
"./functions/image/generateMacIcons": "./dist/functions/image/generateMacIcons.js",
|
|
199
214
|
"./functions/image/generateMacTrayIcon": "./dist/functions/image/generateMacTrayIcon.js",
|
|
@@ -202,6 +217,7 @@
|
|
|
202
217
|
"./functions/image/generatePwaIcons": "./dist/functions/image/generatePwaIcons.js",
|
|
203
218
|
"./functions/image/generateRoundedImage": "./dist/functions/image/generateRoundedImage.js",
|
|
204
219
|
"./functions/image/getImageDimensions": "./dist/functions/image/getImageDimensions.js",
|
|
220
|
+
"./functions/image/imageJpgOrWebpExport": "./dist/functions/image/imageJpgOrWebpExport.js",
|
|
205
221
|
"./functions/image/renderBankCard": "./dist/functions/image/renderBankCard.js",
|
|
206
222
|
"./functions/image/renderBusinessLicense": "./dist/functions/image/renderBusinessLicense.js",
|
|
207
223
|
"./functions/image/renderDrivingLicense": "./dist/functions/image/renderDrivingLicense.js",
|
|
@@ -427,6 +443,7 @@
|
|
|
427
443
|
"./types/android-build": "./types/android-build.d.ts",
|
|
428
444
|
"./types/assets": "./types/assets.d.ts",
|
|
429
445
|
"./types/auth": "./types/auth.d.ts",
|
|
446
|
+
"./types/chat-more-page-config": "./types/chat-more-page-config.d.ts",
|
|
430
447
|
"./types/chat-shell-tab-config": "./types/chat-shell-tab-config.d.ts",
|
|
431
448
|
"./types/checkin-config": "./types/checkin-config.d.ts",
|
|
432
449
|
"./types/cloud-disk-config": "./types/cloud-disk-config.d.ts",
|
|
@@ -470,18 +487,5 @@
|
|
|
470
487
|
"./types/video": "./types/video.d.ts",
|
|
471
488
|
"./types/vue": "./types/vue.d.ts",
|
|
472
489
|
"./types/worker": "./types/worker.d.ts"
|
|
473
|
-
},
|
|
474
|
-
"scripts": {
|
|
475
|
-
"build": "tsc -p tsconfig.build.json && tsx scripts/generate-exports.ts",
|
|
476
|
-
"publish:patch": "npx tsx scripts/publish.ts patch",
|
|
477
|
-
"publish:minor": "npx tsx scripts/publish.ts minor",
|
|
478
|
-
"publish:major": "npx tsx scripts/publish.ts major",
|
|
479
|
-
"publish:prerelease": "npx tsx scripts/publish.ts prerelease",
|
|
480
|
-
"docs:dev": "vitepress dev docs",
|
|
481
|
-
"docs:build": "NODE_OPTIONS=--max-old-space-size=4096 vitepress build docs",
|
|
482
|
-
"docs:preview": "vitepress preview docs",
|
|
483
|
-
"deploy:cos:build": "NODE_OPTIONS=--max-old-space-size=4096 vitepress build docs",
|
|
484
|
-
"deploy:tcb": "npx tsx scripts/deploy-tcb.ts",
|
|
485
|
-
"deploy:cos": "npx tsx scripts/deploy-cos.ts"
|
|
486
490
|
}
|
|
487
491
|
}
|
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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"}
|