diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 571d6ae..c2b1f69 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,18 +5,12 @@
-
-
-
-
+
+
-
-
-
-
-
-
-
+
+
+
@@ -138,7 +132,7 @@
"Vitest.removeDuplicateLines function.newlines option.should filter newlines when newlines is set to filter.executor": "Run",
"Vitest.replaceText function (regexp mode).should return the original text when passed an invalid regexp.executor": "Run",
"Vitest.replaceText function.executor": "Run",
- "git-widget-placeholder": "refactor-file-input",
+ "git-widget-placeholder": "main",
"ignore.virus.scanning.warn.message": "true",
"kotlin-language-version-configured": "true",
"last_opened_file_path": "C:/Users/Ibrahima/IdeaProjects/omni-tools/src/pages/tools/list/duplicate/index.tsx",
@@ -351,14 +345,6 @@
-
-
- 1740488522618
-
-
-
- 1740488522618
-
1740490919407
@@ -743,7 +729,15 @@
1741580736359
-
+
+
+ 1742960931740
+
+
+
+ 1742960931740
+
+
@@ -790,7 +784,6 @@
-
@@ -815,7 +808,8 @@
-
+
+
diff --git a/package-lock.json b/package-lock.json
index 4d80209..95e7f37 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,7 @@
"@ffmpeg/core": "^0.12.10",
"@ffmpeg/ffmpeg": "^0.12.15",
"@ffmpeg/util": "^0.12.2",
+ "@imgly/background-removal": "^1.6.0",
"@jimp/types": "^1.6.0",
"@mui/icons-material": "^5.15.20",
"@mui/material": "^5.15.20",
@@ -1528,6 +1529,20 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@imgly/background-removal": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@imgly/background-removal/-/background-removal-1.6.0.tgz",
+ "integrity": "sha512-nmqOBDE9dQpDEJg73XrKNUoWugyyDHEVh+U1akjYdUW85ILh9UilvKu/kdv1MI822rKExwgLNuVLVulzAzgZJg==",
+ "license": "SEE LICENSE IN LICENSE.md",
+ "dependencies": {
+ "lodash-es": "^4.17.21",
+ "ndarray": "~1.0.0",
+ "zod": "^3.23.8"
+ },
+ "peerDependencies": {
+ "onnxruntime-web": "1.21.0-dev.20250206-d981b153d3"
+ }
+ },
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -2362,6 +2377,80 @@
"url": "https://opencollective.com/popperjs"
}
},
+ "node_modules/@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "node_modules/@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
"node_modules/@remix-run/router": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz",
@@ -3022,7 +3111,6 @@
"version": "20.14.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.6.tgz",
"integrity": "sha512-JbA0XIJPL1IiNnU7PFxDXyfAwcwVVrOoqyzzyQTyMeVhBzkJVMSkC1LlVsRQ2lpqiY4n6Bb9oCS6lzDKVQxbZw==",
- "dev": true,
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -5591,6 +5679,13 @@
"node": "^10.12.0 || >=12.0.0"
}
},
+ "node_modules/flatbuffers": {
+ "version": "25.2.10",
+ "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.2.10.tgz",
+ "integrity": "sha512-7JlN9ZvLDG1McO3kbX0k4v+SUAg48L1rIwEvN6ZQl/eCtgJz9UylTMzE9wrmYrcorgxm3CX/3T/w5VAub99UUw==",
+ "license": "Apache-2.0",
+ "peer": true
+ },
"node_modules/flatted": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
@@ -6033,6 +6128,13 @@
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"dev": true
},
+ "node_modules/guid-typescript": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz",
+ "integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==",
+ "license": "ISC",
+ "peer": true
+ },
"node_modules/happy-dom": {
"version": "12.10.3",
"resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-12.10.3.tgz",
@@ -6300,6 +6402,12 @@
"node": ">= 0.4"
}
},
+ "node_modules/iota-array": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/iota-array/-/iota-array-1.0.0.tgz",
+ "integrity": "sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==",
+ "license": "MIT"
+ },
"node_modules/is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@@ -6392,6 +6500,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "license": "MIT"
+ },
"node_modules/is-callable": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
@@ -7389,6 +7503,13 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
+ "node_modules/long": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.3.1.tgz",
+ "integrity": "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==",
+ "license": "Apache-2.0",
+ "peer": true
+ },
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -7652,6 +7773,16 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
+ "node_modules/ndarray": {
+ "version": "1.0.19",
+ "resolved": "https://registry.npmjs.org/ndarray/-/ndarray-1.0.19.tgz",
+ "integrity": "sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==",
+ "license": "MIT",
+ "dependencies": {
+ "iota-array": "^1.0.0",
+ "is-buffer": "^1.0.2"
+ }
+ },
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
@@ -7912,6 +8043,28 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/onnxruntime-common": {
+ "version": "1.21.0-dev.20250206-d981b153d3",
+ "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.21.0-dev.20250206-d981b153d3.tgz",
+ "integrity": "sha512-TwaE51xV9q2y8pM61q73rbywJnusw9ivTEHAJ39GVWNZqxCoDBpe/tQkh/w9S+o/g+zS7YeeL0I/2mEWd+dgyA==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/onnxruntime-web": {
+ "version": "1.21.0-dev.20250206-d981b153d3",
+ "resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.21.0-dev.20250206-d981b153d3.tgz",
+ "integrity": "sha512-esDVQdRic6J44VBMFLumYvcGfioMh80ceLmzF1yheJyuLKq/Th8VT2aj42XWQst+2bcWnAhw4IKmRQaqzU8ugg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "flatbuffers": "^25.1.24",
+ "guid-typescript": "^1.0.9",
+ "long": "^5.2.3",
+ "onnxruntime-common": "1.21.0-dev.20250206-d981b153d3",
+ "platform": "^1.3.6",
+ "protobufjs": "^7.2.4"
+ }
+ },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -8196,6 +8349,13 @@
"pathe": "^1.1.2"
}
},
+ "node_modules/platform": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",
+ "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==",
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/playwright": {
"version": "1.45.0",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.0.tgz",
@@ -8511,6 +8671,31 @@
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz",
"integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA=="
},
+ "node_modules/protobufjs": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz",
+ "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==",
+ "hasInstallScript": true,
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/node": ">=13.7.0",
+ "long": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
@@ -10180,8 +10365,7 @@
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
- "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
- "dev": true
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
"node_modules/unicorn-magic": {
"version": "0.1.0",
diff --git a/package.json b/package.json
index b69da3d..2bd110c 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
"@ffmpeg/core": "^0.12.10",
"@ffmpeg/ffmpeg": "^0.12.15",
"@ffmpeg/util": "^0.12.2",
+ "@imgly/background-removal": "^1.6.0",
"@jimp/types": "^1.6.0",
"@mui/icons-material": "^5.15.20",
"@mui/material": "^5.15.20",
diff --git a/src/pages/tools/image/png/index.ts b/src/pages/tools/image/png/index.ts
index c5a6a34..f248619 100644
--- a/src/pages/tools/image/png/index.ts
+++ b/src/pages/tools/image/png/index.ts
@@ -4,6 +4,7 @@ import { tool as convertJgpToPng } from './convert-jgp-to-png/meta';
import { tool as pngCreateTransparent } from './create-transparent/meta';
import { tool as changeColorsInPng } from './change-colors-in-png/meta';
import { tool as changeOpacity } from './change-opacity/meta';
+import { tool as removeBackground } from './remove-background/meta';
export const pngTools = [
pngCompressPng,
@@ -11,5 +12,6 @@ export const pngTools = [
changeColorsInPng,
convertJgpToPng,
changeOpacity,
- pngCrop
+ pngCrop,
+ removeBackground
];
diff --git a/src/pages/tools/image/png/remove-background/index.tsx b/src/pages/tools/image/png/remove-background/index.tsx
new file mode 100644
index 0000000..7825092
--- /dev/null
+++ b/src/pages/tools/image/png/remove-background/index.tsx
@@ -0,0 +1,104 @@
+import { Box, CircularProgress, Typography } from '@mui/material';
+import React, { useState } from 'react';
+import * as Yup from 'yup';
+import ToolFileResult from '@components/result/ToolFileResult';
+import ToolContent from '@components/ToolContent';
+import { ToolComponentProps } from '@tools/defineTool';
+import ToolImageInput from '@components/input/ToolImageInput';
+import { removeBackground } from '@imgly/background-removal';
+
+const initialValues = {};
+
+const validationSchema = Yup.object({});
+
+export default function RemoveBackgroundFromPng({ title }: ToolComponentProps) {
+ const [input, setInput] = useState(null);
+ const [result, setResult] = useState(null);
+ const [isProcessing, setIsProcessing] = useState(false);
+
+ const compute = async (_optionsValues: typeof initialValues, input: any) => {
+ if (!input) return;
+
+ setIsProcessing(true);
+
+ try {
+ // Convert the input file to a Blob URL
+ const inputUrl = URL.createObjectURL(input);
+
+ // Process the image with the background removal library
+ const blob = await removeBackground(inputUrl, {
+ progress: (progress) => {
+ console.log(`Background removal progress: ${progress}`);
+ }
+ });
+
+ // Create a new file from the blob
+ const newFile = new File(
+ [blob],
+ input.name.replace(/\.[^/.]+$/, '') + '-no-bg.png',
+ {
+ type: 'image/png'
+ }
+ );
+
+ setResult(newFile);
+ } catch (err) {
+ console.error('Error removing background:', err);
+ throw new Error(
+ 'Failed to remove background. Please try a different image or try again later.'
+ );
+ } finally {
+ setIsProcessing(false);
+ }
+ };
+
+ return (
+
+ }
+ resultComponent={
+ <>
+ {isProcessing ? (
+
+
+
+ Removing background... This may take a moment.
+
+
+ ) : (
+
+ )}
+ >
+ }
+ toolInfo={{
+ title: 'Remove Background from PNG',
+ description:
+ 'This tool uses AI to automatically remove the background from your images, creating a transparent PNG. Perfect for product photos, profile pictures, and design assets.'
+ }}
+ />
+ );
+}
diff --git a/src/pages/tools/image/png/remove-background/meta.ts b/src/pages/tools/image/png/remove-background/meta.ts
new file mode 100644
index 0000000..1ae19e7
--- /dev/null
+++ b/src/pages/tools/image/png/remove-background/meta.ts
@@ -0,0 +1,13 @@
+import { defineTool } from '@tools/defineTool';
+import { lazy } from 'react';
+
+export const tool = defineTool('png', {
+ name: 'Remove Background from PNG',
+ path: 'remove-background',
+ icon: 'mdi:image-remove',
+ description:
+ "World's simplest online tool to remove backgrounds from PNG images. Just upload your image and our AI-powered tool will automatically remove the background, giving you a transparent PNG. Perfect for product photos, profile pictures, and design assets.",
+ shortDescription: 'Automatically remove backgrounds from images',
+ keywords: ['remove', 'background', 'png', 'transparent', 'image', 'ai'],
+ component: lazy(() => import('./index'))
+});