save changes
This commit is contained in:
10
.clinerules/lib.md
Normal file
10
.clinerules/lib.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Library Functions
|
||||||
|
|
||||||
|
## PNG Metadata
|
||||||
|
Use this file `src/lib/util.ts` for embedding and reading JSON data from PNG files.
|
||||||
|
|
||||||
|
### Embed JSON to PNG
|
||||||
|
Use this method `embedJsonToPng(path, obj)`
|
||||||
|
|
||||||
|
### Read JSON from PNG
|
||||||
|
Use this method `readJsonToPng(path)`
|
||||||
516
package-lock.json
generated
516
package-lock.json
generated
@ -10,15 +10,21 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/axios": "^0.14.4",
|
"@types/axios": "^0.14.4",
|
||||||
|
"@types/pngjs": "^6.0.5",
|
||||||
|
"@types/sharp": "^0.32.0",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"mysql2": "^3.14.3",
|
"mysql2": "^3.14.3",
|
||||||
"open": "^10.2.0",
|
"open": "^10.2.0",
|
||||||
|
"png-chunk-text": "^1.0.0",
|
||||||
|
"pngjs": "^7.0.0",
|
||||||
"puppeteer": "^24.16.2",
|
"puppeteer": "^24.16.2",
|
||||||
|
"sharp": "^0.34.4",
|
||||||
"uuid": "^11.1.0"
|
"uuid": "^11.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.0.0",
|
"@types/node": "^20.19.19",
|
||||||
|
"@types/png-chunk-text": "^1.0.3",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.0.0"
|
"typescript": "^5.0.0"
|
||||||
}
|
}
|
||||||
@ -56,6 +62,419 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@emnapi/runtime": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/colour": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-darwin-arm64": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@img/sharp-libvips-darwin-arm64": "1.2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-darwin-x64": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@img/sharp-libvips-darwin-x64": "1.2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-libvips-darwin-arm64": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-libvips-darwin-x64": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-libvips-linux-arm": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-libvips-linux-arm64": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-libvips-linux-ppc64": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-libvips-linux-s390x": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w==",
|
||||||
|
"cpu": [
|
||||||
|
"s390x"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-libvips-linux-x64": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-linux-arm": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@img/sharp-libvips-linux-arm": "1.2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-linux-arm64": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@img/sharp-libvips-linux-arm64": "1.2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-linux-ppc64": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@img/sharp-libvips-linux-ppc64": "1.2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-linux-s390x": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw==",
|
||||||
|
"cpu": [
|
||||||
|
"s390x"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@img/sharp-libvips-linux-s390x": "1.2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-linux-x64": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@img/sharp-libvips-linux-x64": "1.2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-linuxmusl-arm64": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@img/sharp-libvips-linuxmusl-arm64": "1.2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-linuxmusl-x64": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@img/sharp-libvips-linuxmusl-x64": "1.2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-wasm32": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA==",
|
||||||
|
"cpu": [
|
||||||
|
"wasm32"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@emnapi/runtime": "^1.5.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-win32-arm64": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-win32-ia32": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@img/sharp-win32-x64": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@jridgewell/resolve-uri": {
|
"node_modules/@jridgewell/resolve-uri": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||||
@ -140,14 +559,36 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.19.11",
|
"version": "20.19.19",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.19.tgz",
|
||||||
"integrity": "sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==",
|
"integrity": "sha512-pb1Uqj5WJP7wrcbLU7Ru4QtA0+3kAXrkutGiD26wUKzSMgNNaPARTUDQmElUXp64kh3cWdou3Q0C7qwwxqSFmg==",
|
||||||
"devOptional": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~6.21.0"
|
"undici-types": "~6.21.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/png-chunk-text": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/png-chunk-text/-/png-chunk-text-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-7keEFz73uNJ9Ar1XMCNnHEXT9pICJnouMQCCYgBEmHMgdkXaQzSTmSvr6tUDSqgdEgmlRAxZd97wprgliyZoCg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/@types/pngjs": {
|
||||||
|
"version": "6.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/pngjs/-/pngjs-6.0.5.tgz",
|
||||||
|
"integrity": "sha512-0k5eKfrA83JOZPppLtS2C7OUtyNAl2wKNxfyYl9Q5g9lPkgBl/9hNyAu6HuEH2J4XmIv2znEpkDd0SaZVxW6iQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/sharp": {
|
||||||
|
"version": "0.32.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.32.0.tgz",
|
||||||
|
"integrity": "sha512-OOi3kL+FZDnPhVzsfD37J88FNeZh6gQsGcLc95NbeURRGvmSjeXiDcyWzF2o3yh/gQAUn2uhh/e+CPCa5nwAxw==",
|
||||||
|
"deprecated": "This is a stub types definition. sharp provides its own type definitions, so you do not need this installed.",
|
||||||
|
"dependencies": {
|
||||||
|
"sharp": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/yauzl": {
|
"node_modules/@types/yauzl": {
|
||||||
"version": "2.10.3",
|
"version": "2.10.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
|
||||||
@ -551,6 +992,14 @@
|
|||||||
"node": ">=0.10"
|
"node": ">=0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/detect-libc": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/devtools-protocol": {
|
"node_modules/devtools-protocol": {
|
||||||
"version": "0.0.1475386",
|
"version": "0.0.1475386",
|
||||||
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1475386.tgz",
|
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1475386.tgz",
|
||||||
@ -1262,6 +1711,19 @@
|
|||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
|
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/png-chunk-text": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/png-chunk-text/-/png-chunk-text-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-DEROKU3SkkLGWNMzru3xPVgxyd48UGuMSZvioErCure6yhOc/pRH2ZV+SEn7nmaf7WNf3NdIpH+UTrRdKyq9Lw=="
|
||||||
|
},
|
||||||
|
"node_modules/pngjs": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.19.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/progress": {
|
"node_modules/progress": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
||||||
@ -1386,6 +1848,47 @@
|
|||||||
"resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
|
||||||
"integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="
|
"integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="
|
||||||
},
|
},
|
||||||
|
"node_modules/sharp": {
|
||||||
|
"version": "0.34.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.4.tgz",
|
||||||
|
"integrity": "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@img/colour": "^1.0.0",
|
||||||
|
"detect-libc": "^2.1.0",
|
||||||
|
"semver": "^7.7.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/libvips"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@img/sharp-darwin-arm64": "0.34.4",
|
||||||
|
"@img/sharp-darwin-x64": "0.34.4",
|
||||||
|
"@img/sharp-libvips-darwin-arm64": "1.2.3",
|
||||||
|
"@img/sharp-libvips-darwin-x64": "1.2.3",
|
||||||
|
"@img/sharp-libvips-linux-arm": "1.2.3",
|
||||||
|
"@img/sharp-libvips-linux-arm64": "1.2.3",
|
||||||
|
"@img/sharp-libvips-linux-ppc64": "1.2.3",
|
||||||
|
"@img/sharp-libvips-linux-s390x": "1.2.3",
|
||||||
|
"@img/sharp-libvips-linux-x64": "1.2.3",
|
||||||
|
"@img/sharp-libvips-linuxmusl-arm64": "1.2.3",
|
||||||
|
"@img/sharp-libvips-linuxmusl-x64": "1.2.3",
|
||||||
|
"@img/sharp-linux-arm": "0.34.4",
|
||||||
|
"@img/sharp-linux-arm64": "0.34.4",
|
||||||
|
"@img/sharp-linux-ppc64": "0.34.4",
|
||||||
|
"@img/sharp-linux-s390x": "0.34.4",
|
||||||
|
"@img/sharp-linux-x64": "0.34.4",
|
||||||
|
"@img/sharp-linuxmusl-arm64": "0.34.4",
|
||||||
|
"@img/sharp-linuxmusl-x64": "0.34.4",
|
||||||
|
"@img/sharp-wasm32": "0.34.4",
|
||||||
|
"@img/sharp-win32-arm64": "0.34.4",
|
||||||
|
"@img/sharp-win32-ia32": "0.34.4",
|
||||||
|
"@img/sharp-win32-x64": "0.34.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/smart-buffer": {
|
"node_modules/smart-buffer": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
|
||||||
@ -1574,8 +2077,7 @@
|
|||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "6.21.0",
|
"version": "6.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||||
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="
|
||||||
"devOptional": true
|
|
||||||
},
|
},
|
||||||
"node_modules/uuid": {
|
"node_modules/uuid": {
|
||||||
"version": "11.1.0",
|
"version": "11.1.0",
|
||||||
|
|||||||
@ -17,17 +17,23 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.0.0",
|
"@types/node": "^20.19.19",
|
||||||
|
"@types/png-chunk-text": "^1.0.3",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.0.0"
|
"typescript": "^5.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/axios": "^0.14.4",
|
"@types/axios": "^0.14.4",
|
||||||
|
"@types/pngjs": "^6.0.5",
|
||||||
|
"@types/sharp": "^0.32.0",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"mysql2": "^3.14.3",
|
"mysql2": "^3.14.3",
|
||||||
"open": "^10.2.0",
|
"open": "^10.2.0",
|
||||||
|
"png-chunk-text": "^1.0.0",
|
||||||
|
"pngjs": "^7.0.0",
|
||||||
"puppeteer": "^24.16.2",
|
"puppeteer": "^24.16.2",
|
||||||
|
"sharp": "^0.34.4",
|
||||||
"uuid": "^11.1.0"
|
"uuid": "^11.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@
|
|||||||
},
|
},
|
||||||
"7": {
|
"7": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"seed": 838097333311955,
|
"seed": 229610050211520,
|
||||||
"steps": 8,
|
"steps": 8,
|
||||||
"cfg": 1,
|
"cfg": 1,
|
||||||
"sampler_name": "euler",
|
"sampler_name": "euler",
|
||||||
@ -101,6 +101,48 @@
|
|||||||
"title": "VAE Decode"
|
"title": "VAE Decode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"9": {
|
||||||
|
"inputs": {
|
||||||
|
"font_file": "Alibaba-PuHuiTi-Heavy.ttf",
|
||||||
|
"font_size": 40,
|
||||||
|
"border": 32,
|
||||||
|
"color_theme": "light",
|
||||||
|
"reel_1": [
|
||||||
|
"10",
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"class_type": "LayerUtility: ImageReelComposit",
|
||||||
|
"_meta": {
|
||||||
|
"title": "LayerUtility: Image Reel Composit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"10": {
|
||||||
|
"inputs": {
|
||||||
|
"image1_text": "Original image",
|
||||||
|
"image2_text": "Reference",
|
||||||
|
"image3_text": "Result",
|
||||||
|
"image4_text": "image4",
|
||||||
|
"reel_height": 512,
|
||||||
|
"border": 32,
|
||||||
|
"image1": [
|
||||||
|
"11",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"image2": [
|
||||||
|
"11",
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"image3": [
|
||||||
|
"8",
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"class_type": "LayerUtility: ImageReel",
|
||||||
|
"_meta": {
|
||||||
|
"title": "LayerUtility: Image Reel"
|
||||||
|
}
|
||||||
|
},
|
||||||
"11": {
|
"11": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"prompt": [
|
"prompt": [
|
||||||
@ -121,7 +163,7 @@
|
|||||||
0
|
0
|
||||||
],
|
],
|
||||||
"image1": [
|
"image1": [
|
||||||
"24",
|
"27",
|
||||||
0
|
0
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -130,6 +172,45 @@
|
|||||||
"title": "TextEncodeQwenImageEditPlus 小志Jason(xiaozhijason)"
|
"title": "TextEncodeQwenImageEditPlus 小志Jason(xiaozhijason)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"14": {
|
||||||
|
"inputs": {
|
||||||
|
"image": "70437490094806_1759383647641_0.png"
|
||||||
|
},
|
||||||
|
"class_type": "LoadImage",
|
||||||
|
"_meta": {
|
||||||
|
"title": "Load Image"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"19": {
|
||||||
|
"inputs": {
|
||||||
|
"rgthree_comparer": {
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"name": "A",
|
||||||
|
"selected": true,
|
||||||
|
"url": "/api/view?filename=rgthree.compare._temp_camuo_00003_.png&type=temp&subfolder=&rand=0.23138406992361238"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "B",
|
||||||
|
"selected": true,
|
||||||
|
"url": "/api/view?filename=rgthree.compare._temp_camuo_00004_.png&type=temp&subfolder=&rand=0.5709114887760696"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"image_a": [
|
||||||
|
"11",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"image_b": [
|
||||||
|
"8",
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"class_type": "Image Comparer (rgthree)",
|
||||||
|
"_meta": {
|
||||||
|
"title": "Image Comparer (rgthree)"
|
||||||
|
}
|
||||||
|
},
|
||||||
"20": {
|
"20": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"filename_prefix": "qwenedit",
|
"filename_prefix": "qwenedit",
|
||||||
@ -145,43 +226,66 @@
|
|||||||
},
|
},
|
||||||
"21": {
|
"21": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"value": "change camera angle to closeup face from image1, change background to light gray with faing gradient, change face angle to look at directry look at camera"
|
"value": "把图1中的衣服和配饰提取出来,并将背景改为浅灰色。"
|
||||||
},
|
},
|
||||||
"class_type": "PrimitiveStringMultiline",
|
"class_type": "PrimitiveStringMultiline",
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"title": "String (Multiline)"
|
"title": "String (Multiline)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"24": {
|
"22": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"measurement": "pixels",
|
"filename_prefix": "ComfyUI",
|
||||||
"width": 720,
|
"images": [
|
||||||
"height": 1280,
|
"9",
|
||||||
"fit": "contain",
|
|
||||||
"method": "nearest-exact",
|
|
||||||
"image": [
|
|
||||||
"64",
|
|
||||||
0
|
0
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"class_type": "Image Resize (rgthree)",
|
"class_type": "SaveImage",
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"title": "Image Resize (rgthree)"
|
"title": "Save Image"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"64": {
|
"23": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"image": "1337074888177434_1758776251440_2.png"
|
"width": 720,
|
||||||
|
"height": 1280,
|
||||||
|
"batch_size": 1
|
||||||
},
|
},
|
||||||
"class_type": "LoadImage",
|
"class_type": "EmptyLatentImage",
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"title": "Load Image"
|
"title": "Empty Latent Image"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"65": {
|
"24": {
|
||||||
|
"inputs": {
|
||||||
|
"vae_name": "sdxl_vae.safetensors"
|
||||||
|
},
|
||||||
|
"class_type": "VAELoader",
|
||||||
|
"_meta": {
|
||||||
|
"title": "Load VAE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"25": {
|
||||||
|
"inputs": {
|
||||||
|
"samples": [
|
||||||
|
"23",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"vae": [
|
||||||
|
"24",
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"class_type": "VAEDecode",
|
||||||
|
"_meta": {
|
||||||
|
"title": "VAE Decode"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"26": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"images": [
|
"images": [
|
||||||
"24",
|
"25",
|
||||||
0
|
0
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -189,5 +293,25 @@
|
|||||||
"_meta": {
|
"_meta": {
|
||||||
"title": "Preview Image"
|
"title": "Preview Image"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"27": {
|
||||||
|
"inputs": {
|
||||||
|
"width": 720,
|
||||||
|
"height": 1280,
|
||||||
|
"upscale_method": "nearest-exact",
|
||||||
|
"keep_proportion": "pad",
|
||||||
|
"pad_color": "192,192,192",
|
||||||
|
"crop_position": "center",
|
||||||
|
"divisible_by": 2,
|
||||||
|
"device": "cpu",
|
||||||
|
"image": [
|
||||||
|
"14",
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"class_type": "ImageResizeKJv2",
|
||||||
|
"_meta": {
|
||||||
|
"title": "Resize Image v2"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,7 +158,7 @@
|
|||||||
},
|
},
|
||||||
"21": {
|
"21": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"value": "图2中的女孩穿着图1的衣服\n\n\n\n\n\n"
|
"value": "图2中的人物穿着图1的上衣、下装和配饰。"
|
||||||
},
|
},
|
||||||
"class_type": "PrimitiveStringMultiline",
|
"class_type": "PrimitiveStringMultiline",
|
||||||
"_meta": {
|
"_meta": {
|
||||||
|
|||||||
@ -23,9 +23,9 @@ async function convertImage(
|
|||||||
|
|
||||||
workflow = JSON.parse(await fs.readFile('src/comfyworkflows/edit_image_qwen.json', 'utf-8'));
|
workflow = JSON.parse(await fs.readFile('src/comfyworkflows/edit_image_qwen.json', 'utf-8'));
|
||||||
workflow['21']['inputs']['value'] = prompt;
|
workflow['21']['inputs']['value'] = prompt;
|
||||||
workflow['24']['inputs']['width'] = size.width;
|
workflow['23']['inputs']['width'] = size.width;
|
||||||
workflow['24']['inputs']['height'] = size.height;
|
workflow['23']['inputs']['height'] = size.height;
|
||||||
workflow['64']['inputs']['image'] = baseFileName;
|
workflow['14']['inputs']['image'] = baseFileName;
|
||||||
|
|
||||||
const response = await axios.post(`${COMFY_BASE_URL}/prompt`, { prompt: workflow });
|
const response = await axios.post(`${COMFY_BASE_URL}/prompt`, { prompt: workflow });
|
||||||
const promptId = response.data.prompt_id;
|
const promptId = response.data.prompt_id;
|
||||||
@ -262,7 +262,7 @@ export async function convertImageVton(
|
|||||||
const COMFY_OUTPUT_DIR = comfyOutputDir;
|
const COMFY_OUTPUT_DIR = comfyOutputDir;
|
||||||
let workflow;
|
let workflow;
|
||||||
|
|
||||||
workflow = JSON.parse(await fs.readFile('src/comfyworkflows/vton.json', 'utf-8'));
|
workflow = JSON.parse(await fs.readFile('src/comfyworkflows/vton_cloth.json', 'utf-8'));
|
||||||
workflow['76']['inputs']['number'] = size.width;
|
workflow['76']['inputs']['number'] = size.width;
|
||||||
workflow['77']['inputs']['number'] = size.height;
|
workflow['77']['inputs']['number'] = size.height;
|
||||||
|
|
||||||
|
|||||||
52
src/lib/util.ts
Normal file
52
src/lib/util.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import { PNG } from 'pngjs';
|
||||||
|
import { encode, decode } from 'png-chunk-text';
|
||||||
|
|
||||||
|
export async function embedJsonToPng(path: string, obj: any): Promise<void> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const jsonString = JSON.stringify(obj);
|
||||||
|
const chunk = { name: 'tEXt', data: `json:${jsonString}` };
|
||||||
|
|
||||||
|
fs.createReadStream(path)
|
||||||
|
.pipe(new PNG())
|
||||||
|
.on('parsed', function (this: PNG & { chunks?: any[] }) {
|
||||||
|
if (!this.chunks) {
|
||||||
|
return reject(new Error('PNG chunks not found.'));
|
||||||
|
}
|
||||||
|
const newChunks = this.chunks.slice();
|
||||||
|
newChunks.splice(-1, 0, chunk);
|
||||||
|
this.chunks = newChunks;
|
||||||
|
|
||||||
|
this.pack()
|
||||||
|
.pipe(fs.createWriteStream(path))
|
||||||
|
.on('finish', () => resolve())
|
||||||
|
.on('error', (err: Error) => reject(err));
|
||||||
|
})
|
||||||
|
.on('error', (err: Error) => reject(err));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function readJsonToPng(path: string): Promise<any> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.readFile(path, (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
return reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
const chunks = decode(data);
|
||||||
|
const textChunk = chunks.find((chunk: { name: string; data: string }) => chunk.name === 'tEXt' && chunk.data.startsWith('json:'));
|
||||||
|
|
||||||
|
if (textChunk) {
|
||||||
|
const jsonString = textChunk.data.slice(5);
|
||||||
|
try {
|
||||||
|
const jsonObj = JSON.parse(jsonString);
|
||||||
|
resolve(jsonObj);
|
||||||
|
} catch (e) {
|
||||||
|
reject(new Error('Failed to parse JSON from PNG.'));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reject(new Error('No JSON data found in PNG.'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
@ -13,8 +13,8 @@ const PINS_TO_COLLECT = 5;
|
|||||||
|
|
||||||
// Hard-coded user prompt
|
// Hard-coded user prompt
|
||||||
const HARDCODED_USER_PROMPT = process.env.HARDCODED_USER_PROMPT || `
|
const HARDCODED_USER_PROMPT = process.env.HARDCODED_USER_PROMPT || `
|
||||||
Generate 5 keywords for photos of a portrait of woman's outfit. "woman portrait outfit" is mandatory as prefix.
|
Generate 20 keywords for perfume brand photo. List of 20 most famous perfume brands, and its popular perfume names:
|
||||||
Example output : [""woman portrait outfit street",""woman portrait outfit elegant",""woman portrait outfit dress"... and 5 items in array]
|
Example output : ["chanel N5", "dior j'adore", "gucci bloom"....]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
async function getPinUrlsFromPinterest(keyword: string, scrollCount = SCROLL_SEARCH, limit = PINS_TO_COLLECT): Promise<string[]> {
|
async function getPinUrlsFromPinterest(keyword: string, scrollCount = SCROLL_SEARCH, limit = PINS_TO_COLLECT): Promise<string[]> {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -2,35 +2,31 @@ import * as fs from 'fs';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { convertImageVton, convertImage } from '../lib/image-converter';
|
import { convertImageVton, convertImage } from '../lib/image-converter';
|
||||||
import * as dotenv from 'dotenv';
|
import * as dotenv from 'dotenv';
|
||||||
|
import sharp from 'sharp';
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
<<<<<<< HEAD
|
const clothesDir = 'D:\\projects\\random_video_maker\\input';
|
||||||
const modelsBodyDir = 'D:\\CatsEye\\long videos\\vton-demo\\VTON\\models_body';
|
|
||||||
const clothesDir = 'D:\\CatsEye\\long videos\\vton-demo\\VTON\\clothes';
|
|
||||||
const posesDir = 'D:\\CatsEye\\long videos\\vton-demo\\VTON\\poses';
|
|
||||||
=======
|
|
||||||
const clothesDir = 'C:\\Users\\fm201\\Documents\\VTON\\\clothes';
|
|
||||||
const modelPath = 'C:\\Users\\fm201\\Documents\\VTON\\models\\Jessica_body.png';
|
|
||||||
const posesDir = 'C:\\Users\\fm201\\Documents\\VTON\\\poses';
|
|
||||||
>>>>>>> bdca42e82102a00f771ecf58b4ff0673dbd218af
|
|
||||||
const outputDir = 'generated';
|
const outputDir = 'generated';
|
||||||
|
|
||||||
const comfyBaseUrl = process.env.SERVER2_COMFY_BASE_URL;
|
const comfyBaseUrl = process.env.SERVER1_COMFY_BASE_URL;
|
||||||
const comfyOutputDir = process.env.SERVER2_COMFY_OUTPUT_DIR;
|
const comfyOutputDir = process.env.SERVER1_COMFY_OUTPUT_DIR;
|
||||||
|
|
||||||
function getNextIndex(directory: string): number {
|
function getNextIndex(directory: string): number {
|
||||||
if (!fs.existsSync(directory)) {
|
if (!fs.existsSync(directory)) {
|
||||||
fs.mkdirSync(directory, { recursive: true });
|
fs.mkdirSync(directory, { recursive: true });
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const files = fs.readdirSync(directory);
|
const dirs = fs.readdirSync(directory, { withFileTypes: true })
|
||||||
const vtonFiles = files.filter(file => file.startsWith('vton_') && file.endsWith('.png'));
|
.filter(dirent => dirent.isDirectory())
|
||||||
if (vtonFiles.length === 0) {
|
.map(dirent => dirent.name);
|
||||||
|
|
||||||
|
const vtonDirs = dirs.filter(dir => dir.startsWith('vton_'));
|
||||||
|
if (vtonDirs.length === 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const indices = vtonFiles.map(file => {
|
const indices = vtonDirs.map(dir => {
|
||||||
const match = file.match(/vton_(\d+)\.png/);
|
const match = dir.match(/vton_(\d+)/);
|
||||||
return match ? parseInt(match[1], 10) : -1;
|
return match ? parseInt(match[1], 10) : -1;
|
||||||
});
|
});
|
||||||
return Math.max(...indices) + 1;
|
return Math.max(...indices) + 1;
|
||||||
@ -55,27 +51,96 @@ async function generateVtonImages() {
|
|||||||
const comfyInputDir = comfyOutputDir.replace("output", "input");
|
const comfyInputDir = comfyOutputDir.replace("output", "input");
|
||||||
|
|
||||||
while (true) { // Infinite loop
|
while (true) { // Infinite loop
|
||||||
|
const iterationDir = path.join(outputDir, `vton_${index}`);
|
||||||
|
fs.mkdirSync(iterationDir, { recursive: true });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const personFilePath = getRandomFile(modelsBodyDir);
|
const personOrigPath = getRandomFile(clothesDir);
|
||||||
const clothFilePath = getRandomFile(clothesDir);
|
const clothOrigPath = getRandomFile(clothesDir);
|
||||||
const poseFilePath = getRandomFile(posesDir);
|
|
||||||
|
|
||||||
const personFileName = path.basename(personFilePath);
|
fs.copyFileSync(personOrigPath, path.join(iterationDir, '1-personOrig.png'));
|
||||||
const clothFileName = path.basename(clothFilePath);
|
fs.copyFileSync(clothOrigPath, path.join(iterationDir, '3-clothOrig.png'));
|
||||||
const poseFileName = path.basename(poseFilePath);
|
|
||||||
|
|
||||||
fs.copyFileSync(personFilePath, path.join(comfyInputDir, personFileName));
|
const personOrigFileName = path.basename(personOrigPath);
|
||||||
fs.copyFileSync(clothFilePath, path.join(comfyInputDir, clothFileName));
|
const clothOrigFileName = path.basename(clothOrigPath);
|
||||||
fs.copyFileSync(poseFilePath, path.join(comfyInputDir, poseFileName));
|
|
||||||
|
|
||||||
console.log(`Processing person: ${personFileName}, cloth: ${clothFileName}, pose: ${poseFileName}`);
|
fs.copyFileSync(personOrigPath, path.join(comfyInputDir, personOrigFileName));
|
||||||
|
fs.copyFileSync(clothOrigPath, path.join(comfyInputDir, clothOrigFileName));
|
||||||
|
|
||||||
const outputFilename = `vton_${index}.png`;
|
console.log(`Processing person: ${personOrigPath}, cloth: ${clothOrigPath}`);
|
||||||
|
|
||||||
const generatedImagePath = await convertImageVton(personFileName, clothFileName, poseFileName, outputFilename, comfyBaseUrl, comfyOutputDir, { width: 720, height: 1280 });
|
const cleanePersonImagePath = await convertImage("请把姿势改成站立的,转换成全身照片。去掉衣服,只保留白色运动文胸和白色短裤。双脚保持赤脚。背景为浅灰色。", personOrigFileName, comfyBaseUrl, comfyOutputDir, { width: 720, height: 1280 });
|
||||||
|
fs.copyFileSync(cleanePersonImagePath, path.join(iterationDir, '2-personCleaned.png'));
|
||||||
|
const cleanedPersonFileName = path.basename(cleanePersonImagePath);
|
||||||
|
fs.copyFileSync(cleanePersonImagePath, path.join(comfyInputDir, cleanedPersonFileName));
|
||||||
|
|
||||||
|
const cleanedClothImagePath = await convertImage("请将图1中的上衣、下装和配饰分别提取出来,放到同一个浅灰色的背景上。", clothOrigFileName, comfyBaseUrl, comfyOutputDir, { width: 720, height: 1280 });
|
||||||
|
fs.copyFileSync(cleanedClothImagePath, path.join(iterationDir, '4-clothCleaned.png'));
|
||||||
|
const cleanedClothFileName = path.basename(cleanedClothImagePath);
|
||||||
|
fs.copyFileSync(cleanedClothImagePath, path.join(comfyInputDir, cleanedClothFileName));
|
||||||
|
|
||||||
|
const outputFilename = `vton_final_${index}.png`;
|
||||||
|
const generatedImagePath = await convertImageVton(cleanedPersonFileName, cleanedClothFileName, outputFilename, comfyBaseUrl, comfyOutputDir, { width: 720, height: 1280 });
|
||||||
|
|
||||||
if (generatedImagePath) {
|
if (generatedImagePath) {
|
||||||
|
fs.copyFileSync(generatedImagePath, path.join(iterationDir, '5-finalResult.png'));
|
||||||
console.log(`Generated image saved to ${generatedImagePath}`);
|
console.log(`Generated image saved to ${generatedImagePath}`);
|
||||||
|
|
||||||
|
// --- Create composite image ---
|
||||||
|
const imagePaths = [
|
||||||
|
path.join(iterationDir, '1-personOrig.png'),
|
||||||
|
path.join(iterationDir, '3-clothOrig.png'),
|
||||||
|
path.join(iterationDir, '2-personCleaned.png'),
|
||||||
|
path.join(iterationDir, '4-clothCleaned.png'),
|
||||||
|
path.join(iterationDir, '5-finalResult.png')
|
||||||
|
];
|
||||||
|
|
||||||
|
const resizedImages = [];
|
||||||
|
let totalWidth = 10; // Initial left margin
|
||||||
|
const resizedHeight = 720;
|
||||||
|
|
||||||
|
for (const imagePath of imagePaths) {
|
||||||
|
const image = sharp(imagePath);
|
||||||
|
const metadata = await image.metadata();
|
||||||
|
if (!metadata.width || !metadata.height) {
|
||||||
|
throw new Error(`Could not get metadata for image ${imagePath}`);
|
||||||
|
}
|
||||||
|
const resizedWidth = Math.round((metadata.width / metadata.height) * resizedHeight);
|
||||||
|
|
||||||
|
const resizedImageBuffer = await image.resize(resizedWidth, resizedHeight).toBuffer();
|
||||||
|
resizedImages.push({
|
||||||
|
buffer: resizedImageBuffer,
|
||||||
|
width: resizedWidth
|
||||||
|
});
|
||||||
|
totalWidth += resizedWidth + 10; // Add image width and right margin
|
||||||
|
}
|
||||||
|
|
||||||
|
const compositeOps = [];
|
||||||
|
let currentLeft = 10; // Start with left margin
|
||||||
|
|
||||||
|
for (const img of resizedImages) {
|
||||||
|
compositeOps.push({
|
||||||
|
input: img.buffer,
|
||||||
|
top: 10, // 10px top margin
|
||||||
|
left: currentLeft
|
||||||
|
});
|
||||||
|
currentLeft += img.width + 10; // Move to the next position
|
||||||
|
}
|
||||||
|
|
||||||
|
await sharp({
|
||||||
|
create: {
|
||||||
|
width: totalWidth,
|
||||||
|
height: 740,
|
||||||
|
channels: 4,
|
||||||
|
background: { r: 255, g: 255, b: 255, alpha: 1 }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.composite(compositeOps)
|
||||||
|
.toFile(path.join(iterationDir, 'process.png'));
|
||||||
|
|
||||||
|
console.log(`Generated composite image process.png in ${iterationDir}`);
|
||||||
|
// --- End of composite image creation ---
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
} else {
|
} else {
|
||||||
console.error(`Failed to generate image for index ${index}`);
|
console.error(`Failed to generate image for index ${index}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user