Ver código fonte

feat: use upng

Arnošt Pleskot 2 anos atrás
pai
commit
b3d95d9307
4 arquivos alterados com 28 adições e 87 exclusões
  1. 2 2
      package.json
  2. 13 68
      src/data/blob.ts
  3. 0 4
      src/global.d.ts
  4. 13 13
      yarn.lock

+ 2 - 2
package.json

@@ -44,7 +44,6 @@
     "png-chunk-text": "1.0.0",
     "png-chunks-encode": "1.0.0",
     "png-chunks-extract": "1.0.0",
-    "pngjs": "7.0.0",
     "points-on-curve": "0.2.0",
     "pwacompat": "2.0.17",
     "react": "18.2.0",
@@ -54,6 +53,7 @@
     "sass": "1.51.0",
     "socket.io-client": "2.3.1",
     "tunnel-rat": "0.1.2",
+    "upng-js": "2.1.0",
     "workbox-background-sync": "^6.5.4",
     "workbox-broadcast-update": "^6.5.4",
     "workbox-cacheable-response": "^6.5.4",
@@ -75,11 +75,11 @@
     "@types/lodash.throttle": "4.1.7",
     "@types/pako": "1.0.3",
     "@types/pica": "5.1.3",
-    "@types/pngjs": "6.0.1",
     "@types/react": "18.0.15",
     "@types/react-dom": "18.0.6",
     "@types/resize-observer-browser": "0.1.7",
     "@types/socket.io-client": "1.4.36",
+    "@types/upng-js": "2.1.2",
     "chai": "4.3.6",
     "dotenv": "16.0.1",
     "eslint-config-prettier": "8.5.0",

+ 13 - 68
src/data/blob.ts

@@ -13,7 +13,7 @@ import { FileSystemHandle, nativeFileSystemSupported } from "./filesystem";
 import { isValidExcalidrawData, isValidLibrary } from "./json";
 import { restore, restoreLibraryItems } from "./restore";
 import { ImportedLibraryData } from "./types";
-import { PNG } from "pngjs/browser";
+import UPNG from "upng-js";
 
 const parseFileContents = async (blob: Blob | File) => {
   let contents: string;
@@ -234,81 +234,26 @@ const _canvasToBlob = async (canvas: HTMLCanvasElement): Promise<Blob> => {
 export const canvasToBlob = async (
   canvas: HTMLCanvasElement,
 ): Promise<Blob> => {
-  const tileWidth = 1000;
-  const tileHeight = 1000;
-  const tileDataArray: Uint8ClampedArray[][] = []; // Two-dimensional array to store tile data
-
-  const { width: canvasWidth, height: canvasHeight } = canvas;
-
   const ctx = canvas.getContext("2d");
 
   if (!ctx) {
     throw new Error("No canvas context");
   }
 
-  // Function to process each tile
-  function processTile(tileX: number, tileY: number) {
-    // Calculate the starting and ending coordinates for the tile
-    const startX = tileX * tileWidth;
-    const startY = tileY * tileHeight;
-    const endX = Math.min(startX + tileWidth, canvasWidth);
-    const endY = Math.min(startY + tileHeight, canvasHeight);
-
-    // Get the image data for the tile directly from the main canvas
-    const imageData = ctx!.getImageData(
-      startX,
-      startY,
-      endX - startX,
-      endY - startY,
-    ).data;
-
-    // Store the tile data in the two-dimensional array
-    tileDataArray[tileY] = tileDataArray[tileY] || [];
-    tileDataArray[tileY][tileX] = imageData;
-  }
+  console.time("getImageData");
+  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
+  console.timeEnd("getImageData");
 
-  console.time("tiling");
-  // Iterate over the tiles and process each one
-  for (let tileY = 0; tileY < canvasHeight / tileHeight; tileY++) {
-    for (let tileX = 0; tileX < canvasWidth / tileWidth; tileX++) {
-      processTile(tileX, tileY);
-    }
-  }
-  console.timeEnd("tiling");
-
-  console.time("create png");
-  // Create a new PNG image with the final dimensions
-  const finalImage = new PNG({ width: canvasWidth, height: canvasHeight });
-  console.timeEnd("create png");
-
-  console.time("concat tiles");
-  // Merge the tiles into the final image
-  for (let tileY = 0; tileY < canvasHeight / tileHeight; tileY++) {
-    for (let tileX = 0; tileX < canvasWidth / tileWidth; tileX++) {
-      const imageData = tileDataArray[tileY][tileX];
-      const destX = tileX * tileWidth;
-      const destY = tileY * tileHeight;
-
-      // Copy the pixels from the tile to the final image
-      for (let y = 0; y < tileHeight; y++) {
-        for (let x = 0; x < tileWidth; x++) {
-          const index = (y * tileWidth + x) * 4;
-          const destIndex = ((destY + y) * canvasWidth + destX + x) * 4;
-          finalImage.data[destIndex] = imageData[index];
-          finalImage.data[destIndex + 1] = imageData[index + 1];
-          finalImage.data[destIndex + 2] = imageData[index + 2];
-          finalImage.data[destIndex + 3] = imageData[index + 3];
-        }
-      }
-    }
-  }
-  console.timeEnd("concat tiles");
-
-  console.time("create buffer");
-  const buffer = PNG.sync.write(finalImage);
-  console.timeEnd("create buffer");
+  console.time("encode");
+  const pngData = UPNG.encode(
+    [imageData.buffer],
+    canvas.width,
+    canvas.height,
+    0,
+  );
+  console.timeEnd("encode");
 
-  return new Blob([buffer], { type: "image/png" });
+  return new Blob([pngData], { type: "image/png" });
 };
 
 /** generates SHA-1 digest from supplied file (if not supported, falls back

+ 0 - 4
src/global.d.ts

@@ -120,7 +120,3 @@ declare module "image-blob-reduce" {
   const reduce: ImageBlobReduce.ImageBlobReduceStatic;
   export = reduce;
 }
-
-declare module "pngjs/browser" {
-  export { PNG } from "pngjs";
-}

+ 13 - 13
yarn.lock

@@ -2714,13 +2714,6 @@
   resolved "https://registry.yarnpkg.com/@types/pica/-/pica-5.1.3.tgz#5ef64529a1f83f7d6586a8bf75a8a00be32aca02"
   integrity sha512-13SEyETRE5psd9bE0AmN+0M1tannde2fwHfLVaVIljkbL9V0OfFvKwCicyeDvVYLkmjQWEydbAlsDsmjrdyTOg==
 
-"@types/[email protected]":
-  version "6.0.1"
-  resolved "https://registry.yarnpkg.com/@types/pngjs/-/pngjs-6.0.1.tgz#c711ec3fbbf077fed274ecccaf85dd4673130072"
-  integrity sha512-J39njbdW1U/6YyVXvC9+1iflZghP8jgRf2ndYghdJb5xL49LYDB+1EuAxfbuJ2IBbWIL3AjHPQhgaTxT3YaYeg==
-  dependencies:
-    "@types/node" "*"
-
 "@types/prettier@^2.1.5":
   version "2.7.2"
   resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0"
@@ -2858,6 +2851,11 @@
   resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.3.tgz#a136f83b0758698df454e328759dbd3d44555311"
   integrity sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==
 
+"@types/[email protected]":
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/@types/upng-js/-/upng-js-2.1.2.tgz#4680f700c3003eaf958b92418c6e19521bb1e034"
+  integrity sha512-sxCnLDEmGFDcnrdSMml3/mDSbfSAvt86Ld32J6Ac75Og7GzzmwHbUnJNTue74tfQC/3PPD/W0jG2dQuF9v6UOg==
+
 "@types/ws@^8.5.1":
   version "8.5.4"
   resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.4.tgz#bb10e36116d6e570dd943735f86c933c1587b8a5"
@@ -8041,7 +8039,7 @@ p-try@^2.0.0:
   resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
   integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
 
[email protected]:
[email protected], pako@^1.0.5:
   version "1.0.11"
   resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
   integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
@@ -8234,11 +8232,6 @@ [email protected]:
   dependencies:
     crc-32 "^0.3.0"
 
[email protected]:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-7.0.0.tgz#a8b7446020ebbc6ac739db6c5415a65d17090e26"
-  integrity sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==
-
 [email protected], points-on-curve@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/points-on-curve/-/points-on-curve-0.2.0.tgz#7dbb98c43791859434284761330fa893cb81b4d1"
@@ -10569,6 +10562,13 @@ update-browserslist-db@^1.0.10:
     escalade "^3.1.1"
     picocolors "^1.0.0"
 
[email protected]:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/upng-js/-/upng-js-2.1.0.tgz#7176e73973db361ca95d0fa14f958385db6b9dd2"
+  integrity sha512-d3xzZzpMP64YkjP5pr8gNyvBt7dLk/uGI67EctzDuVp4lCZyVMo0aJO6l/VDlgbInJYDY6cnClLoBp29eKWI6g==
+  dependencies:
+    pako "^1.0.5"
+
 uri-js@^4.2.2:
   version "4.4.1"
   resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"