imgly / background-removal-js

Remove backgrounds from images directly in the browser environment with ease and no additional costs or privacy concerns. Explore an interactive demo.
https://img.ly/showcases/cesdk/web/background-removal/web
GNU Affero General Public License v3.0
5.89k stars 362 forks source link

Error: Unsupported protocol: c: #112

Closed MilanAhir227 closed 4 months ago

MilanAhir227 commented 7 months ago

const fs = require("fs"); const { removeBackground } = require("@imgly/background-removal-node");

async function saveBlobToDisk(blob, outputPath) { try { const buffer = Buffer.from(await blob.arrayBuffer()); fs.writeFileSync(outputPath, buffer); console.log("File saved successfully:", outputPath); return 0; } catch (error) { console.error("Error saving file:", error); return 1; } }

async function remove(imgSource, outputPath) { try { let blob = await removeBackground(imgSource); await saveBlobToDisk(blob, outputPath); } catch (error) { console.error("Error removing background:", error); } }

remove( "C:/Users/milanahir227/Desktop/background image/public/test.jpg", "C:/Users/milanahir227/Desktop/background image/public/output.png" );

in this code when run with node then gave me this like error

Error =>

Error removing background: Error: Unsupported protocol: c: at loadFromURI (C:\Users\milanahir227\Desktop\js\node_modules\@imgly\background-removal-node\dist\index.cjs:174:13) at imageSourceToImageData (C:\Users\milanahir227\Desktop\js\node_modules\@imgly\background-removal-node\dist\index.cjs:271:26) at removeBackground (C:\Users\milanahir227\Desktop\js\node_modules\@imgly\background-removal-node\dist\index.cjs:505:29) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async remove (C:\Users\milanahir227\Desktop\js\imagetoarrbuffer.js:18:16)

can any face like this error ?
GangYiKhor commented 7 months ago

Same here, seems like its absolute path problem. Tried with relative path and it is fine.

Code

// Relative Path
console.log("Removing:", "./img/background.jpg");
await removeBackground(path.join("./img/background.jpg"), config);
console.log("Success");

// Absolute Path
console.log("Removing:", path.join(process.cwd(), "img", "background.jpg"));
await removeBackground(
path.join(process.cwd(), "img", "background.jpg"),
config
);
console.log("Success");

Output

Removing: ./img/background.jpg
Success
Removing: C:\Users\USER\Documents\Development\strangerfie\img\background.jpg
Error: Unsupported protocol: c:
    at loadFromURI (file:///C:/Users/USER/Documents/Development/strangerfie/node_modules/@imgly/background-removal-node/dist/index.mjs:137:13)
    at imageSourceToImageData (file:///C:/Users/USER/Documents/Development/strangerfie/node_modules/@imgly/background-removal-node/dist/index.mjs:234:26) 
    at removeBackground (file:///C:/Users/USER/Documents/Development/strangerfie/node_modules/@imgly/background-removal-node/dist/index.mjs:468:29)       
    at async localRemoveBgServices (webpack-internal:///(api)/./src/pages/api/uploadFile/localRemoveBgServices.ts:28:5)
    at async uploadFileServices (webpack-internal:///(api)/./src/pages/api/uploadFile/uploadFileServices.ts:20:31)
    at async uploadFileHandler (webpack-internal:///(api)/./src/pages/api/uploadFile/index.ts:13:59)
    at async K (C:\Users\USER\Documents\Development\strangerfie\node_modules\next\dist\compiled\next-server\pages-api.runtime.dev.js:21:2946)
    at async U.render (C:\Users\USER\Documents\Development\strangerfie\node_modules\next\dist\compiled\next-server\pages-api.runtime.dev.js:21:3827)      
    at async DevServer.runApi (C:\Users\USER\Documents\Development\strangerfie\node_modules\next\dist\server\next-server.js:554:9)
    at async NextNodeServer.handleCatchallRenderRequest (C:\Users\USER\Documents\Development\strangerfie\node_modules\next\dist\server\next-server.js:266:37)
    at async DevServer.handleRequestImpl (C:\Users\USER\Documents\Development\strangerfie\node_modules\next\dist\server\base-server.js:791:17)
    at async C:\Users\USER\Documents\Development\strangerfie\node_modules\next\dist\server\dev\next-dev-server.js:331:20
    at async Span.traceAsyncFn (C:\Users\USER\Documents\Development\strangerfie\node_modules\next\dist\trace\trace.js:151:20)
    at async DevServer.handleRequest (C:\Users\USER\Documents\Development\strangerfie\node_modules\next\dist\server\dev\next-dev-server.js:328:24)        
    at async invokeRender (C:\Users\USER\Documents\Development\strangerfie\node_modules\next\dist\server\lib\router-server.js:174:21)
JPhilipp commented 7 months ago

Same issue here. Unfortunately I seem to need the absolute path for the distributed Electron app. Help please?

GangYiKhor commented 7 months ago

Same issue here. Unfortunately I seem to need the absolute path for the distributed Electron app. Help please?

Hi @JPhilipp, I've found a fix for it.

You may try reading the file yourself and pass the data to imgly, instead of passing the file path Be sure to set the type: "image/jpeg" when creating the Blob This is my code. Hope it helps.

import { removeBackground, Config } from "@imgly/background-removal-node";

export default async function localRemoveBgServices(
    imageBuffer: Buffer  // The imageBuffer is read somewhere with fs.readFileSync(...);
): Promise<Buffer> {
    let config: Config = {
        output: { format: "image/png" },
    };
    const blob = new Blob([imageBuffer], { type: "image/jpeg" });

    const removedBackground = await removeBackground(blob, config);

    return Buffer.from(await removedBackground.arrayBuffer());
}
JPhilipp commented 6 months ago

Thank you, I will try that!

JPhilipp commented 6 months ago

Strange. I now switched to the suggested blob passing, and it all works fine in the dev version, but again when I run it from the distribution, it doesn't generate the image. Even though the image with background saves fine in the distribution at the same foo.png path instead of foo-background-removed.png path. I'm so confused.

    let removeBackgroundConfig = {
      debug: false,
      output: {
        format: 'image/png',
        quality: 1.0
      }
    };

    const imageBuffer = fs.readFileSync(path);
    const blob = new Blob([imageBuffer], { type: "image/png" }); // I use png, not jpeg, but it works fine locally.
    const removedBackgroundBlob = await removeBackground(blob, removeBackgroundConfig);
    const buffer = Buffer.from(await removedBackgroundBlob.arrayBuffer());
    fs.writeFileSync(removedBackgroundPath, buffer);
GangYiKhor commented 6 months ago

Strange. I now switched to the suggested blob passing, and it all works fine in the dev version, but again when I run it from the distribution, it doesn't generate the image. Even though the image with background saves fine in the distribution at the same foo.png path instead of foo-background-removed.png path. I'm so confused.

    let removeBackgroundConfig = {
      debug: false,
      output: {
        format: 'image/png',
        quality: 1.0
      }
    };

    const imageBuffer = fs.readFileSync(path);
    const blob = new Blob([imageBuffer], { type: "image/png" }); // I use png, not jpeg, but it works fine locally.
    const removedBackgroundBlob = await removeBackground(blob, removeBackgroundConfig);
    const buffer = Buffer.from(await removedBackgroundBlob.arrayBuffer());
    fs.writeFileSync(removedBackgroundPath, buffer);

Would it probably because of the removedBackgroundPath in distribution is different? Perhaps you can try console log the buffer (to make sure it does removed background), and the removedBackgroundPath to see where it actually writes to. Since there is no error message thrown, I guess the removedBackgroundBlob did work

DanielHauschildt commented 6 months ago

I think it's a problem with the Asset Resolver which dispatches based on URIs and it tries to parse the path as URI, as such "C" becomes the protocol.

I have no windows machine to debug that case atm.

DanielHauschildt commented 6 months ago

This is the root cause I think: https://github.com/imgly/background-removal-js/blob/5bbd94373fdc6dd52212e8eb8217398990b89e25/packages/node/src/resource.ts#L12