First, we'll write a function that can process a local image through the Remove Background API and save the result image returned by the API to the disk:
import requestsAPI_KEY="REPLACE_WITH_YOUR_API_KEY"defprocess_image(input_image_path,output_image_path):try: url ="https://sdk.photoroom.com/v1/segment"withopen(input_image_path,'rb')as image_file: files ={"image_file": image_file } headers ={"Accept":"image/png, application/json","x-api-key":API_KEY} response = requests.post(url,files=files,headers=headers) response.raise_for_status()withopen(output_image_path,'wb')as f: f.write(response.content)print(f"Image downloaded and saved to {output_image_path}")except requests.RequestException as e:print(f"Error: {str(e)}")returnstr(e)
This code is pretty straightforward:
it opens the image stored at input_image_path
uses the requests library to make the POST HTTP call to the API
saves the result image at output_image_path
Notice that you will need to update the value of the constant API_KEY with your own API key.
Now that we have a function to process a single image, the next step is to iterate over all the images stored in a local directory and call process_image() for each of them.
This time the code is a bit more complex, but here are its important steps:
we iterate over the files inside the directory at input_directory_path
then for each file we:
compose the result_path where the result image will be saved
check that a file doesn't already exist at result_path (so as to not process the same image twice)
call the function process_image() through an executor, which allows us to execute 4 API calls in parallel
If you want, you can increase the value of the argument max_workers to run more API calls in parallel. Keep in mind though that the API is rate limited to 500 calls/minutes.
Step 3: Running the script
We're almost there, the last thing we need is to actually run the script.
To do this we'll add this final piece of code:
Here we set the constants INPUT_DIRECTORY and OUTPUT_DIRECTORY to the paths of respectively:
the directory where the input images are stored
the directory where we want to save the result images.
Then all that's left is to actually run the script using the terminal:
Conclusion
In this tutorial, we saw how to use a Python script to easily process images stored locally with the Photoroom API.
We took the example of processing images through the Remove Background API, but this approach would also work with our other APIs that accept a POST HTTP call: the Generate Background API and the Edit Image API Legacy.
Download the code sample
Here's the entire code sample, if you want to easily save it to a file:
import concurrent.futures
import os
def iterate_over_directory(input_directory_path, result_directory_path):
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
for root, _, files in os.walk(input_directory_path):
for file in files:
file_path = os.path.join(root, file)
result_file_name = os.path.splitext(os.path.basename(file_path))[0] + '.png'
result_path = os.path.join(result_directory_path, result_file_name)
if not os.path.exists(result_path): # don't re-process images
executor.submit(process_image, file_path, result_path)
if __name__ == "__main__":
INPUT_DIRECTORY = "./input/"
OUTPUT_DIRECTORY = "./output/"
if not os.path.exists(OUTPUT_DIRECTORY):
os.makedirs(OUTPUT_DIRECTORY)
iterate_over_directory(input_directory_path=INPUT_DIRECTORY, result_directory_path=OUTPUT_DIRECTORY)
$ pip install requests # run once to install the library `requests`
$ python script.py
import concurrent.futures
import os
import requests
API_KEY = "REPLACE_WITH_YOUR_API_KEY"
def process_image(input_image_path, output_image_path):
try:
url = "https://sdk.photoroom.com/v1/segment"
with open(input_image_path, 'rb') as image_file:
files = { "image_file": image_file }
headers = {
"Accept": "image/png, application/json",
"x-api-key": API_KEY
}
response = requests.post(url, files=files, headers=headers)
response.raise_for_status()
with open(output_image_path, 'wb') as f:
f.write(response.content)
print(f"Image downloaded and saved to {output_image_path}")
except requests.RequestException as e:
print(f"Error: {str(e)}")
return str(e)
def iterate_over_directory(input_directory_path, result_directory_path):
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
for root, _, files in os.walk(input_directory_path):
for file in files:
file_path = os.path.join(root, file)
result_file_name = os.path.splitext(os.path.basename(file_path))[0] + '.png'
result_path = os.path.join(result_directory_path, result_file_name)
if not os.path.exists(result_path): # don't re-process images
executor.submit(process_image, file_path, result_path)
if __name__ == "__main__":
INPUT_DIRECTORY = "./input/"
OUTPUT_DIRECTORY = "./output/"
if not os.path.exists(OUTPUT_DIRECTORY):
os.makedirs(OUTPUT_DIRECTORY)
iterate_over_directory(input_directory_path=INPUT_DIRECTORY, result_directory_path=OUTPUT_DIRECTORY)