diff --git a/package-lock.json b/package-lock.json index 4abfae8..781c65a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,6 +34,7 @@ "dayjs": "^1.11.13", "fast-xml-parser": "^5.2.5", "formik": "^2.4.6", + "heic2any": "^0.0.4", "i18next": "^25.3.2", "i18next-browser-languagedetector": "^8.2.0", "i18next-http-backend": "^3.0.2", @@ -7025,6 +7026,12 @@ "node": ">= 0.4" } }, + "node_modules/heic2any": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/heic2any/-/heic2any-0.0.4.tgz", + "integrity": "sha512-3lLnZiDELfabVH87htnRolZ2iehX9zwpRyGNz22GKXIu0fznlblf0/ftppXKNqS26dqFSeqfIBhAmAj/uSp0cA==", + "license": "MIT" + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", diff --git a/package.json b/package.json index 6c3c93c..ecd8f8e 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "dayjs": "^1.11.13", "fast-xml-parser": "^5.2.5", "formik": "^2.4.6", + "heic2any": "^0.0.4", "i18next": "^25.3.2", "i18next-browser-languagedetector": "^8.2.0", "i18next-http-backend": "^3.0.2", diff --git a/src/pages/tools/image/generic/remove-background/index.tsx b/src/pages/tools/image/generic/remove-background/index.tsx index 8c70633..4d0d312 100644 --- a/src/pages/tools/image/generic/remove-background/index.tsx +++ b/src/pages/tools/image/generic/remove-background/index.tsx @@ -5,6 +5,7 @@ import ToolContent from '@components/ToolContent'; import { ToolComponentProps } from '@tools/defineTool'; import ToolImageInput from '@components/input/ToolImageInput'; import { removeBackground } from '@imgly/background-removal'; +import * as heic2any from 'heic2any'; const initialValues = {}; @@ -23,8 +24,33 @@ export default function RemoveBackgroundFromImage({ setIsProcessing(true); try { - // Convert the input file to a Blob URL - const inputUrl = URL.createObjectURL(input); + let fileToProcess = input; + // Check if the file is HEIC (by MIME type or extension) + if ( + input.type === 'image/heic' || + input.name?.toLowerCase().endsWith('.heic') + ) { + // Convert HEIC to PNG using heic2any + const convertedBlob = await heic2any.default({ + blob: input, + toType: 'image/png' + }); + // heic2any returns a Blob or an array of Blobs + let pngBlob; + if (Array.isArray(convertedBlob)) { + pngBlob = convertedBlob[0]; + } else { + pngBlob = convertedBlob; + } + fileToProcess = new File( + [pngBlob], + input.name.replace(/\.[^/.]+$/, '') + '.png', + { type: 'image/png' } + ); + } + + // Convert the file to a Blob URL + const inputUrl = URL.createObjectURL(fileToProcess); // Process the image with the background removal library const blob = await removeBackground(inputUrl, { @@ -36,7 +62,7 @@ export default function RemoveBackgroundFromImage({ // Create a new file from the blob const newFile = new File( [blob], - input.name.replace(/\.[^/.]+$/, '') + '-no-bg.png', + fileToProcess.name.replace(/\.[^/.]+$/, '') + '-no-bg.png', { type: 'image/png' }