# Removing Backgrounds

Source: https://docs.prodia.com/guides/removing-backgrounds/

We're going to walk through how to take an input image, create a mask for the
background, and use it to remove the background leaving just the foreground.

We'll be using one of our cute puppies-in-the-clouds gens as our input image:

![input.jpg](https://docs.prodia.com/llms/assets/77d2e1b0eff3-flux-styles-output.jpg)

Once we are finished we'll have removed the clouds and we be left with just
cute puppies.

### Project Setup

```bash
# Create a project directory.
mkdir prodia-removing-backgrounds
cd prodia-removing-backgrounds
```

### prodia-js

Install Node (if not already installed):

### macOS

```bash
brew install node
# Close the current terminal and open a new one so that node is available.
```

### Linux

```bash
apt install node
# Close the current terminal and open a new one so that node is available.
```

### Windows

```bash
winget install -e --id OpenJS.NodeJS.LTS
# Close the current terminal and open a new one so that node is available.
```

Create project skeleton:

```bash
# Requires node --version >= 18
# Initialize the project with npm.
npm init -y

# Install the prodia-js library.
npm install prodia --save
```

### requests

Install Python (if not already installed):

### macOS

```bash
brew install python
# Close the current terminal and open a new one so that python is available.
```

### Linux

```bash
apt install python3 python3-venv python-is-python3
# Close the current terminal and open a new one so that python is available.
```

### Windows

```bash
winget install -e --id Python.Python.3.12
# Close the current terminal and open a new one so that python is available.
```

```bash
# Requires python --version >= 3.12
python -m venv venv
source venv/bin/activate
pip install requests
```

### curl

Install curl (if not already installed):

### macOS

```bash
brew install curl
# Close the current terminal and open a new one so that curl is available.
```

### Linux

```bash
apt install curl
# Close the current terminal and open a new one so that curl is available.
```

### Windows

```bash
# NOTE: Windows 10 and up have curl installed by default and this can be
# skipped.
winget install -e --id cURL.cURL
# Close the current terminal and open a new one so that curl is available.
```

```bash
# Export your token so it can be used by the main code.
export PRODIA_TOKEN=your-token-here
```

> note:
>
> Your token is exported to an environment variable. If you close or switch your
> shell you'll need to run `export PRODIA_TOKEN=your-token-here` again.

Create a main file for your project:

### prodia-js

```js title="main.js"
const { createProdia } = require("prodia/v2");

const prodia = createProdia({
    token: process.env.PRODIA_TOKEN // get it from environment
});
```

### requests

Create the following `main.py`

```python title="main.py"
from requests.adapters import HTTPAdapter, Retry
import os
import requests
import sys


prodia_token = os.getenv('PRODIA_TOKEN')
prodia_url = 'https://inference.prodia.com/v2/job'

session = requests.Session()
retries = Retry(allowed_methods=None, status_forcelist=Retry.RETRY_AFTER_STATUS_CODES)
session.mount('http://', HTTPAdapter(max_retries=retries))
session.mount('https://', HTTPAdapter(max_retries=retries))
session.headers.update({'Authorization': f"Bearer {prodia_token}"})
```

### curl

```bash title="main.sh"
set -euo pipefail
```

You're now ready to make some API calls!

### Get a mask for the background pixels

### prodia-js

```bash
npm install sharp --save
```

```javascript
const { createProdia } = require("prodia/v2");
const sharp = require("sharp");

const prodia = createProdia({
  token: process.env.PRODIA_TOKEN,
});

(async () => {
  // get input image
  const inputBuffer = await (await fetch("https://docs.prodia.com/flux-styles-output.jpg")).arrayBuffer();
  await sharp(inputBuffer).toFile("flux-styles-output.jpg");

  // run a flux schnell generation
  const job = await prodia.job({
    type: "inference.mask-background.v1",
  }, {
    inputs: [ inputBuffer ]
  });

  const maskBuffer = await job.arrayBuffer();
  await sharp(maskBuffer).toFile("mask.png");
})();
```

```bash
node main.js
```

### requests

```python
from requests.adapters import HTTPAdapter, Retry
from io import BytesIO
import json
import os
import requests
import sys


prodia_token = os.getenv('PRODIA_TOKEN')
prodia_url = 'https://inference.prodia.com/v2/job'

session = requests.Session()
retries = Retry(allowed_methods=None, status_forcelist=Retry.RETRY_AFTER_STATUS_CODES)
session.mount('http://', HTTPAdapter(max_retries=retries))
session.mount('https://', HTTPAdapter(max_retries=retries))
session.headers.update({'Authorization': f"Bearer {prodia_token}"})

try:
    with open('flux-styles-output.jpg', 'rb') as f:
        input_image = f.read()
except FileNotFoundError:
    res = requests.get('https://docs.prodia.com/flux-styles-output.jpg')
    input_image = BytesIO(res.content)
    with open('flux-styles-output.jpg', 'wb') as f:
        f.write(res.content)
except Exception as e:
    raise e

headers = {
    'Accept': 'image/png',
}

job = {
    'type': 'inference.mask-background.v1',
}

files = [
    ('job', ('job.json', BytesIO(json.dumps(job).encode('utf-8')), 'application/json')),
    ('input', ('flux-styles-output.jpg', input_image, 'image/jpeg')),
]

res = session.post(prodia_url, headers=headers, files=files)
print(f"Request ID: {res.headers['x-request-id']}")
print(f"Status: {res.status_code}")

if res.status_code != 200:
    print(res.text)
    sys.exit(1)

with open('mask.png', 'wb') as f:
    f.write(res.content)
```

```bash
python main.py
```

### curl

```bash
set -euo pipefail
   
cat <<EOF > job.json
{  
  "type": "inference.mask-background.v1"
}  
EOF
   
if [[ ! -f flux-styles-output.jpg ]]; then
  curl -Lo flux-styles-output.jpg 'https://docs.prodia.com/flux-styles-output.jpg'
fi 
   
curl -sSf --retry 3 \
  -H "Authorization: Bearer $PRODIA_TOKEN" \
  -H 'Accept: image/png' \
  -F job=@job.json \
  -F input=@flux-styles-output.jpg \
  --output mask.png \
  https://inference.prodia.com/v2/job
```

```bash
bash main.sh
```

### macOS

```bash
open mask.png
```

### Linux

```bash
xdg-open mask.png
```

### Windows

```bash
start mask.png
```

![mask.png](https://docs.prodia.com/llms/assets/c12ee6aeec61-mask.png)

### Selecting the foreground

### prodia-js

```bash
npm install sharp --save
```

```javascript
const { createProdia } = require("prodia/v2");
const sharp = require("sharp");

const prodia = createProdia({
  token: process.env.PRODIA_TOKEN,
});

(async () => {
  // get input image
  const inputBuffer = await (await fetch("https://docs.prodia.com/flux-styles-output.jpg")).arrayBuffer();
  await sharp(inputBuffer).toFile("flux-styles-output.jpg");

  // run a flux schnell generation
  const job = await prodia.job({
    type: "inference.mask-background.v1",
  }, {
    inputs: [ inputBuffer ]
  });

  const maskBuffer = await job.arrayBuffer();
  await sharp(maskBuffer).toFile("mask.png");

  let foregroundImage = await sharp(inputBuffer).ensureAlpha().joinChannel(maskBuffer);
  await foregroundImage.toFile("foreground.png");
})();
```

```bash
node main.js
```

### requests

```bash
pip install pillow
```

```python
from requests.adapters import HTTPAdapter, Retry
from io import BytesIO
from PIL import Image
import json
import os
import requests
import sys


prodia_token = os.getenv('PRODIA_TOKEN')
prodia_url = 'https://inference.prodia.com/v2/job'

session = requests.Session()
retries = Retry(allowed_methods=None, status_forcelist=Retry.RETRY_AFTER_STATUS_CODES)
session.mount('http://', HTTPAdapter(max_retries=retries))
session.mount('https://', HTTPAdapter(max_retries=retries))
session.headers.update({'Authorization': f"Bearer {prodia_token}"})

try:
    with open('flux-styles-output.jpg', 'rb') as f:
        input_image = f.read()
except FileNotFoundError:
    res = requests.get('https://docs.prodia.com/flux-styles-output.jpg')
    input_image = BytesIO(res.content)
    with open('flux-styles-output.jpg', 'wb') as f:
        f.write(res.content)
except Exception as e:
    raise e

headers = {
    'Accept': 'image/png',
}

job = {
    'type': 'inference.mask-background.v1',
}

files = [
    ('job', ('job.json', BytesIO(json.dumps(job).encode('utf-8')), 'application/json')),
    ('input', ('flux-styles-output.jpg', input_image, 'image/jpeg')),
]

res = session.post(prodia_url, headers=headers, files=files)
print(f"Request ID: {res.headers['x-request-id']}")
print(f"Status: {res.status_code}")

if res.status_code != 200:
    print(res.text)
    sys.exit(1)

with open('mask.png', 'wb') as f:
    f.write(res.content)
    mask = Image.open(BytesIO(res.content))

image = Image.open(input_image)
image.putalpha(mask)
image.save('foreground.png')
```

```bash
python main.py
```

### curl

```bash
apt install imagemagick
```

```bash
set -euo pipefail    
 
cat <<EOF > job.json 
{
  "type": "inference.mask-background.v1"
}
EOF                  
 
if [[ ! -f flux-styles-output.jpg ]]; then
  curl -Lo flux-styles-output.jpg 'https://docs.prodia.com/flux-styles-output.jpg'
fi
 
curl -sSf --retry 3 \
  -H "Authorization: Bearer $PRODIA_TOKEN" \
  -H 'Accept: image/png' \
  -F job=@job.json \ 
  -F input=@flux-styles-output.jpg \
  --output mask.png \              
  https://inference.prodia.com/v2/job
 
magick flux-styles-output.jpg mask.png -alpha Off -compose CopyOpacity -composite foreground.png
```

```bash
bash main.sh
```

### macOS

```bash
open foreground.png
```

### Linux

```bash
xdg-open foreground.png
```

### Windows

```bash
start foreground.png
```

![foreground.png](https://docs.prodia.com/llms/assets/8fcc759f706d-foreground.png)
