Skip to content
This repository was archived by the owner on Feb 28, 2024. It is now read-only.

Commit ea50d08

Browse files
committed
Initial commit
0 parents  commit ea50d08

11 files changed

+822
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
dist
2+
node_modules
3+
.vscode
4+
test-output.webp

.prettierrc

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"arrowParens": "avoid",
3+
"bracketSpacing": true,
4+
"htmlWhitespaceSensitivity": "css",
5+
"printWidth": 80,
6+
"semi": true,
7+
"singleQuote": false,
8+
"tabWidth": 4,
9+
"trailingComma": "all",
10+
"useTabs": true
11+
}

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 [fullname]
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Rembg Node
2+
3+
Rembg lets you **easily remove backgrounds** from images using the [U2-Net ai model](https://github.com/xuebinqin/U-2-Net)
4+
5+
This is a loose port of the original [Rembg for Python](https://github.com/danielgatis/rembg), big thanks to [@danielgatis](https://github.com/danielgatis)
6+
7+
It uses [sharp](https://github.com/lovell/sharp) for input and output so you can easily integrate it
8+
9+
The masking algorithm isn't fully complete yet, but the results are pretty awesome already!
10+
11+
## Example (TypeScript)
12+
13+
```ts
14+
import { RemBg } from "rembg-node";
15+
import sharp from "sharp";
16+
17+
(async () => {
18+
const input = sharp("test-input.jpg");
19+
20+
// optional arguments
21+
const rembg = new RemBg({
22+
logging: true,
23+
});
24+
25+
const output = await rembg.remove(input);
26+
27+
await output.webp().toFile("test-output.webp");
28+
})();
29+
```

package.json

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "rembg-sharp",
3+
"version": "1.0.0",
4+
"description": "Rembg is a tool to remove images background.",
5+
"repository": "https://github.com/makifoxgirl/rembg-sharp",
6+
"author": "Maki",
7+
"license": "MIT",
8+
"main": "dist/index.js",
9+
"types": "dist/index.d.ts",
10+
"files": [
11+
"/dist"
12+
],
13+
"scripts": {
14+
"start": "tsc -w",
15+
"build": "tsc",
16+
"prepublishOnly": "npm run build"
17+
},
18+
"dependencies": {
19+
"axios": "^0.27.2",
20+
"onnxruntime-node": "^1.11.0",
21+
"sharp": "^0.30.7"
22+
},
23+
"devDependencies": {
24+
"@types/node": "^18.0.3",
25+
"@types/sharp": "^0.30.4",
26+
"typescript": "^4.7.4"
27+
}
28+
}

src/gdown.ts

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import axios from "axios";
2+
import * as fs from "fs/promises";
3+
import * as stream from "stream";
4+
import * as util from "util";
5+
6+
const pipeline = util.promisify(stream.pipeline);
7+
8+
function streamToString(stream: NodeJS.ReadableStream): Promise<string> {
9+
return new Promise((resolve, reject) => {
10+
const data = [];
11+
stream.on("data", chunk => {
12+
data.push(chunk);
13+
});
14+
stream.on("end", () => {
15+
resolve(Buffer.concat(data).toString("utf8"));
16+
});
17+
stream.on("error", error => {
18+
reject(error);
19+
});
20+
});
21+
}
22+
23+
// super primitive lol but works (for now)
24+
export async function gdown(id: string, savePath: string) {
25+
const url = "https://drive.google.com/uc?id=" + id;
26+
27+
const res = await axios({ url, responseType: "stream" });
28+
29+
const downloadable = res.headers["content-disposition"] != null;
30+
31+
let fh: fs.FileHandle;
32+
try {
33+
if (downloadable) {
34+
fh = await fs.open(savePath, "w+");
35+
await pipeline(res.data, fh.createWriteStream());
36+
} else {
37+
// aa fuck intermediary page
38+
const html = await streamToString(res.data);
39+
40+
const urlMatches = html.match(/action="([^]+?\/uc\?id=[^]+?)"/i);
41+
if (urlMatches == null)
42+
throw new Error("Failed to download gdrive link");
43+
44+
const actualRes = await axios({
45+
method: "post",
46+
url: urlMatches[1].replace(/&amp;/g, "&"),
47+
responseType: "stream",
48+
});
49+
50+
const actualDownloadable =
51+
actualRes.headers["content-disposition"] != null;
52+
53+
if (!actualDownloadable)
54+
throw new Error("Failed to download gdrive link");
55+
56+
fh = await fs.open(savePath, "w+");
57+
await pipeline(actualRes.data, fh.createWriteStream());
58+
}
59+
} finally {
60+
if (fh) fh.close();
61+
}
62+
}

0 commit comments

Comments
 (0)