vue3-image-compressor 1.0.4 → 1.0.7
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/README.md +6 -0
- package/dist/assets/imageWorker-Qv3pCULy.js +1042 -0
- package/dist/codecs/avif/enc/avif_enc.js +16 -0
- package/dist/codecs/avif/enc/avif_enc.wasm +0 -0
- package/dist/codecs/mozjpeg/enc/mozjpeg_enc.js +16 -0
- package/dist/codecs/mozjpeg/enc/mozjpeg_enc.wasm +0 -0
- package/dist/codecs/webp/dec/webp_dec.js +16 -0
- package/dist/codecs/webp/dec/webp_dec.wasm +0 -0
- package/dist/codecs/webp/enc/webp_enc.js +16 -0
- package/dist/codecs/webp/enc/webp_enc.wasm +0 -0
- package/dist/components/ImageCompressor.vue.d.ts +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/style.css +1 -1
- package/dist/utils/compressFile.d.ts +46 -0
- package/dist/vue-image-compressor.js +508 -382
- package/dist/vue-image-compressor.umd.cjs +1 -1
- package/dist/workers/utils/emscripten.d.ts +15 -1
- package/package.json +2 -1
- package/src/components/ImageCompressor.vue +9 -15
- package/src/composables/useWorker.ts +61 -7
- package/src/index.ts +6 -0
- package/src/types/mozjpeg.d.ts +38 -0
- package/src/utils/compressFile.ts +201 -0
- package/src/utils/file.ts +2 -1
- package/src/workers/imageWorker.ts +126 -30
- package/src/workers/utils/emscripten.ts +12 -1
- package/dist/assets/imageWorker-DyeUTFOy.js +0 -67
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ref as
|
|
2
|
-
const
|
|
1
|
+
import { ref as y, onUnmounted as Y, computed as R, defineComponent as Z, openBlock as z, createElementBlock as k, createElementVNode as E, withModifiers as J, renderSlot as S, toDisplayString as D, unref as v, createCommentVNode as I, withDirectives as ee, isRef as te, Fragment as oe, renderList as re, vModelSelect as ne, createTextVNode as se } from "vue";
|
|
2
|
+
const G = {
|
|
3
3
|
mozJPEG: {
|
|
4
4
|
label: "MozJPEG",
|
|
5
5
|
mimeType: "image/jpeg",
|
|
@@ -50,7 +50,7 @@ const L = {
|
|
|
50
50
|
mimeType: "image/webp2",
|
|
51
51
|
extension: "wp2"
|
|
52
52
|
}
|
|
53
|
-
},
|
|
53
|
+
}, N = {
|
|
54
54
|
mozJPEG: {
|
|
55
55
|
quality: 75,
|
|
56
56
|
baseline: !1,
|
|
@@ -124,537 +124,663 @@ const L = {
|
|
|
124
124
|
wp2: {
|
|
125
125
|
quality: 75
|
|
126
126
|
}
|
|
127
|
-
},
|
|
128
|
-
async function
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
const
|
|
132
|
-
return
|
|
127
|
+
}, ae = Object.keys(G);
|
|
128
|
+
async function Q(r) {
|
|
129
|
+
const o = await createImageBitmap(r), n = document.createElement("canvas");
|
|
130
|
+
n.width = o.width, n.height = o.height;
|
|
131
|
+
const t = n.getContext("2d");
|
|
132
|
+
return t.drawImage(o, 0, 0), t.getImageData(0, 0, n.width, n.height);
|
|
133
133
|
}
|
|
134
|
-
async function
|
|
135
|
-
const
|
|
136
|
-
return
|
|
137
|
-
|
|
138
|
-
(
|
|
139
|
-
|
|
140
|
-
|
|
134
|
+
async function B(r, o, n) {
|
|
135
|
+
const t = document.createElement("canvas");
|
|
136
|
+
return t.width = r.width, t.height = r.height, t.getContext("2d").putImageData(r, 0, 0), new Promise((s) => {
|
|
137
|
+
t.toBlob(
|
|
138
|
+
(a) => s(a),
|
|
139
|
+
o,
|
|
140
|
+
n
|
|
141
141
|
);
|
|
142
142
|
});
|
|
143
143
|
}
|
|
144
|
-
function
|
|
145
|
-
return new Promise((
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
},
|
|
144
|
+
function Le(r) {
|
|
145
|
+
return new Promise((o, n) => {
|
|
146
|
+
const t = new Image();
|
|
147
|
+
t.onload = () => {
|
|
148
|
+
o({ width: t.width, height: t.height }), URL.revokeObjectURL(t.src);
|
|
149
|
+
}, t.onerror = n, t.src = URL.createObjectURL(r);
|
|
150
150
|
});
|
|
151
151
|
}
|
|
152
|
-
async function
|
|
153
|
-
const
|
|
154
|
-
return
|
|
152
|
+
async function ie(r) {
|
|
153
|
+
const o = new Uint8Array(await r.slice(0, 4).arrayBuffer());
|
|
154
|
+
return o[0] === 137 && o[1] === 80 ? "image/png" : o[0] === 255 && o[1] === 216 ? "image/jpeg" : o[0] === 71 && o[1] === 73 ? "image/gif" : o[0] === 82 && o[1] === 73 ? "image/webp" : o[0] === 0 && o[1] === 0 ? "image/avif" : r.type || "image/jpeg";
|
|
155
155
|
}
|
|
156
|
-
function
|
|
157
|
-
return new Promise((
|
|
158
|
-
const
|
|
159
|
-
|
|
156
|
+
function le(r) {
|
|
157
|
+
return new Promise((o) => {
|
|
158
|
+
const n = new Image();
|
|
159
|
+
n.onload = () => o(!0), n.onerror = () => o(!1), n.src = `data:${r};base64,`;
|
|
160
160
|
});
|
|
161
161
|
}
|
|
162
|
-
function
|
|
163
|
-
return new File([
|
|
162
|
+
function H(r, o, n) {
|
|
163
|
+
return new File([r], o, { type: n });
|
|
164
164
|
}
|
|
165
|
-
function $(
|
|
166
|
-
if (
|
|
167
|
-
const
|
|
168
|
-
return parseFloat((
|
|
165
|
+
function $(r, o = 2) {
|
|
166
|
+
if (r === 0) return "0 Bytes";
|
|
167
|
+
const n = 1024, t = o < 0 ? 0 : o, e = ["Bytes", "KB", "MB", "GB"], s = Math.floor(Math.log(r) / Math.log(n));
|
|
168
|
+
return parseFloat((r / Math.pow(n, s)).toFixed(t)) + " " + e[s];
|
|
169
169
|
}
|
|
170
|
-
function
|
|
171
|
-
|
|
170
|
+
function K(r, o) {
|
|
171
|
+
if (r === 0) return 0;
|
|
172
|
+
const n = Math.round((r - o) / r * 100);
|
|
173
|
+
return Math.max(0, n);
|
|
172
174
|
}
|
|
173
|
-
function
|
|
174
|
-
return `${
|
|
175
|
+
function X(r, o) {
|
|
176
|
+
return `${r.replace(/\.[^.]+$/, "")}_compressed.${o}`;
|
|
175
177
|
}
|
|
176
|
-
function V(
|
|
177
|
-
return URL.createObjectURL(
|
|
178
|
+
function V(r) {
|
|
179
|
+
return URL.createObjectURL(r);
|
|
178
180
|
}
|
|
179
|
-
function
|
|
180
|
-
URL.revokeObjectURL(
|
|
181
|
+
function ce(r) {
|
|
182
|
+
URL.revokeObjectURL(r);
|
|
181
183
|
}
|
|
182
|
-
const
|
|
183
|
-
function
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
184
|
+
const ue = 1e4;
|
|
185
|
+
function de(r) {
|
|
186
|
+
let o = 0;
|
|
187
|
+
const n = /* @__PURE__ */ new Map();
|
|
188
|
+
r.addEventListener("message", (e) => {
|
|
189
|
+
const { id: s, result: a, error: p } = e.data, u = n.get(s);
|
|
190
|
+
u && (n.delete(s), p ? u.reject(new Error(p)) : u.resolve(a));
|
|
191
|
+
}), r.addEventListener("error", (e) => {
|
|
192
|
+
console.error("Worker error:", {
|
|
193
|
+
message: e.message,
|
|
194
|
+
filename: e.filename,
|
|
195
|
+
lineno: e.lineno,
|
|
196
|
+
colno: e.colno,
|
|
197
|
+
error: e.error
|
|
198
|
+
}), n.forEach((s) => s.reject(e)), n.clear();
|
|
199
|
+
});
|
|
200
|
+
function t(e, ...s) {
|
|
201
|
+
return new Promise((a, p) => {
|
|
202
|
+
const u = ++o;
|
|
203
|
+
n.set(u, { resolve: a, reject: p }), r.postMessage({ id: u, method: e, args: s });
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
avifDecode: (e) => t("avifDecode", e),
|
|
208
|
+
jxlDecode: (e) => t("jxlDecode", e),
|
|
209
|
+
qoiDecode: (e) => t("qoiDecode", e),
|
|
210
|
+
webpDecode: (e) => t("webpDecode", e),
|
|
211
|
+
wp2Decode: (e) => t("wp2Decode", e),
|
|
212
|
+
avifEncode: (e, s) => t("avifEncode", e, s),
|
|
213
|
+
jxlEncode: (e, s) => t("jxlEncode", e, s),
|
|
214
|
+
mozjpegEncode: (e, s) => t("mozjpegEncode", e, s),
|
|
215
|
+
oxipngEncode: (e, s) => t("oxipngEncode", e, s),
|
|
216
|
+
qoiEncode: (e, s) => t("qoiEncode", e, s),
|
|
217
|
+
webpEncode: (e, s) => t("webpEncode", e, s),
|
|
218
|
+
wp2Encode: (e, s) => t("wp2Encode", e, s),
|
|
219
|
+
rotate: (e, s) => t("rotate", e, s),
|
|
220
|
+
quantize: (e, s) => t("quantize", e, s),
|
|
221
|
+
resize: (e, s) => t("resize", e, s)
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function pe() {
|
|
225
|
+
const r = y(!1), o = y(!1), n = y(null);
|
|
226
|
+
let t = null, e = null;
|
|
227
|
+
function s() {
|
|
228
|
+
if (!t)
|
|
188
229
|
try {
|
|
189
|
-
|
|
230
|
+
o.value = !0, t = new Worker(
|
|
190
231
|
new URL(
|
|
191
232
|
/* @vite-ignore */
|
|
192
|
-
"/assets/imageWorker-
|
|
233
|
+
"/assets/imageWorker-Qv3pCULy.js",
|
|
193
234
|
import.meta.url
|
|
194
235
|
),
|
|
195
236
|
{ type: "module" }
|
|
196
|
-
),
|
|
197
|
-
} catch (
|
|
198
|
-
|
|
237
|
+
), r.value = !0, n.value = null;
|
|
238
|
+
} catch (b) {
|
|
239
|
+
n.value = b instanceof Error ? b : new Error("Failed to start worker"), console.error("Worker start failed:", b);
|
|
199
240
|
} finally {
|
|
200
|
-
|
|
241
|
+
o.value = !1;
|
|
201
242
|
}
|
|
202
243
|
}
|
|
203
|
-
function
|
|
204
|
-
|
|
244
|
+
function a() {
|
|
245
|
+
e && (clearTimeout(e), e = null), t && (t.terminate(), t = null, r.value = !1);
|
|
205
246
|
}
|
|
206
|
-
function
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
},
|
|
247
|
+
function p() {
|
|
248
|
+
e && clearTimeout(e), e = window.setTimeout(() => {
|
|
249
|
+
a();
|
|
250
|
+
}, ue);
|
|
210
251
|
}
|
|
211
|
-
async function
|
|
212
|
-
if (
|
|
252
|
+
async function u() {
|
|
253
|
+
if (t || s(), !t)
|
|
213
254
|
throw new Error("Worker failed to initialize");
|
|
214
|
-
return
|
|
255
|
+
return de(t);
|
|
215
256
|
}
|
|
216
|
-
async function
|
|
217
|
-
if (
|
|
257
|
+
async function h(b, O) {
|
|
258
|
+
if (b.aborted)
|
|
218
259
|
throw new DOMException("AbortError", "AbortError");
|
|
219
|
-
return clearTimeout(
|
|
220
|
-
const
|
|
221
|
-
|
|
260
|
+
return clearTimeout(e), new Promise((q, P) => {
|
|
261
|
+
const T = () => {
|
|
262
|
+
a(), P(new DOMException("AbortError", "AbortError"));
|
|
222
263
|
};
|
|
223
|
-
|
|
224
|
-
|
|
264
|
+
b.addEventListener("abort", T), O().then(q).catch(P).finally(() => {
|
|
265
|
+
b.removeEventListener("abort", T), p();
|
|
225
266
|
});
|
|
226
267
|
});
|
|
227
268
|
}
|
|
228
|
-
return
|
|
229
|
-
|
|
269
|
+
return Y(() => {
|
|
270
|
+
a();
|
|
230
271
|
}), {
|
|
231
|
-
isReady:
|
|
232
|
-
isLoading:
|
|
233
|
-
error:
|
|
234
|
-
worker:
|
|
235
|
-
getWorkerApi:
|
|
236
|
-
executeTask:
|
|
237
|
-
terminateWorker:
|
|
272
|
+
isReady: r,
|
|
273
|
+
isLoading: o,
|
|
274
|
+
error: n,
|
|
275
|
+
worker: t,
|
|
276
|
+
getWorkerApi: u,
|
|
277
|
+
executeTask: h,
|
|
278
|
+
terminateWorker: a
|
|
238
279
|
};
|
|
239
280
|
}
|
|
240
|
-
function
|
|
241
|
-
const
|
|
242
|
-
async function
|
|
243
|
-
const
|
|
244
|
-
if (!
|
|
245
|
-
if (
|
|
246
|
-
return
|
|
247
|
-
if (
|
|
248
|
-
return
|
|
249
|
-
if (
|
|
250
|
-
return
|
|
251
|
-
if (
|
|
252
|
-
return
|
|
253
|
-
if (
|
|
254
|
-
return
|
|
281
|
+
function me() {
|
|
282
|
+
const r = y(!1), o = y(0), n = y(null), t = y(null), e = y(null), { getWorkerApi: s, executeTask: a } = pe(), p = R(() => r.value && !!e.value);
|
|
283
|
+
async function u(f, i) {
|
|
284
|
+
const l = await ie(i), d = await le(l), w = await s();
|
|
285
|
+
if (!d) {
|
|
286
|
+
if (l === "image/avif")
|
|
287
|
+
return a(f, () => w.avifDecode(i));
|
|
288
|
+
if (l === "image/webp")
|
|
289
|
+
return a(f, () => w.webpDecode(i));
|
|
290
|
+
if (l === "image/jxl")
|
|
291
|
+
return a(f, () => w.jxlDecode(i));
|
|
292
|
+
if (l === "image/webp2")
|
|
293
|
+
return a(f, () => w.wp2Decode(i));
|
|
294
|
+
if (l === "image/qoi")
|
|
295
|
+
return a(f, () => w.qoiDecode(i));
|
|
255
296
|
}
|
|
256
|
-
return
|
|
297
|
+
return Q(i);
|
|
257
298
|
}
|
|
258
|
-
async function
|
|
259
|
-
if (
|
|
260
|
-
const
|
|
261
|
-
return
|
|
262
|
-
|
|
263
|
-
() =>
|
|
299
|
+
async function h(f, i, l) {
|
|
300
|
+
if (l === 0) return i;
|
|
301
|
+
const d = await s();
|
|
302
|
+
return a(
|
|
303
|
+
f,
|
|
304
|
+
() => d.rotate(i, { rotate: l })
|
|
264
305
|
);
|
|
265
306
|
}
|
|
266
|
-
async function
|
|
267
|
-
var
|
|
268
|
-
let
|
|
269
|
-
const
|
|
270
|
-
return (
|
|
271
|
-
|
|
272
|
-
() =>
|
|
273
|
-
width:
|
|
274
|
-
height:
|
|
275
|
-
method:
|
|
276
|
-
fitMethod:
|
|
307
|
+
async function b(f, i, l) {
|
|
308
|
+
var g, x;
|
|
309
|
+
let d = i;
|
|
310
|
+
const w = await s();
|
|
311
|
+
return (g = l.resize) != null && g.enabled && (d = await a(
|
|
312
|
+
f,
|
|
313
|
+
() => w.resize(d, {
|
|
314
|
+
width: l.resize.width || d.width,
|
|
315
|
+
height: l.resize.height || d.height,
|
|
316
|
+
method: l.resize.method || "lanczos3",
|
|
317
|
+
fitMethod: l.resize.fitMethod || "stretch",
|
|
277
318
|
premultiply: !0,
|
|
278
319
|
linearRGB: !0
|
|
279
320
|
})
|
|
280
|
-
)), (
|
|
281
|
-
|
|
282
|
-
() =>
|
|
283
|
-
numColors:
|
|
284
|
-
dither:
|
|
321
|
+
)), (x = l.quantize) != null && x.enabled && (d = await a(
|
|
322
|
+
f,
|
|
323
|
+
() => w.quantize(d, {
|
|
324
|
+
numColors: l.quantize.numColors || 256,
|
|
325
|
+
dither: l.quantize.dither || 1
|
|
285
326
|
})
|
|
286
|
-
)),
|
|
327
|
+
)), d;
|
|
287
328
|
}
|
|
288
|
-
async function
|
|
289
|
-
const
|
|
290
|
-
if (
|
|
291
|
-
return (await
|
|
292
|
-
|
|
329
|
+
async function O(f, i, l) {
|
|
330
|
+
const d = await s(), w = l.encoder;
|
|
331
|
+
if (w === "browserJPEG")
|
|
332
|
+
return (await B(
|
|
333
|
+
i,
|
|
293
334
|
"image/jpeg",
|
|
294
|
-
|
|
335
|
+
l.encoderOptions.quality
|
|
295
336
|
)).arrayBuffer();
|
|
296
|
-
if (
|
|
297
|
-
return (await
|
|
298
|
-
if (
|
|
337
|
+
if (w === "browserPNG")
|
|
338
|
+
return (await B(i, "image/png")).arrayBuffer();
|
|
339
|
+
if (w === "browserGIF")
|
|
299
340
|
throw new Error("Browser GIF encoding not supported directly");
|
|
300
|
-
const
|
|
301
|
-
mozJPEG:
|
|
302
|
-
webP:
|
|
303
|
-
avif:
|
|
304
|
-
jxl:
|
|
305
|
-
oxiPNG:
|
|
306
|
-
qoi:
|
|
307
|
-
wp2:
|
|
308
|
-
}[
|
|
309
|
-
if (!
|
|
310
|
-
throw new Error(`Unknown encoder: ${
|
|
311
|
-
return (await
|
|
312
|
-
|
|
313
|
-
() =>
|
|
341
|
+
const x = {
|
|
342
|
+
mozJPEG: d.mozjpegEncode,
|
|
343
|
+
webP: d.webpEncode,
|
|
344
|
+
avif: d.avifEncode,
|
|
345
|
+
jxl: d.jxlEncode,
|
|
346
|
+
oxiPNG: d.oxipngEncode,
|
|
347
|
+
qoi: d.qoiEncode,
|
|
348
|
+
wp2: d.wp2Encode
|
|
349
|
+
}[w];
|
|
350
|
+
if (!x)
|
|
351
|
+
throw new Error(`Unknown encoder: ${w}`);
|
|
352
|
+
return (await a(
|
|
353
|
+
f,
|
|
354
|
+
() => x.call(d, i, l.encoderOptions)
|
|
314
355
|
)).buffer;
|
|
315
356
|
}
|
|
316
|
-
async function
|
|
317
|
-
var
|
|
318
|
-
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
const
|
|
322
|
-
|
|
357
|
+
async function q(f, i) {
|
|
358
|
+
var w;
|
|
359
|
+
e.value = new AbortController();
|
|
360
|
+
const l = e.value.signal;
|
|
361
|
+
r.value = !0, o.value = 0, n.value = null;
|
|
362
|
+
const d = t.value;
|
|
363
|
+
t.value = null, (w = d == null ? void 0 : d.compressed) != null && w.blobUrl && ce(d.compressed.blobUrl);
|
|
323
364
|
try {
|
|
324
|
-
|
|
325
|
-
const
|
|
326
|
-
file:
|
|
327
|
-
size:
|
|
365
|
+
o.value = 10;
|
|
366
|
+
const g = {
|
|
367
|
+
file: f,
|
|
368
|
+
size: f.size,
|
|
328
369
|
width: 0,
|
|
329
370
|
height: 0,
|
|
330
|
-
blobUrl: V(
|
|
331
|
-
},
|
|
332
|
-
|
|
333
|
-
const
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
371
|
+
blobUrl: V(f)
|
|
372
|
+
}, x = await u(l, f);
|
|
373
|
+
g.width = x.width, g.height = x.height, o.value = 25;
|
|
374
|
+
const U = await h(
|
|
375
|
+
l,
|
|
376
|
+
x,
|
|
377
|
+
i.rotate || 0
|
|
337
378
|
);
|
|
338
|
-
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
const F = await
|
|
342
|
-
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
(
|
|
346
|
-
),
|
|
379
|
+
o.value = 35;
|
|
380
|
+
const j = await b(l, U, i);
|
|
381
|
+
o.value = 50;
|
|
382
|
+
const F = await O(l, j, i);
|
|
383
|
+
o.value = 80;
|
|
384
|
+
const C = G[i.encoder], A = X(
|
|
385
|
+
f.name,
|
|
386
|
+
(C == null ? void 0 : C.extension) || "bin"
|
|
387
|
+
), L = H(
|
|
347
388
|
F,
|
|
348
|
-
|
|
349
|
-
(
|
|
350
|
-
),
|
|
351
|
-
file:
|
|
352
|
-
size:
|
|
353
|
-
width:
|
|
354
|
-
height:
|
|
355
|
-
blobUrl: V(
|
|
356
|
-
},
|
|
357
|
-
original:
|
|
358
|
-
compressed:
|
|
359
|
-
savingsBytes:
|
|
360
|
-
savingsPercent:
|
|
361
|
-
encoderType:
|
|
362
|
-
encoderOptions:
|
|
389
|
+
A,
|
|
390
|
+
(C == null ? void 0 : C.mimeType) || "application/octet-stream"
|
|
391
|
+
), M = {
|
|
392
|
+
file: L,
|
|
393
|
+
size: L.size,
|
|
394
|
+
width: j.width,
|
|
395
|
+
height: j.height,
|
|
396
|
+
blobUrl: V(L)
|
|
397
|
+
}, m = {
|
|
398
|
+
original: g,
|
|
399
|
+
compressed: M,
|
|
400
|
+
savingsBytes: g.size - M.size,
|
|
401
|
+
savingsPercent: K(g.size, M.size),
|
|
402
|
+
encoderType: i.encoder,
|
|
403
|
+
encoderOptions: i.encoderOptions
|
|
363
404
|
};
|
|
364
|
-
return
|
|
365
|
-
} catch (
|
|
366
|
-
if (
|
|
367
|
-
throw
|
|
368
|
-
const
|
|
369
|
-
throw
|
|
405
|
+
return t.value = m, o.value = 100, m;
|
|
406
|
+
} catch (g) {
|
|
407
|
+
if (g instanceof DOMException && g.name === "AbortError")
|
|
408
|
+
throw n.value = "已取消", g;
|
|
409
|
+
const x = g instanceof Error ? g.message : "压缩失败";
|
|
410
|
+
throw n.value = x, console.error("Compression error:", g), g;
|
|
370
411
|
} finally {
|
|
371
|
-
|
|
412
|
+
r.value = !1, e.value = null;
|
|
372
413
|
}
|
|
373
414
|
}
|
|
374
|
-
function
|
|
375
|
-
|
|
415
|
+
function P() {
|
|
416
|
+
e.value && e.value.abort();
|
|
376
417
|
}
|
|
377
|
-
function
|
|
378
|
-
if (!
|
|
379
|
-
const { compressed:
|
|
380
|
-
|
|
418
|
+
function T() {
|
|
419
|
+
if (!t.value) return;
|
|
420
|
+
const { compressed: f } = t.value, i = document.createElement("a");
|
|
421
|
+
i.href = f.blobUrl, i.download = f.file.name, document.body.appendChild(i), i.click(), document.body.removeChild(i);
|
|
381
422
|
}
|
|
382
423
|
return {
|
|
383
|
-
compress:
|
|
384
|
-
cancel:
|
|
385
|
-
downloadResult:
|
|
386
|
-
isCompressing:
|
|
387
|
-
progress:
|
|
388
|
-
error:
|
|
389
|
-
result:
|
|
390
|
-
canCancel:
|
|
424
|
+
compress: q,
|
|
425
|
+
cancel: P,
|
|
426
|
+
downloadResult: T,
|
|
427
|
+
isCompressing: r,
|
|
428
|
+
progress: o,
|
|
429
|
+
error: n,
|
|
430
|
+
result: t,
|
|
431
|
+
canCancel: p
|
|
391
432
|
};
|
|
392
433
|
}
|
|
393
434
|
function fe() {
|
|
394
|
-
const
|
|
395
|
-
() =>
|
|
396
|
-
),
|
|
397
|
-
() =>
|
|
398
|
-
type:
|
|
399
|
-
label:
|
|
400
|
-
mimeType:
|
|
401
|
-
extension:
|
|
435
|
+
const r = y("mozJPEG"), o = y({}), n = R(() => G[r.value]), t = R(
|
|
436
|
+
() => N[r.value]
|
|
437
|
+
), e = R(
|
|
438
|
+
() => ae.map((u) => ({
|
|
439
|
+
type: u,
|
|
440
|
+
label: G[u].label,
|
|
441
|
+
mimeType: G[u].mimeType,
|
|
442
|
+
extension: G[u].extension
|
|
402
443
|
}))
|
|
403
444
|
);
|
|
404
|
-
function
|
|
405
|
-
|
|
445
|
+
function s(u) {
|
|
446
|
+
r.value = u, o.value = { ...N[u] };
|
|
406
447
|
}
|
|
407
|
-
function
|
|
408
|
-
|
|
409
|
-
...
|
|
410
|
-
[
|
|
448
|
+
function a(u, h) {
|
|
449
|
+
o.value = {
|
|
450
|
+
...o.value,
|
|
451
|
+
[u]: h
|
|
411
452
|
};
|
|
412
453
|
}
|
|
413
|
-
function
|
|
414
|
-
|
|
454
|
+
function p() {
|
|
455
|
+
o.value = { ...t.value };
|
|
415
456
|
}
|
|
416
|
-
return
|
|
417
|
-
selectedEncoder:
|
|
418
|
-
encoderOptions:
|
|
419
|
-
currentMeta:
|
|
420
|
-
currentDefaults:
|
|
421
|
-
availableEncoders:
|
|
422
|
-
selectEncoder:
|
|
423
|
-
updateOption:
|
|
424
|
-
resetOptions:
|
|
457
|
+
return p(), {
|
|
458
|
+
selectedEncoder: r,
|
|
459
|
+
encoderOptions: o,
|
|
460
|
+
currentMeta: n,
|
|
461
|
+
currentDefaults: t,
|
|
462
|
+
availableEncoders: e,
|
|
463
|
+
selectEncoder: s,
|
|
464
|
+
updateOption: a,
|
|
465
|
+
resetOptions: p
|
|
425
466
|
};
|
|
426
467
|
}
|
|
427
|
-
const ve = { class: "image-compressor" },
|
|
468
|
+
const ve = { class: "image-compressor" }, we = {
|
|
428
469
|
key: 0,
|
|
429
470
|
class: "preview-area"
|
|
430
|
-
},
|
|
471
|
+
}, ge = { class: "preview-item" }, be = ["src"], Ee = { class: "preview-item" }, he = ["src"], ye = {
|
|
431
472
|
key: 1,
|
|
432
473
|
class: "compressing"
|
|
433
|
-
},
|
|
474
|
+
}, xe = ["value"], _e = { key: 2 }, ze = {
|
|
434
475
|
key: 1,
|
|
435
476
|
class: "encoder-settings"
|
|
436
|
-
},
|
|
477
|
+
}, ke = ["value"], Oe = {
|
|
437
478
|
key: 0,
|
|
438
479
|
class: "quality-control"
|
|
439
|
-
},
|
|
480
|
+
}, Pe = ["value"], Te = {
|
|
440
481
|
key: 2,
|
|
441
482
|
class: "actions"
|
|
442
|
-
},
|
|
483
|
+
}, De = ["disabled"], Ie = {
|
|
443
484
|
key: 3,
|
|
444
485
|
class: "error"
|
|
445
|
-
},
|
|
486
|
+
}, qe = /* @__PURE__ */ Z({
|
|
446
487
|
__name: "ImageCompressor",
|
|
447
488
|
props: {
|
|
448
489
|
defaultEncoder: {},
|
|
449
490
|
defaultOptions: {}
|
|
450
491
|
},
|
|
451
492
|
emits: ["success", "error", "cancel"],
|
|
452
|
-
setup(
|
|
453
|
-
const
|
|
454
|
-
compress:
|
|
455
|
-
cancel:
|
|
456
|
-
downloadResult:
|
|
457
|
-
isCompressing:
|
|
458
|
-
progress:
|
|
459
|
-
error:
|
|
460
|
-
result:
|
|
461
|
-
canCancel:
|
|
462
|
-
} =
|
|
463
|
-
selectedEncoder:
|
|
464
|
-
encoderOptions:
|
|
465
|
-
availableEncoders:
|
|
466
|
-
selectEncoder:
|
|
467
|
-
updateOption:
|
|
493
|
+
setup(r, { emit: o }) {
|
|
494
|
+
const n = r, t = o, e = y(null), s = y(null), a = y(""), p = y(""), {
|
|
495
|
+
compress: u,
|
|
496
|
+
cancel: h,
|
|
497
|
+
downloadResult: b,
|
|
498
|
+
isCompressing: O,
|
|
499
|
+
progress: q,
|
|
500
|
+
error: P,
|
|
501
|
+
result: T,
|
|
502
|
+
canCancel: f
|
|
503
|
+
} = me(), {
|
|
504
|
+
selectedEncoder: i,
|
|
505
|
+
encoderOptions: l,
|
|
506
|
+
availableEncoders: d,
|
|
507
|
+
selectEncoder: w,
|
|
508
|
+
updateOption: g
|
|
468
509
|
} = fe();
|
|
469
|
-
|
|
470
|
-
const
|
|
471
|
-
() =>
|
|
472
|
-
),
|
|
473
|
-
() =>
|
|
474
|
-
),
|
|
475
|
-
() => ["mozJPEG", "webP", "jxl", "browserJPEG", "wp2"].includes(
|
|
510
|
+
n.defaultEncoder && w(n.defaultEncoder), n.defaultOptions && Object.entries(n.defaultOptions).forEach(([m, c]) => g(m, c));
|
|
511
|
+
const x = R(
|
|
512
|
+
() => s.value ? $(s.value.size) : ""
|
|
513
|
+
), U = R(
|
|
514
|
+
() => T.value ? $(T.value.compressed.size) : ""
|
|
515
|
+
), j = R(
|
|
516
|
+
() => ["mozJPEG", "webP", "jxl", "browserJPEG", "wp2"].includes(i.value)
|
|
476
517
|
);
|
|
477
|
-
function F(
|
|
478
|
-
const
|
|
479
|
-
|
|
518
|
+
function F(m) {
|
|
519
|
+
const c = m.target;
|
|
520
|
+
c.files && c.files[0] && A(c.files[0]);
|
|
480
521
|
}
|
|
481
|
-
function
|
|
482
|
-
var
|
|
483
|
-
(
|
|
522
|
+
function C(m) {
|
|
523
|
+
var c;
|
|
524
|
+
(c = m.dataTransfer) != null && c.files[0] && A(m.dataTransfer.files[0]);
|
|
484
525
|
}
|
|
485
|
-
function
|
|
486
|
-
|
|
526
|
+
function A(m) {
|
|
527
|
+
m.type.startsWith("image/") && (a.value && URL.revokeObjectURL(a.value), p.value && (URL.revokeObjectURL(p.value), p.value = ""), s.value = m, a.value = URL.createObjectURL(m));
|
|
487
528
|
}
|
|
488
|
-
function
|
|
489
|
-
|
|
529
|
+
function L() {
|
|
530
|
+
w(i.value);
|
|
490
531
|
}
|
|
491
|
-
async function
|
|
492
|
-
if (
|
|
532
|
+
async function M() {
|
|
533
|
+
if (s.value)
|
|
493
534
|
try {
|
|
494
|
-
const
|
|
495
|
-
encoder:
|
|
496
|
-
encoderOptions: { ...
|
|
497
|
-
},
|
|
498
|
-
|
|
499
|
-
} catch (
|
|
500
|
-
if (
|
|
501
|
-
|
|
535
|
+
const m = {
|
|
536
|
+
encoder: i.value,
|
|
537
|
+
encoderOptions: { ...l.value }
|
|
538
|
+
}, c = await u(s.value, m);
|
|
539
|
+
p.value = c.compressed.blobUrl, t("success", c);
|
|
540
|
+
} catch (m) {
|
|
541
|
+
if (m instanceof DOMException && m.name === "AbortError") {
|
|
542
|
+
t("cancel");
|
|
502
543
|
return;
|
|
503
544
|
}
|
|
504
|
-
|
|
545
|
+
t("error", m instanceof Error ? m : new Error(String(m)));
|
|
505
546
|
}
|
|
506
547
|
}
|
|
507
|
-
return
|
|
508
|
-
(
|
|
509
|
-
(l, s) => {
|
|
510
|
-
l && l !== s && c.value && URL.revokeObjectURL(c.value);
|
|
511
|
-
}
|
|
512
|
-
), (l, s) => (_(), k("div", ve, [
|
|
513
|
-
g("div", {
|
|
548
|
+
return (m, c) => (z(), k("div", ve, [
|
|
549
|
+
E("div", {
|
|
514
550
|
class: "upload-zone",
|
|
515
|
-
onDrop:
|
|
516
|
-
onDragover:
|
|
551
|
+
onDrop: J(C, ["prevent"]),
|
|
552
|
+
onDragover: c[1] || (c[1] = J(() => {
|
|
517
553
|
}, ["prevent"]))
|
|
518
554
|
}, [
|
|
519
|
-
|
|
555
|
+
E("input", {
|
|
520
556
|
type: "file",
|
|
521
557
|
accept: "image/*",
|
|
522
558
|
onChange: F,
|
|
523
559
|
ref_key: "fileInput",
|
|
524
|
-
ref:
|
|
560
|
+
ref: e,
|
|
525
561
|
class: "file-input"
|
|
526
562
|
}, null, 544),
|
|
527
|
-
|
|
563
|
+
E("div", {
|
|
528
564
|
class: "upload-prompt",
|
|
529
|
-
onClick:
|
|
530
|
-
var
|
|
531
|
-
return (
|
|
565
|
+
onClick: c[0] || (c[0] = (_) => {
|
|
566
|
+
var W;
|
|
567
|
+
return (W = e.value) == null ? void 0 : W.click();
|
|
532
568
|
})
|
|
533
569
|
}, [
|
|
534
|
-
S(
|
|
535
|
-
|
|
570
|
+
S(m.$slots, "upload-prompt", {}, () => [
|
|
571
|
+
c[6] || (c[6] = E("p", null, "拖拽图片到此处,或点击上传", -1))
|
|
536
572
|
], !0)
|
|
537
573
|
])
|
|
538
574
|
], 32),
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
src:
|
|
575
|
+
a.value ? (z(), k("div", we, [
|
|
576
|
+
E("div", ge, [
|
|
577
|
+
c[7] || (c[7] = E("h4", null, "原始图片", -1)),
|
|
578
|
+
E("img", {
|
|
579
|
+
src: a.value,
|
|
544
580
|
alt: "Original"
|
|
545
581
|
}, null, 8, be),
|
|
546
|
-
|
|
582
|
+
E("p", null, D(x.value), 1)
|
|
547
583
|
]),
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
584
|
+
E("div", Ee, [
|
|
585
|
+
c[8] || (c[8] = E("h4", null, "压缩后", -1)),
|
|
586
|
+
p.value ? (z(), k("img", {
|
|
551
587
|
key: 0,
|
|
552
|
-
src:
|
|
588
|
+
src: p.value,
|
|
553
589
|
alt: "Compressed"
|
|
554
|
-
}, null, 8,
|
|
555
|
-
|
|
556
|
-
value:
|
|
590
|
+
}, null, 8, he)) : v(O) ? (z(), k("div", ye, [
|
|
591
|
+
E("progress", {
|
|
592
|
+
value: v(q),
|
|
557
593
|
max: "100"
|
|
558
|
-
}, null, 8,
|
|
559
|
-
|
|
560
|
-
])) :
|
|
561
|
-
|
|
594
|
+
}, null, 8, xe),
|
|
595
|
+
E("p", null, "压缩中... " + D(v(q)) + "%", 1)
|
|
596
|
+
])) : I("", !0),
|
|
597
|
+
U.value ? (z(), k("p", _e, D(U.value), 1)) : I("", !0)
|
|
562
598
|
])
|
|
563
|
-
])) :
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
"onUpdate:modelValue":
|
|
568
|
-
onChange:
|
|
599
|
+
])) : I("", !0),
|
|
600
|
+
a.value ? (z(), k("div", ze, [
|
|
601
|
+
c[9] || (c[9] = E("label", null, "编码器:", -1)),
|
|
602
|
+
ee(E("select", {
|
|
603
|
+
"onUpdate:modelValue": c[2] || (c[2] = (_) => te(i) ? i.value = _ : null),
|
|
604
|
+
onChange: L
|
|
569
605
|
}, [
|
|
570
|
-
(
|
|
571
|
-
key:
|
|
572
|
-
value:
|
|
573
|
-
},
|
|
606
|
+
(z(!0), k(oe, null, re(v(d), (_) => (z(), k("option", {
|
|
607
|
+
key: _.type,
|
|
608
|
+
value: _.type
|
|
609
|
+
}, D(_.label) + " (" + D(_.extension) + ") ", 9, ke))), 128))
|
|
574
610
|
], 544), [
|
|
575
|
-
[
|
|
611
|
+
[ne, v(i)]
|
|
576
612
|
]),
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
613
|
+
j.value ? (z(), k("div", Oe, [
|
|
614
|
+
E("label", null, [
|
|
615
|
+
se(" 质量: " + D(v(l).quality ?? 75) + " ", 1),
|
|
616
|
+
E("input", {
|
|
581
617
|
type: "range",
|
|
582
618
|
min: "0",
|
|
583
619
|
max: "100",
|
|
584
|
-
value:
|
|
585
|
-
onInput:
|
|
586
|
-
|
|
587
|
-
REPLACE: ""
|
|
588
|
-
}, null, 40, ze)
|
|
620
|
+
value: v(l).quality ?? 75,
|
|
621
|
+
onInput: c[3] || (c[3] = (_) => v(g)("quality", Number(_.target.value)))
|
|
622
|
+
}, null, 40, Pe)
|
|
589
623
|
])
|
|
590
|
-
])) :
|
|
591
|
-
S(
|
|
592
|
-
encoder:
|
|
593
|
-
options:
|
|
624
|
+
])) : I("", !0),
|
|
625
|
+
S(m.$slots, "encoder-settings", {
|
|
626
|
+
encoder: v(i),
|
|
627
|
+
options: v(l)
|
|
594
628
|
}, void 0, !0)
|
|
595
|
-
])) :
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
onClick:
|
|
599
|
-
disabled:
|
|
629
|
+
])) : I("", !0),
|
|
630
|
+
a.value ? (z(), k("div", Te, [
|
|
631
|
+
E("button", {
|
|
632
|
+
onClick: M,
|
|
633
|
+
disabled: v(O),
|
|
600
634
|
class: "btn-primary"
|
|
601
|
-
},
|
|
602
|
-
|
|
635
|
+
}, D(v(O) ? "压缩中..." : "开始压缩"), 9, De),
|
|
636
|
+
v(f) ? (z(), k("button", {
|
|
603
637
|
key: 0,
|
|
604
|
-
onClick:
|
|
605
|
-
(...
|
|
638
|
+
onClick: c[4] || (c[4] = //@ts-ignore
|
|
639
|
+
(..._) => v(h) && v(h)(..._)),
|
|
606
640
|
class: "btn-secondary"
|
|
607
|
-
}, " 取消 ")) :
|
|
608
|
-
|
|
641
|
+
}, " 取消 ")) : I("", !0),
|
|
642
|
+
v(T) ? (z(), k("button", {
|
|
609
643
|
key: 1,
|
|
610
|
-
onClick:
|
|
611
|
-
(...
|
|
644
|
+
onClick: c[5] || (c[5] = //@ts-ignore
|
|
645
|
+
(..._) => v(b) && v(b)(..._)),
|
|
612
646
|
class: "btn-success"
|
|
613
|
-
}, " 下载 (节省 " +
|
|
614
|
-
])) :
|
|
615
|
-
|
|
647
|
+
}, " 下载 (节省 " + D(v(T).savingsPercent) + "%) ", 1)) : I("", !0)
|
|
648
|
+
])) : I("", !0),
|
|
649
|
+
v(P) ? (z(), k("div", Ie, D(v(P)), 1)) : I("", !0)
|
|
616
650
|
]));
|
|
617
651
|
}
|
|
618
|
-
}),
|
|
619
|
-
const
|
|
620
|
-
for (const [
|
|
621
|
-
|
|
622
|
-
return
|
|
623
|
-
},
|
|
652
|
+
}), Ce = (r, o) => {
|
|
653
|
+
const n = r.__vccOpts || r;
|
|
654
|
+
for (const [t, e] of o)
|
|
655
|
+
n[t] = e;
|
|
656
|
+
return n;
|
|
657
|
+
}, Me = /* @__PURE__ */ Ce(qe, [["__scopeId", "data-v-d7e6eec9"]]), Ae = [
|
|
624
658
|
{ value: "lanczos3", label: "Lanczos3" },
|
|
625
659
|
{ value: "catrom", label: "Catrom" },
|
|
626
660
|
{ value: "mitchell", label: "Mitchell" },
|
|
627
661
|
{ value: "triangle", label: "Triangle" },
|
|
628
662
|
{ value: "vector", label: "Vector" }
|
|
629
|
-
],
|
|
663
|
+
], Be = [
|
|
630
664
|
{ value: "stretch", label: "拉伸" },
|
|
631
665
|
{ value: "contain", label: "适应" }
|
|
632
|
-
],
|
|
666
|
+
], Fe = [
|
|
633
667
|
{ value: 0, label: "不旋转" },
|
|
634
668
|
{ value: 90, label: "顺时针 90°" },
|
|
635
669
|
{ value: 180, label: "旋转 180°" },
|
|
636
670
|
{ value: 270, label: "逆时针 90°" }
|
|
637
|
-
]
|
|
671
|
+
], je = {
|
|
672
|
+
mozJPEG: "mozjpegEncode",
|
|
673
|
+
webP: "webpEncode",
|
|
674
|
+
avif: "avifEncode",
|
|
675
|
+
jxl: "jxlEncode",
|
|
676
|
+
oxiPNG: "oxipngEncode",
|
|
677
|
+
qoi: "qoiEncode",
|
|
678
|
+
wp2: "wp2Encode"
|
|
679
|
+
};
|
|
680
|
+
function Ge() {
|
|
681
|
+
return new Worker(
|
|
682
|
+
new URL(
|
|
683
|
+
/* @vite-ignore */
|
|
684
|
+
"/assets/imageWorker-Qv3pCULy.js",
|
|
685
|
+
import.meta.url
|
|
686
|
+
),
|
|
687
|
+
{ type: "module" }
|
|
688
|
+
);
|
|
689
|
+
}
|
|
690
|
+
function Re(r, o, n, t) {
|
|
691
|
+
return new Promise((e, s) => {
|
|
692
|
+
const a = Ge();
|
|
693
|
+
let p = !1;
|
|
694
|
+
function u() {
|
|
695
|
+
p || (p = !0, a.terminate());
|
|
696
|
+
}
|
|
697
|
+
a.addEventListener("message", (O) => {
|
|
698
|
+
const { result: q, error: P } = O.data;
|
|
699
|
+
u(), P ? s(new Error(P)) : e(q.buffer);
|
|
700
|
+
}), a.addEventListener("error", (O) => {
|
|
701
|
+
u(), s(O.error || O);
|
|
702
|
+
});
|
|
703
|
+
const h = () => {
|
|
704
|
+
u(), s(new DOMException("AbortError", "AbortError"));
|
|
705
|
+
};
|
|
706
|
+
t && t.addEventListener("abort", h, { once: !0 });
|
|
707
|
+
const b = je[r];
|
|
708
|
+
if (!b) {
|
|
709
|
+
u(), s(new Error(`Unknown encoder: ${r}`));
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
a.postMessage({ id: 1, method: b, args: [o, n] });
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
async function Ne(r, o = {}) {
|
|
716
|
+
const { signal: n } = o;
|
|
717
|
+
if (n != null && n.aborted)
|
|
718
|
+
throw new DOMException("AbortError", "AbortError");
|
|
719
|
+
const t = o.encoder || "mozJPEG", e = {
|
|
720
|
+
...N[t],
|
|
721
|
+
...o.encoderOptions
|
|
722
|
+
}, s = G[t], a = await Q(r);
|
|
723
|
+
if (n != null && n.aborted)
|
|
724
|
+
throw new DOMException("AbortError", "AbortError");
|
|
725
|
+
let p;
|
|
726
|
+
if (t === "browserJPEG")
|
|
727
|
+
p = await (await B(
|
|
728
|
+
a,
|
|
729
|
+
"image/jpeg",
|
|
730
|
+
e.quality
|
|
731
|
+
)).arrayBuffer();
|
|
732
|
+
else if (t === "browserPNG")
|
|
733
|
+
p = await (await B(a, "image/png")).arrayBuffer();
|
|
734
|
+
else {
|
|
735
|
+
if (t === "browserGIF")
|
|
736
|
+
throw new Error("Browser GIF encoding not supported directly");
|
|
737
|
+
p = await Re(
|
|
738
|
+
t,
|
|
739
|
+
a,
|
|
740
|
+
e,
|
|
741
|
+
n
|
|
742
|
+
);
|
|
743
|
+
}
|
|
744
|
+
if (n != null && n.aborted)
|
|
745
|
+
throw new DOMException("AbortError", "AbortError");
|
|
746
|
+
const u = X(r.name, s.extension), h = H(
|
|
747
|
+
p,
|
|
748
|
+
u,
|
|
749
|
+
s.mimeType
|
|
750
|
+
);
|
|
751
|
+
return {
|
|
752
|
+
file: h,
|
|
753
|
+
originalSize: r.size,
|
|
754
|
+
compressedSize: h.size,
|
|
755
|
+
savingsBytes: r.size - h.size,
|
|
756
|
+
savingsPercent: K(r.size, h.size),
|
|
757
|
+
width: a.width,
|
|
758
|
+
height: a.height,
|
|
759
|
+
encoderType: t,
|
|
760
|
+
encoderOptions: e
|
|
761
|
+
};
|
|
762
|
+
}
|
|
638
763
|
export {
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
764
|
+
N as DEFAULT_ENCODER_OPTIONS,
|
|
765
|
+
ae as ENCODER_LIST,
|
|
766
|
+
G as ENCODER_REGISTRY,
|
|
767
|
+
Be as FIT_METHODS,
|
|
768
|
+
Me as ImageCompressor,
|
|
769
|
+
Ae as RESIZE_METHODS,
|
|
770
|
+
Fe as ROTATE_OPTIONS,
|
|
771
|
+
H as arrayBufferToFile,
|
|
772
|
+
Q as blobToImageData,
|
|
773
|
+
K as calculateSavings,
|
|
774
|
+
le as canDecodeImageType,
|
|
775
|
+
Ne as compressFile,
|
|
650
776
|
V as createBlobUrl,
|
|
651
777
|
$ as formatBytes,
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
778
|
+
X as generateCompressedFilename,
|
|
779
|
+
Le as getImageDimensions,
|
|
780
|
+
B as imageDataToBlob,
|
|
781
|
+
ce as revokeBlobUrl,
|
|
782
|
+
ie as sniffMimeType,
|
|
783
|
+
me as useCompression,
|
|
658
784
|
fe as useEncoderRegistry,
|
|
659
|
-
|
|
785
|
+
pe as useWorker
|
|
660
786
|
};
|