vue3-image-compressor 1.0.7 → 1.0.9

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.
@@ -1,5 +1,5 @@
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 = {
1
+ import { ref as y, onUnmounted as Y, computed as G, 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 C, withDirectives as ee, isRef as te, Fragment as oe, renderList as re, vModelSelect as ne, createTextVNode as se } from "vue";
2
+ const j = {
3
3
  mozJPEG: {
4
4
  label: "MozJPEG",
5
5
  mimeType: "image/jpeg",
@@ -124,14 +124,14 @@ const G = {
124
124
  wp2: {
125
125
  quality: 75
126
126
  }
127
- }, ae = Object.keys(G);
128
- async function Q(r) {
127
+ }, ae = Object.keys(j);
128
+ async function H(r) {
129
129
  const o = await createImageBitmap(r), n = document.createElement("canvas");
130
130
  n.width = o.width, n.height = o.height;
131
131
  const t = n.getContext("2d");
132
132
  return t.drawImage(o, 0, 0), t.getImageData(0, 0, n.width, n.height);
133
133
  }
134
- async function B(r, o, n) {
134
+ async function A(r, o, n) {
135
135
  const t = document.createElement("canvas");
136
136
  return t.width = r.width, t.height = r.height, t.getContext("2d").putImageData(r, 0, 0), new Promise((s) => {
137
137
  t.toBlob(
@@ -159,7 +159,7 @@ function le(r) {
159
159
  n.onload = () => o(!0), n.onerror = () => o(!1), n.src = `data:${r};base64,`;
160
160
  });
161
161
  }
162
- function H(r, o, n) {
162
+ function Q(r, o, n) {
163
163
  return new File([r], o, { type: n });
164
164
  }
165
165
  function $(r, o = 2) {
@@ -230,10 +230,9 @@ function pe() {
230
230
  o.value = !0, t = new Worker(
231
231
  new URL(
232
232
  /* @vite-ignore */
233
- "/assets/imageWorker-Qv3pCULy.js",
233
+ "" + new URL("assets/imageWorker-B_HCdCy9.js", import.meta.url).href,
234
234
  import.meta.url
235
- ),
236
- { type: "module" }
235
+ )
237
236
  ), r.value = !0, n.value = null;
238
237
  } catch (b) {
239
238
  n.value = b instanceof Error ? b : new Error("Failed to start worker"), console.error("Worker start failed:", b);
@@ -257,11 +256,11 @@ function pe() {
257
256
  async function h(b, O) {
258
257
  if (b.aborted)
259
258
  throw new DOMException("AbortError", "AbortError");
260
- return clearTimeout(e), new Promise((q, P) => {
259
+ return clearTimeout(e), new Promise((I, P) => {
261
260
  const T = () => {
262
261
  a(), P(new DOMException("AbortError", "AbortError"));
263
262
  };
264
- b.addEventListener("abort", T), O().then(q).catch(P).finally(() => {
263
+ b.addEventListener("abort", T), O().then(I).catch(P).finally(() => {
265
264
  b.removeEventListener("abort", T), p();
266
265
  });
267
266
  });
@@ -279,7 +278,7 @@ function pe() {
279
278
  };
280
279
  }
281
280
  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);
281
+ const r = y(!1), o = y(0), n = y(null), t = y(null), e = y(null), { getWorkerApi: s, executeTask: a } = pe(), p = G(() => r.value && !!e.value);
283
282
  async function u(f, i) {
284
283
  const l = await ie(i), d = await le(l), w = await s();
285
284
  if (!d) {
@@ -294,7 +293,7 @@ function me() {
294
293
  if (l === "image/qoi")
295
294
  return a(f, () => w.qoiDecode(i));
296
295
  }
297
- return Q(i);
296
+ return H(i);
298
297
  }
299
298
  async function h(f, i, l) {
300
299
  if (l === 0) return i;
@@ -305,7 +304,7 @@ function me() {
305
304
  );
306
305
  }
307
306
  async function b(f, i, l) {
308
- var g, x;
307
+ var g, _;
309
308
  let d = i;
310
309
  const w = await s();
311
310
  return (g = l.resize) != null && g.enabled && (d = await a(
@@ -318,7 +317,7 @@ function me() {
318
317
  premultiply: !0,
319
318
  linearRGB: !0
320
319
  })
321
- )), (x = l.quantize) != null && x.enabled && (d = await a(
320
+ )), (_ = l.quantize) != null && _.enabled && (d = await a(
322
321
  f,
323
322
  () => w.quantize(d, {
324
323
  numColors: l.quantize.numColors || 256,
@@ -329,16 +328,16 @@ function me() {
329
328
  async function O(f, i, l) {
330
329
  const d = await s(), w = l.encoder;
331
330
  if (w === "browserJPEG")
332
- return (await B(
331
+ return (await A(
333
332
  i,
334
333
  "image/jpeg",
335
334
  l.encoderOptions.quality
336
335
  )).arrayBuffer();
337
336
  if (w === "browserPNG")
338
- return (await B(i, "image/png")).arrayBuffer();
337
+ return (await A(i, "image/png")).arrayBuffer();
339
338
  if (w === "browserGIF")
340
339
  throw new Error("Browser GIF encoding not supported directly");
341
- const x = {
340
+ const _ = {
342
341
  mozJPEG: d.mozjpegEncode,
343
342
  webP: d.webpEncode,
344
343
  avif: d.avifEncode,
@@ -347,14 +346,14 @@ function me() {
347
346
  qoi: d.qoiEncode,
348
347
  wp2: d.wp2Encode
349
348
  }[w];
350
- if (!x)
349
+ if (!_)
351
350
  throw new Error(`Unknown encoder: ${w}`);
352
351
  return (await a(
353
352
  f,
354
- () => x.call(d, i, l.encoderOptions)
353
+ () => _.call(d, i, l.encoderOptions)
355
354
  )).buffer;
356
355
  }
357
- async function q(f, i) {
356
+ async function I(f, i) {
358
357
  var w;
359
358
  e.value = new AbortController();
360
359
  const l = e.value.signal;
@@ -369,30 +368,30 @@ function me() {
369
368
  width: 0,
370
369
  height: 0,
371
370
  blobUrl: V(f)
372
- }, x = await u(l, f);
373
- g.width = x.width, g.height = x.height, o.value = 25;
371
+ }, _ = await u(l, f);
372
+ g.width = _.width, g.height = _.height, o.value = 25;
374
373
  const U = await h(
375
374
  l,
376
- x,
375
+ _,
377
376
  i.rotate || 0
378
377
  );
379
378
  o.value = 35;
380
- const j = await b(l, U, i);
379
+ const R = await b(l, U, i);
381
380
  o.value = 50;
382
- const F = await O(l, j, i);
381
+ const F = await O(l, R, i);
383
382
  o.value = 80;
384
- const C = G[i.encoder], A = X(
383
+ const q = j[i.encoder], B = X(
385
384
  f.name,
386
- (C == null ? void 0 : C.extension) || "bin"
387
- ), L = H(
385
+ (q == null ? void 0 : q.extension) || "bin"
386
+ ), L = Q(
388
387
  F,
389
- A,
390
- (C == null ? void 0 : C.mimeType) || "application/octet-stream"
388
+ B,
389
+ (q == null ? void 0 : q.mimeType) || "application/octet-stream"
391
390
  ), M = {
392
391
  file: L,
393
392
  size: L.size,
394
- width: j.width,
395
- height: j.height,
393
+ width: R.width,
394
+ height: R.height,
396
395
  blobUrl: V(L)
397
396
  }, m = {
398
397
  original: g,
@@ -406,8 +405,8 @@ function me() {
406
405
  } catch (g) {
407
406
  if (g instanceof DOMException && g.name === "AbortError")
408
407
  throw n.value = "已取消", g;
409
- const x = g instanceof Error ? g.message : "压缩失败";
410
- throw n.value = x, console.error("Compression error:", g), g;
408
+ const _ = g instanceof Error ? g.message : "压缩失败";
409
+ throw n.value = _, console.error("Compression error:", g), g;
411
410
  } finally {
412
411
  r.value = !1, e.value = null;
413
412
  }
@@ -421,7 +420,7 @@ function me() {
421
420
  i.href = f.blobUrl, i.download = f.file.name, document.body.appendChild(i), i.click(), document.body.removeChild(i);
422
421
  }
423
422
  return {
424
- compress: q,
423
+ compress: I,
425
424
  cancel: P,
426
425
  downloadResult: T,
427
426
  isCompressing: r,
@@ -432,14 +431,14 @@ function me() {
432
431
  };
433
432
  }
434
433
  function fe() {
435
- const r = y("mozJPEG"), o = y({}), n = R(() => G[r.value]), t = R(
434
+ const r = y("mozJPEG"), o = y({}), n = G(() => j[r.value]), t = G(
436
435
  () => N[r.value]
437
- ), e = R(
436
+ ), e = G(
438
437
  () => ae.map((u) => ({
439
438
  type: u,
440
- label: G[u].label,
441
- mimeType: G[u].mimeType,
442
- extension: G[u].extension
439
+ label: j[u].label,
440
+ mimeType: j[u].mimeType,
441
+ extension: j[u].extension
443
442
  }))
444
443
  );
445
444
  function s(u) {
@@ -471,7 +470,7 @@ const ve = { class: "image-compressor" }, we = {
471
470
  }, ge = { class: "preview-item" }, be = ["src"], Ee = { class: "preview-item" }, he = ["src"], ye = {
472
471
  key: 1,
473
472
  class: "compressing"
474
- }, xe = ["value"], _e = { key: 2 }, ze = {
473
+ }, _e = ["value"], xe = { key: 2 }, ze = {
475
474
  key: 1,
476
475
  class: "encoder-settings"
477
476
  }, ke = ["value"], Oe = {
@@ -480,10 +479,10 @@ const ve = { class: "image-compressor" }, we = {
480
479
  }, Pe = ["value"], Te = {
481
480
  key: 2,
482
481
  class: "actions"
483
- }, De = ["disabled"], Ie = {
482
+ }, De = ["disabled"], Ce = {
484
483
  key: 3,
485
484
  class: "error"
486
- }, qe = /* @__PURE__ */ Z({
485
+ }, Ie = /* @__PURE__ */ Z({
487
486
  __name: "ImageCompressor",
488
487
  props: {
489
488
  defaultEncoder: {},
@@ -496,7 +495,7 @@ const ve = { class: "image-compressor" }, we = {
496
495
  cancel: h,
497
496
  downloadResult: b,
498
497
  isCompressing: O,
499
- progress: q,
498
+ progress: I,
500
499
  error: P,
501
500
  result: T,
502
501
  canCancel: f
@@ -508,22 +507,22 @@ const ve = { class: "image-compressor" }, we = {
508
507
  updateOption: g
509
508
  } = fe();
510
509
  n.defaultEncoder && w(n.defaultEncoder), n.defaultOptions && Object.entries(n.defaultOptions).forEach(([m, c]) => g(m, c));
511
- const x = R(
510
+ const _ = G(
512
511
  () => s.value ? $(s.value.size) : ""
513
- ), U = R(
512
+ ), U = G(
514
513
  () => T.value ? $(T.value.compressed.size) : ""
515
- ), j = R(
514
+ ), R = G(
516
515
  () => ["mozJPEG", "webP", "jxl", "browserJPEG", "wp2"].includes(i.value)
517
516
  );
518
517
  function F(m) {
519
518
  const c = m.target;
520
- c.files && c.files[0] && A(c.files[0]);
519
+ c.files && c.files[0] && B(c.files[0]);
521
520
  }
522
- function C(m) {
521
+ function q(m) {
523
522
  var c;
524
- (c = m.dataTransfer) != null && c.files[0] && A(m.dataTransfer.files[0]);
523
+ (c = m.dataTransfer) != null && c.files[0] && B(m.dataTransfer.files[0]);
525
524
  }
526
- function A(m) {
525
+ function B(m) {
527
526
  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));
528
527
  }
529
528
  function L() {
@@ -548,7 +547,7 @@ const ve = { class: "image-compressor" }, we = {
548
547
  return (m, c) => (z(), k("div", ve, [
549
548
  E("div", {
550
549
  class: "upload-zone",
551
- onDrop: J(C, ["prevent"]),
550
+ onDrop: J(q, ["prevent"]),
552
551
  onDragover: c[1] || (c[1] = J(() => {
553
552
  }, ["prevent"]))
554
553
  }, [
@@ -562,7 +561,7 @@ const ve = { class: "image-compressor" }, we = {
562
561
  }, null, 544),
563
562
  E("div", {
564
563
  class: "upload-prompt",
565
- onClick: c[0] || (c[0] = (_) => {
564
+ onClick: c[0] || (c[0] = (x) => {
566
565
  var W;
567
566
  return (W = e.value) == null ? void 0 : W.click();
568
567
  })
@@ -579,7 +578,7 @@ const ve = { class: "image-compressor" }, we = {
579
578
  src: a.value,
580
579
  alt: "Original"
581
580
  }, null, 8, be),
582
- E("p", null, D(x.value), 1)
581
+ E("p", null, D(_.value), 1)
583
582
  ]),
584
583
  E("div", Ee, [
585
584
  c[8] || (c[8] = E("h4", null, "压缩后", -1)),
@@ -589,28 +588,28 @@ const ve = { class: "image-compressor" }, we = {
589
588
  alt: "Compressed"
590
589
  }, null, 8, he)) : v(O) ? (z(), k("div", ye, [
591
590
  E("progress", {
592
- value: v(q),
591
+ value: v(I),
593
592
  max: "100"
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)
593
+ }, null, 8, _e),
594
+ E("p", null, "压缩中... " + D(v(I)) + "%", 1)
595
+ ])) : C("", !0),
596
+ U.value ? (z(), k("p", xe, D(U.value), 1)) : C("", !0)
598
597
  ])
599
- ])) : I("", !0),
598
+ ])) : C("", !0),
600
599
  a.value ? (z(), k("div", ze, [
601
600
  c[9] || (c[9] = E("label", null, "编码器:", -1)),
602
601
  ee(E("select", {
603
- "onUpdate:modelValue": c[2] || (c[2] = (_) => te(i) ? i.value = _ : null),
602
+ "onUpdate:modelValue": c[2] || (c[2] = (x) => te(i) ? i.value = x : null),
604
603
  onChange: L
605
604
  }, [
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))
605
+ (z(!0), k(oe, null, re(v(d), (x) => (z(), k("option", {
606
+ key: x.type,
607
+ value: x.type
608
+ }, D(x.label) + " (" + D(x.extension) + ") ", 9, ke))), 128))
610
609
  ], 544), [
611
610
  [ne, v(i)]
612
611
  ]),
613
- j.value ? (z(), k("div", Oe, [
612
+ R.value ? (z(), k("div", Oe, [
614
613
  E("label", null, [
615
614
  se(" 质量: " + D(v(l).quality ?? 75) + " ", 1),
616
615
  E("input", {
@@ -618,15 +617,15 @@ const ve = { class: "image-compressor" }, we = {
618
617
  min: "0",
619
618
  max: "100",
620
619
  value: v(l).quality ?? 75,
621
- onInput: c[3] || (c[3] = (_) => v(g)("quality", Number(_.target.value)))
620
+ onInput: c[3] || (c[3] = (x) => v(g)("quality", Number(x.target.value)))
622
621
  }, null, 40, Pe)
623
622
  ])
624
- ])) : I("", !0),
623
+ ])) : C("", !0),
625
624
  S(m.$slots, "encoder-settings", {
626
625
  encoder: v(i),
627
626
  options: v(l)
628
627
  }, void 0, !0)
629
- ])) : I("", !0),
628
+ ])) : C("", !0),
630
629
  a.value ? (z(), k("div", Te, [
631
630
  E("button", {
632
631
  onClick: M,
@@ -636,31 +635,31 @@ const ve = { class: "image-compressor" }, we = {
636
635
  v(f) ? (z(), k("button", {
637
636
  key: 0,
638
637
  onClick: c[4] || (c[4] = //@ts-ignore
639
- (..._) => v(h) && v(h)(..._)),
638
+ (...x) => v(h) && v(h)(...x)),
640
639
  class: "btn-secondary"
641
- }, " 取消 ")) : I("", !0),
640
+ }, " 取消 ")) : C("", !0),
642
641
  v(T) ? (z(), k("button", {
643
642
  key: 1,
644
643
  onClick: c[5] || (c[5] = //@ts-ignore
645
- (..._) => v(b) && v(b)(..._)),
644
+ (...x) => v(b) && v(b)(...x)),
646
645
  class: "btn-success"
647
- }, " 下载 (节省 " + D(v(T).savingsPercent) + "%) ", 1)) : I("", !0)
648
- ])) : I("", !0),
649
- v(P) ? (z(), k("div", Ie, D(v(P)), 1)) : I("", !0)
646
+ }, " 下载 (节省 " + D(v(T).savingsPercent) + "%) ", 1)) : C("", !0)
647
+ ])) : C("", !0),
648
+ v(P) ? (z(), k("div", Ce, D(v(P)), 1)) : C("", !0)
650
649
  ]));
651
650
  }
652
- }), Ce = (r, o) => {
651
+ }), qe = (r, o) => {
653
652
  const n = r.__vccOpts || r;
654
653
  for (const [t, e] of o)
655
654
  n[t] = e;
656
655
  return n;
657
- }, Me = /* @__PURE__ */ Ce(qe, [["__scopeId", "data-v-d7e6eec9"]]), Ae = [
656
+ }, Me = /* @__PURE__ */ qe(Ie, [["__scopeId", "data-v-d7e6eec9"]]), Be = [
658
657
  { value: "lanczos3", label: "Lanczos3" },
659
658
  { value: "catrom", label: "Catrom" },
660
659
  { value: "mitchell", label: "Mitchell" },
661
660
  { value: "triangle", label: "Triangle" },
662
661
  { value: "vector", label: "Vector" }
663
- ], Be = [
662
+ ], Ae = [
664
663
  { value: "stretch", label: "拉伸" },
665
664
  { value: "contain", label: "适应" }
666
665
  ], Fe = [
@@ -668,7 +667,7 @@ const ve = { class: "image-compressor" }, we = {
668
667
  { value: 90, label: "顺时针 90°" },
669
668
  { value: 180, label: "旋转 180°" },
670
669
  { value: 270, label: "逆时针 90°" }
671
- ], je = {
670
+ ], Re = {
672
671
  mozJPEG: "mozjpegEncode",
673
672
  webP: "webpEncode",
674
673
  avif: "avifEncode",
@@ -677,26 +676,25 @@ const ve = { class: "image-compressor" }, we = {
677
676
  qoi: "qoiEncode",
678
677
  wp2: "wp2Encode"
679
678
  };
680
- function Ge() {
679
+ function je() {
681
680
  return new Worker(
682
681
  new URL(
683
682
  /* @vite-ignore */
684
- "/assets/imageWorker-Qv3pCULy.js",
683
+ "" + new URL("assets/imageWorker-B_HCdCy9.js", import.meta.url).href,
685
684
  import.meta.url
686
- ),
687
- { type: "module" }
685
+ )
688
686
  );
689
687
  }
690
- function Re(r, o, n, t) {
688
+ function Ge(r, o, n, t) {
691
689
  return new Promise((e, s) => {
692
- const a = Ge();
690
+ const a = je();
693
691
  let p = !1;
694
692
  function u() {
695
693
  p || (p = !0, a.terminate());
696
694
  }
697
695
  a.addEventListener("message", (O) => {
698
- const { result: q, error: P } = O.data;
699
- u(), P ? s(new Error(P)) : e(q.buffer);
696
+ const { result: I, error: P } = O.data;
697
+ u(), P ? s(new Error(P)) : e(I.buffer);
700
698
  }), a.addEventListener("error", (O) => {
701
699
  u(), s(O.error || O);
702
700
  });
@@ -704,7 +702,7 @@ function Re(r, o, n, t) {
704
702
  u(), s(new DOMException("AbortError", "AbortError"));
705
703
  };
706
704
  t && t.addEventListener("abort", h, { once: !0 });
707
- const b = je[r];
705
+ const b = Re[r];
708
706
  if (!b) {
709
707
  u(), s(new Error(`Unknown encoder: ${r}`));
710
708
  return;
@@ -719,22 +717,22 @@ async function Ne(r, o = {}) {
719
717
  const t = o.encoder || "mozJPEG", e = {
720
718
  ...N[t],
721
719
  ...o.encoderOptions
722
- }, s = G[t], a = await Q(r);
720
+ }, s = j[t], a = await H(r);
723
721
  if (n != null && n.aborted)
724
722
  throw new DOMException("AbortError", "AbortError");
725
723
  let p;
726
724
  if (t === "browserJPEG")
727
- p = await (await B(
725
+ p = await (await A(
728
726
  a,
729
727
  "image/jpeg",
730
728
  e.quality
731
729
  )).arrayBuffer();
732
730
  else if (t === "browserPNG")
733
- p = await (await B(a, "image/png")).arrayBuffer();
731
+ p = await (await A(a, "image/png")).arrayBuffer();
734
732
  else {
735
733
  if (t === "browserGIF")
736
734
  throw new Error("Browser GIF encoding not supported directly");
737
- p = await Re(
735
+ p = await Ge(
738
736
  t,
739
737
  a,
740
738
  e,
@@ -743,7 +741,7 @@ async function Ne(r, o = {}) {
743
741
  }
744
742
  if (n != null && n.aborted)
745
743
  throw new DOMException("AbortError", "AbortError");
746
- const u = X(r.name, s.extension), h = H(
744
+ const u = X(r.name, s.extension), h = Q(
747
745
  p,
748
746
  u,
749
747
  s.mimeType
@@ -763,13 +761,13 @@ async function Ne(r, o = {}) {
763
761
  export {
764
762
  N as DEFAULT_ENCODER_OPTIONS,
765
763
  ae as ENCODER_LIST,
766
- G as ENCODER_REGISTRY,
767
- Be as FIT_METHODS,
764
+ j as ENCODER_REGISTRY,
765
+ Ae as FIT_METHODS,
768
766
  Me as ImageCompressor,
769
- Ae as RESIZE_METHODS,
767
+ Be as RESIZE_METHODS,
770
768
  Fe as ROTATE_OPTIONS,
771
- H as arrayBufferToFile,
772
- Q as blobToImageData,
769
+ Q as arrayBufferToFile,
770
+ H as blobToImageData,
773
771
  K as calculateSavings,
774
772
  le as canDecodeImageType,
775
773
  Ne as compressFile,
@@ -777,7 +775,7 @@ export {
777
775
  $ as formatBytes,
778
776
  X as generateCompressedFilename,
779
777
  Le as getImageDimensions,
780
- B as imageDataToBlob,
778
+ A as imageDataToBlob,
781
779
  ce as revokeBlobUrl,
782
780
  ie as sniffMimeType,
783
781
  me as useCompression,
@@ -1 +1 @@
1
- (function(u,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(u=typeof globalThis<"u"?globalThis:u||self,e(u.VueImageCompressor={},u.Vue))})(this,function(u,e){"use strict";var I=typeof document<"u"?document.currentScript:null;const B={mozJPEG:{label:"MozJPEG",mimeType:"image/jpeg",extension:"jpg"},webP:{label:"WebP",mimeType:"image/webp",extension:"webp"},avif:{label:"AVIF",mimeType:"image/avif",extension:"avif"},jxl:{label:"JPEG XL",mimeType:"image/jxl",extension:"jxl"},oxiPNG:{label:"OxiPNG",mimeType:"image/png",extension:"png"},browserJPEG:{label:"Browser JPEG",mimeType:"image/jpeg",extension:"jpg"},browserPNG:{label:"Browser PNG",mimeType:"image/png",extension:"png"},browserGIF:{label:"Browser GIF",mimeType:"image/gif",extension:"gif"},qoi:{label:"QOI",mimeType:"image/qoi",extension:"qoi"},wp2:{label:"WebP2",mimeType:"image/webp2",extension:"wp2"}},x={mozJPEG:{quality:75,baseline:!1,arithmetic:!1,progressive:!0,optimize_coding:!0,smoothing:0,color_space:3,quant_table:3,trellis_multipass:!1,trellis_opt_zero:!1,trellis_opt_table:!1,trellis_loops:1,auto_subsample:!0,chroma_subsample:2,separate_chroma_quality:!1,chroma_quality:75},webP:{quality:75,target_size:0,target_PSNR:0,method:4,sns_strength:50,filter_strength:60,filter_sharpness:0,filter_type:1,partitions:0,segments:4,pass:1,show_compressed:0,preprocessing:0,autofilter:0,partition_limit:0,alpha_compression:1,alpha_filtering:1,alpha_quality:100,lossless:0,exact:0,use_delta_palette:0,vlnr:0,near_lossless:60},avif:{cqLevel:33,denoiseLevel:0,cqAlphaLevel:-1,tileRows:0,tileCols:0,speed:6,subsample:1,chromaDeltaQ:!1,sharpness:0,tune:0},jxl:{effort:7,quality:75,progressive:!1,targetPsize:0},oxiPNG:{level:2},browserJPEG:{quality:.75},browserPNG:{},browserGIF:{},qoi:{},wp2:{quality:75}},A=Object.keys(B);async function q(r){const n=await createImageBitmap(r),a=document.createElement("canvas");a.width=n.width,a.height=n.height;const o=a.getContext("2d");return o.drawImage(n,0,0),o.getImageData(0,0,a.width,a.height)}async function N(r,n,a){const o=document.createElement("canvas");return o.width=r.width,o.height=r.height,o.getContext("2d").putImageData(r,0,0),new Promise(i=>{o.toBlob(s=>i(s),n,a)})}function Z(r){return new Promise((n,a)=>{const o=new Image;o.onload=()=>{n({width:o.width,height:o.height}),URL.revokeObjectURL(o.src)},o.onerror=a,o.src=URL.createObjectURL(r)})}async function W(r){const n=new Uint8Array(await r.slice(0,4).arrayBuffer());return n[0]===137&&n[1]===80?"image/png":n[0]===255&&n[1]===216?"image/jpeg":n[0]===71&&n[1]===73?"image/gif":n[0]===82&&n[1]===73?"image/webp":n[0]===0&&n[1]===0?"image/avif":r.type||"image/jpeg"}function J(r){return new Promise(n=>{const a=new Image;a.onload=()=>n(!0),a.onerror=()=>n(!1),a.src=`data:${r};base64,`})}function L(r,n,a){return new File([r],n,{type:a})}function M(r,n=2){if(r===0)return"0 Bytes";const a=1024,o=n<0?0:n,t=["Bytes","KB","MB","GB"],i=Math.floor(Math.log(r)/Math.log(a));return parseFloat((r/Math.pow(a,i)).toFixed(o))+" "+t[i]}function S(r,n){if(r===0)return 0;const a=Math.round((r-n)/r*100);return Math.max(0,a)}function G(r,n){return`${r.replace(/\.[^.]+$/,"")}_compressed.${n}`}function V(r){return URL.createObjectURL(r)}function $(r){URL.revokeObjectURL(r)}const X=1e4;function ee(r){let n=0;const a=new Map;r.addEventListener("message",t=>{const{id:i,result:s,error:p}=t.data,m=a.get(i);m&&(a.delete(i),p?m.reject(new Error(p)):m.resolve(s))}),r.addEventListener("error",t=>{console.error("Worker error:",{message:t.message,filename:t.filename,lineno:t.lineno,colno:t.colno,error:t.error}),a.forEach(i=>i.reject(t)),a.clear()});function o(t,...i){return new Promise((s,p)=>{const m=++n;a.set(m,{resolve:s,reject:p}),r.postMessage({id:m,method:t,args:i})})}return{avifDecode:t=>o("avifDecode",t),jxlDecode:t=>o("jxlDecode",t),qoiDecode:t=>o("qoiDecode",t),webpDecode:t=>o("webpDecode",t),wp2Decode:t=>o("wp2Decode",t),avifEncode:(t,i)=>o("avifEncode",t,i),jxlEncode:(t,i)=>o("jxlEncode",t,i),mozjpegEncode:(t,i)=>o("mozjpegEncode",t,i),oxipngEncode:(t,i)=>o("oxipngEncode",t,i),qoiEncode:(t,i)=>o("qoiEncode",t,i),webpEncode:(t,i)=>o("webpEncode",t,i),wp2Encode:(t,i)=>o("wp2Encode",t,i),rotate:(t,i)=>o("rotate",t,i),quantize:(t,i)=>o("quantize",t,i),resize:(t,i)=>o("resize",t,i)}}function H(){const r=e.ref(!1),n=e.ref(!1),a=e.ref(null);let o=null,t=null;function i(){if(!o)try{n.value=!0,o=new Worker(new URL("/assets/imageWorker-Qv3pCULy.js",typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:I&&I.tagName.toUpperCase()==="SCRIPT"&&I.src||new URL("vue-image-compressor.umd.cjs",document.baseURI).href),{type:"module"}),r.value=!0,a.value=null}catch(h){a.value=h instanceof Error?h:new Error("Failed to start worker"),console.error("Worker start failed:",h)}finally{n.value=!1}}function s(){t&&(clearTimeout(t),t=null),o&&(o.terminate(),o=null,r.value=!1)}function p(){t&&clearTimeout(t),t=window.setTimeout(()=>{s()},X)}async function m(){if(o||i(),!o)throw new Error("Worker failed to initialize");return ee(o)}async function y(h,T){if(h.aborted)throw new DOMException("AbortError","AbortError");return clearTimeout(t),new Promise((C,O)=>{const D=()=>{s(),O(new DOMException("AbortError","AbortError"))};h.addEventListener("abort",D),T().then(C).catch(O).finally(()=>{h.removeEventListener("abort",D),p()})})}return e.onUnmounted(()=>{s()}),{isReady:r,isLoading:n,error:a,worker:o,getWorkerApi:m,executeTask:y,terminateWorker:s}}function Q(){const r=e.ref(!1),n=e.ref(0),a=e.ref(null),o=e.ref(null),t=e.ref(null),{getWorkerApi:i,executeTask:s}=H(),p=e.computed(()=>r.value&&!!t.value);async function m(E,l){const c=await W(l),f=await J(c),w=await i();if(!f){if(c==="image/avif")return s(E,()=>w.avifDecode(l));if(c==="image/webp")return s(E,()=>w.webpDecode(l));if(c==="image/jxl")return s(E,()=>w.jxlDecode(l));if(c==="image/webp2")return s(E,()=>w.wp2Decode(l));if(c==="image/qoi")return s(E,()=>w.qoiDecode(l))}return q(l)}async function y(E,l,c){if(c===0)return l;const f=await i();return s(E,()=>f.rotate(l,{rotate:c}))}async function h(E,l,c){var b,k;let f=l;const w=await i();return(b=c.resize)!=null&&b.enabled&&(f=await s(E,()=>w.resize(f,{width:c.resize.width||f.width,height:c.resize.height||f.height,method:c.resize.method||"lanczos3",fitMethod:c.resize.fitMethod||"stretch",premultiply:!0,linearRGB:!0}))),(k=c.quantize)!=null&&k.enabled&&(f=await s(E,()=>w.quantize(f,{numColors:c.quantize.numColors||256,dither:c.quantize.dither||1}))),f}async function T(E,l,c){const f=await i(),w=c.encoder;if(w==="browserJPEG")return(await N(l,"image/jpeg",c.encoderOptions.quality)).arrayBuffer();if(w==="browserPNG")return(await N(l,"image/png")).arrayBuffer();if(w==="browserGIF")throw new Error("Browser GIF encoding not supported directly");const k={mozJPEG:f.mozjpegEncode,webP:f.webpEncode,avif:f.avifEncode,jxl:f.jxlEncode,oxiPNG:f.oxipngEncode,qoi:f.qoiEncode,wp2:f.wp2Encode}[w];if(!k)throw new Error(`Unknown encoder: ${w}`);return(await s(E,()=>k.call(f,l,c.encoderOptions))).buffer}async function C(E,l){var w;t.value=new AbortController;const c=t.value.signal;r.value=!0,n.value=0,a.value=null;const f=o.value;o.value=null,(w=f==null?void 0:f.compressed)!=null&&w.blobUrl&&$(f.compressed.blobUrl);try{n.value=10;const b={file:E,size:E.size,width:0,height:0,blobUrl:V(E)},k=await m(c,E);b.width=k.width,b.height=k.height,n.value=25;const P=await y(c,k,l.rotate||0);n.value=35;const z=await h(c,P,l);n.value=50;const F=await T(c,z,l);n.value=80;const v=B[l.encoder],j=G(E.name,(v==null?void 0:v.extension)||"bin"),R=L(F,j,(v==null?void 0:v.mimeType)||"application/octet-stream"),U={file:R,size:R.size,width:z.width,height:z.height,blobUrl:V(R)},g={original:b,compressed:U,savingsBytes:b.size-U.size,savingsPercent:S(b.size,U.size),encoderType:l.encoder,encoderOptions:l.encoderOptions};return o.value=g,n.value=100,g}catch(b){if(b instanceof DOMException&&b.name==="AbortError")throw a.value="已取消",b;const k=b instanceof Error?b.message:"压缩失败";throw a.value=k,console.error("Compression error:",b),b}finally{r.value=!1,t.value=null}}function O(){t.value&&t.value.abort()}function D(){if(!o.value)return;const{compressed:E}=o.value,l=document.createElement("a");l.href=E.blobUrl,l.download=E.file.name,document.body.appendChild(l),l.click(),document.body.removeChild(l)}return{compress:C,cancel:O,downloadResult:D,isCompressing:r,progress:n,error:a,result:o,canCancel:p}}function K(){const r=e.ref("mozJPEG"),n=e.ref({}),a=e.computed(()=>B[r.value]),o=e.computed(()=>x[r.value]),t=e.computed(()=>A.map(m=>({type:m,label:B[m].label,mimeType:B[m].mimeType,extension:B[m].extension})));function i(m){r.value=m,n.value={...x[m]}}function s(m,y){n.value={...n.value,[m]:y}}function p(){n.value={...o.value}}return p(),{selectedEncoder:r,encoderOptions:n,currentMeta:a,currentDefaults:o,availableEncoders:t,selectEncoder:i,updateOption:s,resetOptions:p}}const te={class:"image-compressor"},oe={key:0,class:"preview-area"},ne={class:"preview-item"},re=["src"],ae={class:"preview-item"},ie=["src"],se={key:1,class:"compressing"},le=["value"],ce={key:2},de={key:1,class:"encoder-settings"},me=["value"],ue={key:0,class:"quality-control"},fe=["value"],pe={key:2,class:"actions"},ge=["disabled"],Ee={key:3,class:"error"},we=((r,n)=>{const a=r.__vccOpts||r;for(const[o,t]of n)a[o]=t;return a})(e.defineComponent({__name:"ImageCompressor",props:{defaultEncoder:{},defaultOptions:{}},emits:["success","error","cancel"],setup(r,{emit:n}){const a=r,o=n,t=e.ref(null),i=e.ref(null),s=e.ref(""),p=e.ref(""),{compress:m,cancel:y,downloadResult:h,isCompressing:T,progress:C,error:O,result:D,canCancel:E}=Q(),{selectedEncoder:l,encoderOptions:c,availableEncoders:f,selectEncoder:w,updateOption:b}=K();a.defaultEncoder&&w(a.defaultEncoder),a.defaultOptions&&Object.entries(a.defaultOptions).forEach(([g,d])=>b(g,d));const k=e.computed(()=>i.value?M(i.value.size):""),P=e.computed(()=>D.value?M(D.value.compressed.size):""),z=e.computed(()=>["mozJPEG","webP","jxl","browserJPEG","wp2"].includes(l.value));function F(g){const d=g.target;d.files&&d.files[0]&&j(d.files[0])}function v(g){var d;(d=g.dataTransfer)!=null&&d.files[0]&&j(g.dataTransfer.files[0])}function j(g){g.type.startsWith("image/")&&(s.value&&URL.revokeObjectURL(s.value),p.value&&(URL.revokeObjectURL(p.value),p.value=""),i.value=g,s.value=URL.createObjectURL(g))}function R(){w(l.value)}async function U(){if(i.value)try{const g={encoder:l.value,encoderOptions:{...c.value}},d=await m(i.value,g);p.value=d.compressed.blobUrl,o("success",d)}catch(g){if(g instanceof DOMException&&g.name==="AbortError"){o("cancel");return}o("error",g instanceof Error?g:new Error(String(g)))}}return(g,d)=>(e.openBlock(),e.createElementBlock("div",te,[e.createElementVNode("div",{class:"upload-zone",onDrop:e.withModifiers(v,["prevent"]),onDragover:d[1]||(d[1]=e.withModifiers(()=>{},["prevent"]))},[e.createElementVNode("input",{type:"file",accept:"image/*",onChange:F,ref_key:"fileInput",ref:t,class:"file-input"},null,544),e.createElementVNode("div",{class:"upload-prompt",onClick:d[0]||(d[0]=_=>{var Y;return(Y=t.value)==null?void 0:Y.click()})},[e.renderSlot(g.$slots,"upload-prompt",{},()=>[d[6]||(d[6]=e.createElementVNode("p",null,"拖拽图片到此处,或点击上传",-1))],!0)])],32),s.value?(e.openBlock(),e.createElementBlock("div",oe,[e.createElementVNode("div",ne,[d[7]||(d[7]=e.createElementVNode("h4",null,"原始图片",-1)),e.createElementVNode("img",{src:s.value,alt:"Original"},null,8,re),e.createElementVNode("p",null,e.toDisplayString(k.value),1)]),e.createElementVNode("div",ae,[d[8]||(d[8]=e.createElementVNode("h4",null,"压缩后",-1)),p.value?(e.openBlock(),e.createElementBlock("img",{key:0,src:p.value,alt:"Compressed"},null,8,ie)):e.unref(T)?(e.openBlock(),e.createElementBlock("div",se,[e.createElementVNode("progress",{value:e.unref(C),max:"100"},null,8,le),e.createElementVNode("p",null,"压缩中... "+e.toDisplayString(e.unref(C))+"%",1)])):e.createCommentVNode("",!0),P.value?(e.openBlock(),e.createElementBlock("p",ce,e.toDisplayString(P.value),1)):e.createCommentVNode("",!0)])])):e.createCommentVNode("",!0),s.value?(e.openBlock(),e.createElementBlock("div",de,[d[9]||(d[9]=e.createElementVNode("label",null,"编码器:",-1)),e.withDirectives(e.createElementVNode("select",{"onUpdate:modelValue":d[2]||(d[2]=_=>e.isRef(l)?l.value=_:null),onChange:R},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(f),_=>(e.openBlock(),e.createElementBlock("option",{key:_.type,value:_.type},e.toDisplayString(_.label)+" ("+e.toDisplayString(_.extension)+") ",9,me))),128))],544),[[e.vModelSelect,e.unref(l)]]),z.value?(e.openBlock(),e.createElementBlock("div",ue,[e.createElementVNode("label",null,[e.createTextVNode(" 质量: "+e.toDisplayString(e.unref(c).quality??75)+" ",1),e.createElementVNode("input",{type:"range",min:"0",max:"100",value:e.unref(c).quality??75,onInput:d[3]||(d[3]=_=>e.unref(b)("quality",Number(_.target.value)))},null,40,fe)])])):e.createCommentVNode("",!0),e.renderSlot(g.$slots,"encoder-settings",{encoder:e.unref(l),options:e.unref(c)},void 0,!0)])):e.createCommentVNode("",!0),s.value?(e.openBlock(),e.createElementBlock("div",pe,[e.createElementVNode("button",{onClick:U,disabled:e.unref(T),class:"btn-primary"},e.toDisplayString(e.unref(T)?"压缩中...":"开始压缩"),9,ge),e.unref(E)?(e.openBlock(),e.createElementBlock("button",{key:0,onClick:d[4]||(d[4]=(..._)=>e.unref(y)&&e.unref(y)(..._)),class:"btn-secondary"}," 取消 ")):e.createCommentVNode("",!0),e.unref(D)?(e.openBlock(),e.createElementBlock("button",{key:1,onClick:d[5]||(d[5]=(..._)=>e.unref(h)&&e.unref(h)(..._)),class:"btn-success"}," 下载 (节省 "+e.toDisplayString(e.unref(D).savingsPercent)+"%) ",1)):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0),e.unref(O)?(e.openBlock(),e.createElementBlock("div",Ee,e.toDisplayString(e.unref(O)),1)):e.createCommentVNode("",!0)]))}}),[["__scopeId","data-v-d7e6eec9"]]),be=[{value:"lanczos3",label:"Lanczos3"},{value:"catrom",label:"Catrom"},{value:"mitchell",label:"Mitchell"},{value:"triangle",label:"Triangle"},{value:"vector",label:"Vector"}],he=[{value:"stretch",label:"拉伸"},{value:"contain",label:"适应"}],ye=[{value:0,label:"不旋转"},{value:90,label:"顺时针 90°"},{value:180,label:"旋转 180°"},{value:270,label:"逆时针 90°"}],ke={mozJPEG:"mozjpegEncode",webP:"webpEncode",avif:"avifEncode",jxl:"jxlEncode",oxiPNG:"oxipngEncode",qoi:"qoiEncode",wp2:"wp2Encode"};function _e(){return new Worker(new URL("/assets/imageWorker-Qv3pCULy.js",typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:I&&I.tagName.toUpperCase()==="SCRIPT"&&I.src||new URL("vue-image-compressor.umd.cjs",document.baseURI).href),{type:"module"})}function Te(r,n,a,o){return new Promise((t,i)=>{const s=_e();let p=!1;function m(){p||(p=!0,s.terminate())}s.addEventListener("message",T=>{const{result:C,error:O}=T.data;m(),O?i(new Error(O)):t(C.buffer)}),s.addEventListener("error",T=>{m(),i(T.error||T)});const y=()=>{m(),i(new DOMException("AbortError","AbortError"))};o&&o.addEventListener("abort",y,{once:!0});const h=ke[r];if(!h){m(),i(new Error(`Unknown encoder: ${r}`));return}s.postMessage({id:1,method:h,args:[n,a]})})}async function Oe(r,n={}){const{signal:a}=n;if(a!=null&&a.aborted)throw new DOMException("AbortError","AbortError");const o=n.encoder||"mozJPEG",t={...x[o],...n.encoderOptions},i=B[o],s=await q(r);if(a!=null&&a.aborted)throw new DOMException("AbortError","AbortError");let p;if(o==="browserJPEG")p=await(await N(s,"image/jpeg",t.quality)).arrayBuffer();else if(o==="browserPNG")p=await(await N(s,"image/png")).arrayBuffer();else{if(o==="browserGIF")throw new Error("Browser GIF encoding not supported directly");p=await Te(o,s,t,a)}if(a!=null&&a.aborted)throw new DOMException("AbortError","AbortError");const m=G(r.name,i.extension),y=L(p,m,i.mimeType);return{file:y,originalSize:r.size,compressedSize:y.size,savingsBytes:r.size-y.size,savingsPercent:S(r.size,y.size),width:s.width,height:s.height,encoderType:o,encoderOptions:t}}u.DEFAULT_ENCODER_OPTIONS=x,u.ENCODER_LIST=A,u.ENCODER_REGISTRY=B,u.FIT_METHODS=he,u.ImageCompressor=we,u.RESIZE_METHODS=be,u.ROTATE_OPTIONS=ye,u.arrayBufferToFile=L,u.blobToImageData=q,u.calculateSavings=S,u.canDecodeImageType=J,u.compressFile=Oe,u.createBlobUrl=V,u.formatBytes=M,u.generateCompressedFilename=G,u.getImageDimensions=Z,u.imageDataToBlob=N,u.revokeBlobUrl=$,u.sniffMimeType=W,u.useCompression=Q,u.useEncoderRegistry=K,u.useWorker=H,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
1
+ (function(u,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(u=typeof globalThis<"u"?globalThis:u||self,e(u.VueImageCompressor={},u.Vue))})(this,function(u,e){"use strict";var N=typeof document<"u"?document.currentScript:null;const O={mozJPEG:{label:"MozJPEG",mimeType:"image/jpeg",extension:"jpg"},webP:{label:"WebP",mimeType:"image/webp",extension:"webp"},avif:{label:"AVIF",mimeType:"image/avif",extension:"avif"},jxl:{label:"JPEG XL",mimeType:"image/jxl",extension:"jxl"},oxiPNG:{label:"OxiPNG",mimeType:"image/png",extension:"png"},browserJPEG:{label:"Browser JPEG",mimeType:"image/jpeg",extension:"jpg"},browserPNG:{label:"Browser PNG",mimeType:"image/png",extension:"png"},browserGIF:{label:"Browser GIF",mimeType:"image/gif",extension:"gif"},qoi:{label:"QOI",mimeType:"image/qoi",extension:"qoi"},wp2:{label:"WebP2",mimeType:"image/webp2",extension:"wp2"}},S={mozJPEG:{quality:75,baseline:!1,arithmetic:!1,progressive:!0,optimize_coding:!0,smoothing:0,color_space:3,quant_table:3,trellis_multipass:!1,trellis_opt_zero:!1,trellis_opt_table:!1,trellis_loops:1,auto_subsample:!0,chroma_subsample:2,separate_chroma_quality:!1,chroma_quality:75},webP:{quality:75,target_size:0,target_PSNR:0,method:4,sns_strength:50,filter_strength:60,filter_sharpness:0,filter_type:1,partitions:0,segments:4,pass:1,show_compressed:0,preprocessing:0,autofilter:0,partition_limit:0,alpha_compression:1,alpha_filtering:1,alpha_quality:100,lossless:0,exact:0,use_delta_palette:0,vlnr:0,near_lossless:60},avif:{cqLevel:33,denoiseLevel:0,cqAlphaLevel:-1,tileRows:0,tileCols:0,speed:6,subsample:1,chromaDeltaQ:!1,sharpness:0,tune:0},jxl:{effort:7,quality:75,progressive:!1,targetPsize:0},oxiPNG:{level:2},browserJPEG:{quality:.75},browserPNG:{},browserGIF:{},qoi:{},wp2:{quality:75}},A=Object.keys(O);async function j(r){const n=await createImageBitmap(r),a=document.createElement("canvas");a.width=n.width,a.height=n.height;const o=a.getContext("2d");return o.drawImage(n,0,0),o.getImageData(0,0,a.width,a.height)}async function z(r,n,a){const o=document.createElement("canvas");return o.width=r.width,o.height=r.height,o.getContext("2d").putImageData(r,0,0),new Promise(i=>{o.toBlob(s=>i(s),n,a)})}function Z(r){return new Promise((n,a)=>{const o=new Image;o.onload=()=>{n({width:o.width,height:o.height}),URL.revokeObjectURL(o.src)},o.onerror=a,o.src=URL.createObjectURL(r)})}async function W(r){const n=new Uint8Array(await r.slice(0,4).arrayBuffer());return n[0]===137&&n[1]===80?"image/png":n[0]===255&&n[1]===216?"image/jpeg":n[0]===71&&n[1]===73?"image/gif":n[0]===82&&n[1]===73?"image/webp":n[0]===0&&n[1]===0?"image/avif":r.type||"image/jpeg"}function J(r){return new Promise(n=>{const a=new Image;a.onload=()=>n(!0),a.onerror=()=>n(!1),a.src=`data:${r};base64,`})}function q(r,n,a){return new File([r],n,{type:a})}function L(r,n=2){if(r===0)return"0 Bytes";const a=1024,o=n<0?0:n,t=["Bytes","KB","MB","GB"],i=Math.floor(Math.log(r)/Math.log(a));return parseFloat((r/Math.pow(a,i)).toFixed(o))+" "+t[i]}function M(r,n){if(r===0)return 0;const a=Math.round((r-n)/r*100);return Math.max(0,a)}function G(r,n){return`${r.replace(/\.[^.]+$/,"")}_compressed.${n}`}function F(r){return URL.createObjectURL(r)}function H(r){URL.revokeObjectURL(r)}const X=1e4;function ee(r){let n=0;const a=new Map;r.addEventListener("message",t=>{const{id:i,result:s,error:p}=t.data,m=a.get(i);m&&(a.delete(i),p?m.reject(new Error(p)):m.resolve(s))}),r.addEventListener("error",t=>{console.error("Worker error:",{message:t.message,filename:t.filename,lineno:t.lineno,colno:t.colno,error:t.error}),a.forEach(i=>i.reject(t)),a.clear()});function o(t,...i){return new Promise((s,p)=>{const m=++n;a.set(m,{resolve:s,reject:p}),r.postMessage({id:m,method:t,args:i})})}return{avifDecode:t=>o("avifDecode",t),jxlDecode:t=>o("jxlDecode",t),qoiDecode:t=>o("qoiDecode",t),webpDecode:t=>o("webpDecode",t),wp2Decode:t=>o("wp2Decode",t),avifEncode:(t,i)=>o("avifEncode",t,i),jxlEncode:(t,i)=>o("jxlEncode",t,i),mozjpegEncode:(t,i)=>o("mozjpegEncode",t,i),oxipngEncode:(t,i)=>o("oxipngEncode",t,i),qoiEncode:(t,i)=>o("qoiEncode",t,i),webpEncode:(t,i)=>o("webpEncode",t,i),wp2Encode:(t,i)=>o("wp2Encode",t,i),rotate:(t,i)=>o("rotate",t,i),quantize:(t,i)=>o("quantize",t,i),resize:(t,i)=>o("resize",t,i)}}function $(){const r=e.ref(!1),n=e.ref(!1),a=e.ref(null);let o=null,t=null;function i(){if(!o)try{n.value=!0,o=new Worker(new URL(""+(typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__dirname+"/assets/imageWorker-B_HCdCy9.js").href:new URL("assets/imageWorker-B_HCdCy9.js",typeof document>"u"?location.href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href),typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:N&&N.tagName.toUpperCase()==="SCRIPT"&&N.src||new URL("vue-image-compressor.umd.cjs",document.baseURI).href)),r.value=!0,a.value=null}catch(h){a.value=h instanceof Error?h:new Error("Failed to start worker"),console.error("Worker start failed:",h)}finally{n.value=!1}}function s(){t&&(clearTimeout(t),t=null),o&&(o.terminate(),o=null,r.value=!1)}function p(){t&&clearTimeout(t),t=window.setTimeout(()=>{s()},X)}async function m(){if(o||i(),!o)throw new Error("Worker failed to initialize");return ee(o)}async function y(h,T){if(h.aborted)throw new DOMException("AbortError","AbortError");return clearTimeout(t),new Promise((D,C)=>{const B=()=>{s(),C(new DOMException("AbortError","AbortError"))};h.addEventListener("abort",B),T().then(D).catch(C).finally(()=>{h.removeEventListener("abort",B),p()})})}return e.onUnmounted(()=>{s()}),{isReady:r,isLoading:n,error:a,worker:o,getWorkerApi:m,executeTask:y,terminateWorker:s}}function Q(){const r=e.ref(!1),n=e.ref(0),a=e.ref(null),o=e.ref(null),t=e.ref(null),{getWorkerApi:i,executeTask:s}=$(),p=e.computed(()=>r.value&&!!t.value);async function m(E,l){const c=await W(l),f=await J(c),w=await i();if(!f){if(c==="image/avif")return s(E,()=>w.avifDecode(l));if(c==="image/webp")return s(E,()=>w.webpDecode(l));if(c==="image/jxl")return s(E,()=>w.jxlDecode(l));if(c==="image/webp2")return s(E,()=>w.wp2Decode(l));if(c==="image/qoi")return s(E,()=>w.qoiDecode(l))}return j(l)}async function y(E,l,c){if(c===0)return l;const f=await i();return s(E,()=>f.rotate(l,{rotate:c}))}async function h(E,l,c){var b,_;let f=l;const w=await i();return(b=c.resize)!=null&&b.enabled&&(f=await s(E,()=>w.resize(f,{width:c.resize.width||f.width,height:c.resize.height||f.height,method:c.resize.method||"lanczos3",fitMethod:c.resize.fitMethod||"stretch",premultiply:!0,linearRGB:!0}))),(_=c.quantize)!=null&&_.enabled&&(f=await s(E,()=>w.quantize(f,{numColors:c.quantize.numColors||256,dither:c.quantize.dither||1}))),f}async function T(E,l,c){const f=await i(),w=c.encoder;if(w==="browserJPEG")return(await z(l,"image/jpeg",c.encoderOptions.quality)).arrayBuffer();if(w==="browserPNG")return(await z(l,"image/png")).arrayBuffer();if(w==="browserGIF")throw new Error("Browser GIF encoding not supported directly");const _={mozJPEG:f.mozjpegEncode,webP:f.webpEncode,avif:f.avifEncode,jxl:f.jxlEncode,oxiPNG:f.oxipngEncode,qoi:f.qoiEncode,wp2:f.wp2Encode}[w];if(!_)throw new Error(`Unknown encoder: ${w}`);return(await s(E,()=>_.call(f,l,c.encoderOptions))).buffer}async function D(E,l){var w;t.value=new AbortController;const c=t.value.signal;r.value=!0,n.value=0,a.value=null;const f=o.value;o.value=null,(w=f==null?void 0:f.compressed)!=null&&w.blobUrl&&H(f.compressed.blobUrl);try{n.value=10;const b={file:E,size:E.size,width:0,height:0,blobUrl:F(E)},_=await m(c,E);b.width=_.width,b.height=_.height,n.value=25;const P=await y(c,_,l.rotate||0);n.value=35;const I=await h(c,P,l);n.value=50;const V=await T(c,I,l);n.value=80;const R=O[l.encoder],x=G(E.name,(R==null?void 0:R.extension)||"bin"),v=q(V,x,(R==null?void 0:R.mimeType)||"application/octet-stream"),U={file:v,size:v.size,width:I.width,height:I.height,blobUrl:F(v)},g={original:b,compressed:U,savingsBytes:b.size-U.size,savingsPercent:M(b.size,U.size),encoderType:l.encoder,encoderOptions:l.encoderOptions};return o.value=g,n.value=100,g}catch(b){if(b instanceof DOMException&&b.name==="AbortError")throw a.value="已取消",b;const _=b instanceof Error?b.message:"压缩失败";throw a.value=_,console.error("Compression error:",b),b}finally{r.value=!1,t.value=null}}function C(){t.value&&t.value.abort()}function B(){if(!o.value)return;const{compressed:E}=o.value,l=document.createElement("a");l.href=E.blobUrl,l.download=E.file.name,document.body.appendChild(l),l.click(),document.body.removeChild(l)}return{compress:D,cancel:C,downloadResult:B,isCompressing:r,progress:n,error:a,result:o,canCancel:p}}function K(){const r=e.ref("mozJPEG"),n=e.ref({}),a=e.computed(()=>O[r.value]),o=e.computed(()=>S[r.value]),t=e.computed(()=>A.map(m=>({type:m,label:O[m].label,mimeType:O[m].mimeType,extension:O[m].extension})));function i(m){r.value=m,n.value={...S[m]}}function s(m,y){n.value={...n.value,[m]:y}}function p(){n.value={...o.value}}return p(),{selectedEncoder:r,encoderOptions:n,currentMeta:a,currentDefaults:o,availableEncoders:t,selectEncoder:i,updateOption:s,resetOptions:p}}const te={class:"image-compressor"},oe={key:0,class:"preview-area"},ne={class:"preview-item"},re=["src"],ae={class:"preview-item"},ie=["src"],se={key:1,class:"compressing"},le=["value"],ce={key:2},de={key:1,class:"encoder-settings"},me=["value"],ue={key:0,class:"quality-control"},fe=["value"],pe={key:2,class:"actions"},ge=["disabled"],Ee={key:3,class:"error"},we=((r,n)=>{const a=r.__vccOpts||r;for(const[o,t]of n)a[o]=t;return a})(e.defineComponent({__name:"ImageCompressor",props:{defaultEncoder:{},defaultOptions:{}},emits:["success","error","cancel"],setup(r,{emit:n}){const a=r,o=n,t=e.ref(null),i=e.ref(null),s=e.ref(""),p=e.ref(""),{compress:m,cancel:y,downloadResult:h,isCompressing:T,progress:D,error:C,result:B,canCancel:E}=Q(),{selectedEncoder:l,encoderOptions:c,availableEncoders:f,selectEncoder:w,updateOption:b}=K();a.defaultEncoder&&w(a.defaultEncoder),a.defaultOptions&&Object.entries(a.defaultOptions).forEach(([g,d])=>b(g,d));const _=e.computed(()=>i.value?L(i.value.size):""),P=e.computed(()=>B.value?L(B.value.compressed.size):""),I=e.computed(()=>["mozJPEG","webP","jxl","browserJPEG","wp2"].includes(l.value));function V(g){const d=g.target;d.files&&d.files[0]&&x(d.files[0])}function R(g){var d;(d=g.dataTransfer)!=null&&d.files[0]&&x(g.dataTransfer.files[0])}function x(g){g.type.startsWith("image/")&&(s.value&&URL.revokeObjectURL(s.value),p.value&&(URL.revokeObjectURL(p.value),p.value=""),i.value=g,s.value=URL.createObjectURL(g))}function v(){w(l.value)}async function U(){if(i.value)try{const g={encoder:l.value,encoderOptions:{...c.value}},d=await m(i.value,g);p.value=d.compressed.blobUrl,o("success",d)}catch(g){if(g instanceof DOMException&&g.name==="AbortError"){o("cancel");return}o("error",g instanceof Error?g:new Error(String(g)))}}return(g,d)=>(e.openBlock(),e.createElementBlock("div",te,[e.createElementVNode("div",{class:"upload-zone",onDrop:e.withModifiers(R,["prevent"]),onDragover:d[1]||(d[1]=e.withModifiers(()=>{},["prevent"]))},[e.createElementVNode("input",{type:"file",accept:"image/*",onChange:V,ref_key:"fileInput",ref:t,class:"file-input"},null,544),e.createElementVNode("div",{class:"upload-prompt",onClick:d[0]||(d[0]=k=>{var Y;return(Y=t.value)==null?void 0:Y.click()})},[e.renderSlot(g.$slots,"upload-prompt",{},()=>[d[6]||(d[6]=e.createElementVNode("p",null,"拖拽图片到此处,或点击上传",-1))],!0)])],32),s.value?(e.openBlock(),e.createElementBlock("div",oe,[e.createElementVNode("div",ne,[d[7]||(d[7]=e.createElementVNode("h4",null,"原始图片",-1)),e.createElementVNode("img",{src:s.value,alt:"Original"},null,8,re),e.createElementVNode("p",null,e.toDisplayString(_.value),1)]),e.createElementVNode("div",ae,[d[8]||(d[8]=e.createElementVNode("h4",null,"压缩后",-1)),p.value?(e.openBlock(),e.createElementBlock("img",{key:0,src:p.value,alt:"Compressed"},null,8,ie)):e.unref(T)?(e.openBlock(),e.createElementBlock("div",se,[e.createElementVNode("progress",{value:e.unref(D),max:"100"},null,8,le),e.createElementVNode("p",null,"压缩中... "+e.toDisplayString(e.unref(D))+"%",1)])):e.createCommentVNode("",!0),P.value?(e.openBlock(),e.createElementBlock("p",ce,e.toDisplayString(P.value),1)):e.createCommentVNode("",!0)])])):e.createCommentVNode("",!0),s.value?(e.openBlock(),e.createElementBlock("div",de,[d[9]||(d[9]=e.createElementVNode("label",null,"编码器:",-1)),e.withDirectives(e.createElementVNode("select",{"onUpdate:modelValue":d[2]||(d[2]=k=>e.isRef(l)?l.value=k:null),onChange:v},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(f),k=>(e.openBlock(),e.createElementBlock("option",{key:k.type,value:k.type},e.toDisplayString(k.label)+" ("+e.toDisplayString(k.extension)+") ",9,me))),128))],544),[[e.vModelSelect,e.unref(l)]]),I.value?(e.openBlock(),e.createElementBlock("div",ue,[e.createElementVNode("label",null,[e.createTextVNode(" 质量: "+e.toDisplayString(e.unref(c).quality??75)+" ",1),e.createElementVNode("input",{type:"range",min:"0",max:"100",value:e.unref(c).quality??75,onInput:d[3]||(d[3]=k=>e.unref(b)("quality",Number(k.target.value)))},null,40,fe)])])):e.createCommentVNode("",!0),e.renderSlot(g.$slots,"encoder-settings",{encoder:e.unref(l),options:e.unref(c)},void 0,!0)])):e.createCommentVNode("",!0),s.value?(e.openBlock(),e.createElementBlock("div",pe,[e.createElementVNode("button",{onClick:U,disabled:e.unref(T),class:"btn-primary"},e.toDisplayString(e.unref(T)?"压缩中...":"开始压缩"),9,ge),e.unref(E)?(e.openBlock(),e.createElementBlock("button",{key:0,onClick:d[4]||(d[4]=(...k)=>e.unref(y)&&e.unref(y)(...k)),class:"btn-secondary"}," 取消 ")):e.createCommentVNode("",!0),e.unref(B)?(e.openBlock(),e.createElementBlock("button",{key:1,onClick:d[5]||(d[5]=(...k)=>e.unref(h)&&e.unref(h)(...k)),class:"btn-success"}," 下载 (节省 "+e.toDisplayString(e.unref(B).savingsPercent)+"%) ",1)):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0),e.unref(C)?(e.openBlock(),e.createElementBlock("div",Ee,e.toDisplayString(e.unref(C)),1)):e.createCommentVNode("",!0)]))}}),[["__scopeId","data-v-d7e6eec9"]]),be=[{value:"lanczos3",label:"Lanczos3"},{value:"catrom",label:"Catrom"},{value:"mitchell",label:"Mitchell"},{value:"triangle",label:"Triangle"},{value:"vector",label:"Vector"}],he=[{value:"stretch",label:"拉伸"},{value:"contain",label:"适应"}],ye=[{value:0,label:"不旋转"},{value:90,label:"顺时针 90°"},{value:180,label:"旋转 180°"},{value:270,label:"逆时针 90°"}],_e={mozJPEG:"mozjpegEncode",webP:"webpEncode",avif:"avifEncode",jxl:"jxlEncode",oxiPNG:"oxipngEncode",qoi:"qoiEncode",wp2:"wp2Encode"};function ke(){return new Worker(new URL(""+(typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__dirname+"/assets/imageWorker-B_HCdCy9.js").href:new URL("assets/imageWorker-B_HCdCy9.js",typeof document>"u"?location.href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href),typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:N&&N.tagName.toUpperCase()==="SCRIPT"&&N.src||new URL("vue-image-compressor.umd.cjs",document.baseURI).href))}function Te(r,n,a,o){return new Promise((t,i)=>{const s=ke();let p=!1;function m(){p||(p=!0,s.terminate())}s.addEventListener("message",T=>{const{result:D,error:C}=T.data;m(),C?i(new Error(C)):t(D.buffer)}),s.addEventListener("error",T=>{m(),i(T.error||T)});const y=()=>{m(),i(new DOMException("AbortError","AbortError"))};o&&o.addEventListener("abort",y,{once:!0});const h=_e[r];if(!h){m(),i(new Error(`Unknown encoder: ${r}`));return}s.postMessage({id:1,method:h,args:[n,a]})})}async function Ce(r,n={}){const{signal:a}=n;if(a!=null&&a.aborted)throw new DOMException("AbortError","AbortError");const o=n.encoder||"mozJPEG",t={...S[o],...n.encoderOptions},i=O[o],s=await j(r);if(a!=null&&a.aborted)throw new DOMException("AbortError","AbortError");let p;if(o==="browserJPEG")p=await(await z(s,"image/jpeg",t.quality)).arrayBuffer();else if(o==="browserPNG")p=await(await z(s,"image/png")).arrayBuffer();else{if(o==="browserGIF")throw new Error("Browser GIF encoding not supported directly");p=await Te(o,s,t,a)}if(a!=null&&a.aborted)throw new DOMException("AbortError","AbortError");const m=G(r.name,i.extension),y=q(p,m,i.mimeType);return{file:y,originalSize:r.size,compressedSize:y.size,savingsBytes:r.size-y.size,savingsPercent:M(r.size,y.size),width:s.width,height:s.height,encoderType:o,encoderOptions:t}}u.DEFAULT_ENCODER_OPTIONS=S,u.ENCODER_LIST=A,u.ENCODER_REGISTRY=O,u.FIT_METHODS=he,u.ImageCompressor=we,u.RESIZE_METHODS=be,u.ROTATE_OPTIONS=ye,u.arrayBufferToFile=q,u.blobToImageData=j,u.calculateSavings=M,u.canDecodeImageType=J,u.compressFile=Ce,u.createBlobUrl=F,u.formatBytes=L,u.generateCompressedFilename=G,u.getImageDimensions=Z,u.imageDataToBlob=z,u.revokeBlobUrl=H,u.sniffMimeType=W,u.useCompression=Q,u.useEncoderRegistry=K,u.useWorker=$,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue3-image-compressor",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Vue3 + TypeScript 图片压缩组件,基于 Squoosh 核心原理",
5
5
  "type": "module",
6
6
  "main": "./dist/vue-image-compressor.umd.cjs",
@@ -87,8 +87,7 @@ export function useWorker() {
87
87
  try {
88
88
  isLoading.value = true;
89
89
  worker = new Worker(
90
- new URL('../workers/imageWorker.ts', import.meta.url),
91
- { type: 'module' }
90
+ new URL('../workers/imageWorker.ts', import.meta.url)
92
91
  );
93
92
  isReady.value = true;
94
93
  error.value = null;
@@ -51,8 +51,7 @@ const ENCODER_METHOD_MAP: Record<string, string> = {
51
51
 
52
52
  function createWorker(): Worker {
53
53
  return new Worker(
54
- new URL('../workers/imageWorker.ts', import.meta.url),
55
- { type: 'module' }
54
+ new URL('../workers/imageWorker.ts', import.meta.url)
56
55
  );
57
56
  }
58
57
 
@@ -82,7 +82,7 @@ const workerApi: WorkerApi = {
82
82
  return initEmscriptenModule(mozjpeg_enc, {
83
83
  locateFile: (path: string) => {
84
84
  if (path === 'mozjpeg_enc.wasm') {
85
- return '/codecs/mozjpeg/enc/mozjpeg_enc.wasm';
85
+ return '../codecs/mozjpeg/enc/mozjpeg_enc.wasm';
86
86
  }
87
87
  return path;
88
88
  },