UNPKG

@remove-background-ai/rembg.js

Version:

A simple wrapper for the https://www.rembg.com API

139 lines (138 loc) 6.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.rembg = void 0; const fs = __importStar(require("fs")); const axios_1 = __importDefault(require("axios")); const form_data_1 = __importDefault(require("form-data")); const tmp_promise_1 = require("tmp-promise"); const buffer_1 = require("buffer"); /** * Removes the background from an image using the rembg.com API. * * @param apiKey - The API key for rembg.com. * @param inputImage - file path, Buffer, or an object with a { base64: string } property. * @param onUploadProgress - A callback function to handle upload progress events. Defaults to console.log. * @param onDownloadProgress - A callback function to handle download progress events. Defaults to console.log. * @param Options - set of options for image Post processing. * @param options.returnMask - If true, returns the alpha-Matte (mask) image instead of the image. * @param options.returnBase64 - If true, returns the output image as a Base64 string instead of saving it to a file. * @param options.w - The width of the output image. * @param options.h - The height of the output image. * @param options.exact_resize - If true, the output image will be resized to the specified width and height. * @returns If returnBase64 is true, returns an object with the base64Image property containing the Base64 string of the output image. * If returnBase64 is false, returns an object with the outputImagePath property containing the path to the output image file, * and the cleanup function to delete the temporary file. * @throws Throws an error if the API key is not provided or if the request fails. */ const rembg = ({ apiKey, inputImage, options, onUploadProgress = console.log, // it will log every uploadProgress event by default onDownloadProgress = console.log, // it will log every uploadProgress event by default }) => __awaiter(void 0, void 0, void 0, function* () { if (!apiKey) throw new Error(' ⚠️⚠️⚠️ WARNING ⚠️⚠️⚠️: API key not provided, trials will be very limited.'); const { returnMask = false, returnBase64 = false, w = 0, h = 0, exact_resize = false } = options || {}; const url = "https://api.rembg.com/rmbg"; const API_KEY_HEADER = "x-api-key"; const data = new form_data_1.default(); // Handle different input types if (typeof inputImage === 'string') { // Input is a file path data.append('image', fs.createReadStream(inputImage)); } else if (buffer_1.Buffer.isBuffer(inputImage)) { // Input is a Buffer data.append('image', inputImage, { filename: 'image.png' }); } else if (typeof inputImage === 'object' && 'base64' in inputImage) { // Input is a base64 string let base64Data = inputImage.base64; // Remove data URL prefix if present if (base64Data.startsWith('data:')) { base64Data = base64Data.split(',')[1]; } const buffer = buffer_1.Buffer.from(base64Data, 'base64'); data.append('image', buffer, { filename: 'image.png', contentType: 'image/png' }); } else { throw new Error('Invalid input type. Must be a file path, Buffer, or an object with a base64 property.'); } data.append('exact_resize', exact_resize.toString()); data.append('w', w); data.append('h', h); data.append('mask', returnMask.toString()); data.append('return_base64', returnBase64.toString()); const config = { method: 'post', maxBodyLength: Infinity, url, headers: Object.assign({ [API_KEY_HEADER]: apiKey }, data.getHeaders()), data, responseType: 'arraybuffer', onUploadProgress, onDownloadProgress }; try { const response = yield axios_1.default.request(config); if (returnBase64) { // Return a base64 string if returnBase64 is true const base64Image = `data:image/png;base64,${buffer_1.Buffer.from(response.data).toString('base64')}`; return { base64Image }; } else { const { path: outputImagePath, cleanup } = yield (0, tmp_promise_1.file)({ prefix: 'rembg-', postfix: '.png' }); fs.writeFileSync(outputImagePath, response.data); return { outputImagePath, cleanup }; } } catch (error) { if (error.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx throw new Error(`❌ ${error.response.status} ${error.response.data.toString()}`); } else if (error.request) { // The request was made but no response was received throw new Error(`❌ ${error.message}`); } else { // Something happened in setting up the request that triggered an Error throw new Error(`❌ Request failed ${error.message}`); } } }); exports.rembg = rembg; exports.default = exports.rembg;