-
Notifications
You must be signed in to change notification settings - Fork 128
Add python example #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
6387771
7fa0793
8436c75
b25729e
846d1f8
4b0a526
fa4cbce
287e471
f3424f8
5fd5235
53cb8eb
066bf61
02f4b4c
904062e
6165985
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # This demo shows how to use the APIs using Python | ||
|
|
||
| here an example of command lines: | ||
|
|
||
| python clipdrop.py --API_KEY your_api_key --api remove-background -i input -o output --background_color red |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,190 @@ | ||
| # Process files using ClipDrop API | ||
|
|
||
| import argparse | ||
| import math | ||
| import os | ||
| import sys | ||
| import time | ||
| from os import listdir | ||
| from os.path import isfile, join | ||
|
|
||
| import numpy as np | ||
| import requests | ||
| from black import main | ||
| from PIL import Image | ||
|
|
||
| parser = argparse.ArgumentParser( | ||
| description='This tool can process images using the ClipAPI.') | ||
| parser.add_argument('--API_KEY', required=True, type=str, | ||
| help='The API key to use for the API call.') | ||
| parser.add_argument('--api', required=True, choices=('remove-background', 'super-resolution'), | ||
| help='The alogrythm to be applyed on all your images') | ||
| parser.add_argument('-i', '--input', required=True, | ||
| help='the folder containing the images to process') | ||
| parser.add_argument('-o', '--output', required=True, | ||
| help='the output folder') | ||
| parser.add_argument('--upscale', type=int, default=2, | ||
| help='the upscale ratio, can be 2 or 4') | ||
| parser.add_argument('--output_format', | ||
| choices=('png', 'jpeg', 'webp'), | ||
| default='png', | ||
| help='Select the new background') | ||
| parser.add_argument('--background_color', | ||
| type=str, | ||
| default=None, | ||
| help='Select the new background color, can be any color, or chekcboard, do not set to set a transparent background') | ||
| parser.add_argument('--join', action='store_true', default=False, | ||
| help='center the image') | ||
|
|
||
| args = parser.parse_args() | ||
|
|
||
|
|
||
| # API urls and Key | ||
| SUPER_RESOLUTION = 'https://apis.clipdrop.co/super-resolution/v1' | ||
| REMOVE_BACKGROUND = 'https://apis.clipdrop.co/remove-background/v1' | ||
| API_KEY = args.API_KEY | ||
|
|
||
|
|
||
| def call_remove_background_api(input_file, output_file): | ||
| """call the API to remove the background""" | ||
| output_format = os.path.splitext(output_file)[1].lower() | ||
| img_in = open(input_file, 'rb') | ||
| files = {'image_file': ('image.jpeg', img_in, 'image/jpeg')} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if the input image is a webp / png ?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it doesn't matter. I've tryed with png and it work (ligne 53). It seems that neither the API or the services cares |
||
| # Use the extension of the output file to determine the image type | ||
| image_type = {'.png': 'image/png', '.jpeg': 'image/jpeg', | ||
dh7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| '.jpg': 'image/jpeg', '.webp': 'image/webp'}[output_format.lower()] | ||
| # Create the headers for the API call, mentionning the type of image we whant to get | ||
| headers = {'x-api-key': API_KEY, | ||
| 'accept': image_type} | ||
dh7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| r = requests.post(REMOVE_BACKGROUND, | ||
| files=files, | ||
| headers=headers) | ||
|
|
||
| if r.ok: | ||
| with open(output_file, 'wb') as f: | ||
| f.write(r.content) | ||
| else: | ||
| r.raise_for_status() | ||
|
|
||
|
|
||
| def call_super_resolution_api(input_file, output_file, scale=2): | ||
dh7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| """call the API to upscale the image""" | ||
| output_format = os.path.splitext(output_file)[1].lower() | ||
| img_in = open(input_file, 'rb') | ||
| files = {'image_file': ('image.jpeg', img_in, 'image/jpeg')} | ||
| # Use the extension of the output file to determine the image type | ||
| image_type = {'.png': 'image/png', '.jpeg': 'image/jpeg', | ||
| '.jpg': 'image/jpeg', '.webp': 'image/webp'}[output_format.lower()] | ||
| # Create the headers for the API call, mentionning the type of image we whant to get | ||
| headers = {'x-api-key': API_KEY, | ||
| 'accept': image_type} # | ||
| data = {'upscale': scale} | ||
| r = requests.post(SUPER_RESOLUTION, | ||
| files=files, | ||
| headers=headers, | ||
| data=data) | ||
|
|
||
| if r.ok: | ||
| with open(output_file, 'wb') as f: | ||
| f.write(r.content) | ||
| else: | ||
| r.raise_for_status() | ||
|
|
||
|
|
||
| def checkerboard(h, w, channels=3, tiles=16, fg=.95, bg=.6): | ||
| """Create a shape (w,h,1) array tiled with a checkerboard pattern.""" | ||
| square_size = [math.ceil(float(d / tiles) / 2) for d in [h, w]] | ||
| board = [[fg, bg] * tiles, [bg, fg] * tiles] * tiles | ||
| scaled = np.kron(board, np.ones(square_size)) | ||
| scaled = scaled[:h, :w] | ||
| return Image.fromarray(np.uint8(np.dstack([scaled]*channels)*255)) | ||
|
|
||
|
|
||
| def composite(image_in, f_out, color='white'): | ||
| """compose an image with a new background and a checkerboard""" | ||
| if color == 'checkerboard': | ||
| img = Image.open(image_in) | ||
| checker = checkerboard(h=img.size[1], w=img.size[0]) | ||
| checker.paste(img, (0, 0), img) | ||
| checker.save(f_out) | ||
| else: | ||
| img = Image.open(image_in) | ||
| background = Image.new('RGB', img.size, color=color) | ||
| background.paste(img, (0, 0), img) | ||
| background.save(f_out) | ||
|
|
||
|
|
||
| def resize(f_in, f_out, new_size): | ||
| """resize an image""" | ||
| img = Image.open(f_in) | ||
| img.thumbnail(new_size, Image.LANCZOS) | ||
| img = img.convert("RGB") | ||
| img.save(f_out) | ||
|
|
||
|
|
||
| def join_imgs(imgs, filename_out): | ||
| """join images to compare them""" | ||
| images = [Image.open(x) for x in imgs] | ||
| widths, heights = zip(*(i.size for i in images)) | ||
|
|
||
| total_width = sum(widths) | ||
| max_height = max(heights) | ||
|
|
||
| new_im = Image.new('RGB', (total_width, max_height)) | ||
|
|
||
| x_offset = 0 | ||
| for im in images: | ||
| new_im.paste(im, (x_offset, 0)) | ||
| x_offset += im.size[0] | ||
| new_im.save(filename_out) | ||
|
|
||
|
|
||
| # process all the images in the input folder | ||
| file_system = { | ||
| 'in': args.input, | ||
| 'out': args.output, | ||
| } | ||
|
|
||
| # Generate folders if needed | ||
| for key, folder in file_system.items(): | ||
| if not os.path.exists(folder): | ||
| print('Creating ', folder) | ||
| os.makedirs(folder) | ||
|
|
||
| # List files an iterate | ||
| files = [f for f in listdir(file_system['in']) | ||
| if isfile(join(file_system['in'], f))] | ||
dh7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| for file in files: | ||
| try: | ||
| print(f'Start processing {file}') | ||
| start = time.time() | ||
| if args.api == 'remove-background': | ||
| file_in = join(file_system['in'], file) | ||
| name = os.path.splitext(file)[0] | ||
| if args.background_color: | ||
| file_out = join(file_system['out'], f'{name}.png') | ||
| call_remove_background_api(file_in, 'temp.png') | ||
| composite('temp.png', file_out, args.background_color) | ||
| os.remove('temp.png') | ||
| else: | ||
| file_out = join(file_system['out'], | ||
| f'{name}.{args.output_format}') | ||
| call_remove_background_api(file_in, file_out) | ||
| elif args.api == 'super-resolution': | ||
| file_in = join(file_system['in'], file) | ||
| name = os.path.splitext(file)[0] | ||
| file_out = join(file_system['out'], f'{name}.{args.output_format}') | ||
| call_super_resolution_api(file_in, file_out, args.upscale) | ||
| if args.join: | ||
| join_imgs([file_in, file_out], file_out) | ||
| end = time.time() | ||
| print(f'{file} processed in {end - start} seconds') | ||
|
|
||
| except KeyboardInterrupt: | ||
| print('Interrupted') | ||
| try: | ||
| sys.exit(0) | ||
| except SystemExit: | ||
| os._exit(0) | ||
| except BaseException as error: | ||
| print('Error with {}, {}'.format(file_system['in'], error)) | ||
Uh oh!
There was an error while loading. Please reload this page.