Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | 1x 1x 1x 1x 1x 1x 1x 23x 23x 22x 22x 22x 22x 22x 19x 3x 1x 2x 1x 1x 1x 1x 1x 21x 21x 21x 21x 21x 21x 2x 21x 3x 18x 21x 3x 21x 21x 2x 21x 21x 21x 18x 2x 2x 16x 16x 16x 3x 1x 2x 1x 1x 1x | import * as fs from 'fs';
import axios, { AxiosProgressEvent, AxiosRequestConfig } from 'axios';
import FormData from 'form-data';
import { file as tmpFile } from 'tmp-promise';
import { Buffer } from 'buffer';
type InputType = string | Buffer | { base64: string };
type Options = {
returnMask?: boolean;
returnBase64?: boolean; // by default, it won't return a Base64 string
w: number;
h: number;
exact_resize?: boolean;
format?: "png" | "PNG" | "webp" | "WEBP";
angle?: number; // Rotation angle in degrees
expand?: boolean; // Add padding so rotated images aren't cropped
bg_color?: string; // Optional solid background color in hex (e.g. #FFFFFFFF) or named color (e.g. "red", "blue")
}
const D_FORMAT = 'WEBP'
/**
* 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.
* @param options.format - format the image to target format, by default it is WEBP.
* @param options.angle - Rotation angle in degrees (optional).
* @param options.expand - Add padding so rotated images aren't cropped (optional, defaults to true).
* @param options.bg_color - Optional solid background color in hex (e.g. #FFFFFFFF) or named color (e.g. "red", "blue").
* @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.
*/
export const rembg = async ({
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
}: {
apiKey: string;
inputImage: InputType;
options?: Options;
onUploadProgress: (progressEvent: AxiosProgressEvent) => void;
onDownloadProgress: (progressEvent: AxiosProgressEvent) => void;
}) => {
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,
angle,
expand,
bg_color
} = options || {};
const url = "https://api.rembg.com/rmbg";
const API_KEY_HEADER = "x-api-key";
const data = new FormData();
// Handle different input types
if (typeof inputImage === 'string') {
// Input is a file path
data.append('image', fs.createReadStream(inputImage));
} else if (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
Iif (base64Data.startsWith('data:')) {
base64Data = base64Data.split(',')[1];
}
const buffer = 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());
// Add new parameters if provided
if (angle !== undefined) {
data.append('angle', angle.toString());
}
if (expand !== undefined) {
data.append('expand', expand.toString());
} else {
data.append('expand', 'true'); // Default value when not provided
}
if (bg_color !== undefined) {
data.append('bg_color', bg_color);
}
const format = options?.format
if(format && format.toLowerCase() === "png" || format?.toLowerCase() === "webp") {
data.append('format', options?.format)
}
const config = {
method: 'post',
maxBodyLength: Infinity,
url,
headers: {
[API_KEY_HEADER]: apiKey,
...data.getHeaders()
},
data,
responseType: 'arraybuffer',
onUploadProgress,
onDownloadProgress
} as AxiosRequestConfig<FormData>;
try {
const response = await axios.request(config);
if (returnBase64) {
// Return a base64 string if returnBase64 is true
const base64Image = `data:image/png;base64,${Buffer.from(response.data).toString('base64')}`;
return { base64Image };
} else {
const { path: outputImagePath, cleanup } = await tmpFile({ prefix: 'rembg-', postfix: `.${options?.format || D_FORMAT}` });
fs.writeFileSync(outputImagePath, response.data);
return { outputImagePath, cleanup };
}
} catch (error: any) {
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}`);
}
}
}
export default rembg;
|