百度接口的申请就不赘述了。
主要用到了百度人体分析api和PIL库,主要实现三个功能:
具体方法
python3.8以上
from aip import AipBodyAnalysis
from PIL import Image
import base64
import requests
import os
import time
APP_ID = '****'
API_KEY = '****'
SECRET_KEY = '****'
client = AipBodyAnalysis(APP_ID, API_KEY, SECRET_KEY)
def create_dir(path):
if not os.path.exists(path):
os.mkdir(path)
class Zjz:
def __init__(self):
self.prefix_url = "https://aip.baidubce.com/rest/2.0/image-classify/v1/body_seg?access_token="
self.host = f'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={API_KEY}&client_secret={SECRET_KEY}'
self.save_path = r'C:\Users\Administrator\Pictures\Camera Roll'
self.pending_path = r'C:\Users\Administrator\Pictures\Temporary image'
self.access_token = None
self.original_image_path = None
self.response = None
self.foreground = None
self.original_size = None
self.bool_invalid = None
self.images = []
self.image_names = []
self.background_colors = ['white', 'blue', 'red', 'green', 'pink', 'yellow', 'purple', 'black', 'snow']
print('You must give the path of the image')
def get_access_token(self):
if response := requests.get(self.host):
self.access_token = response.json()['access_token']
def valid(self, image_path):
try:
(image := Image.open(image_path)).verify()
self.bool_invalid = False
if 0 in image.size:
self.bool_invalid = True
print(image.size)
except Exception as e:
print(e)
self.bool_invalid = True
def get_portrait(self):
with open(self.original_image_path, 'rb') as fp:
img = base64.b64encode(fp.read())
headers = {'content-type': 'application/x-www-form-urlencoded'}
params = {"image": img}
filename = f'{self.pending_path}/{os.path.basename(os.path.splitext(self.original_image_path)[0])}.png'
print('portrait: ', filename)
self.valid(filename)
if not os.path.exists(filename) or self.bool_invalid is True:
self.get_access_token()
self.response = requests.post(self.prefix_url + self.access_token, data=params, headers=headers)
if self.response:
with open(filename, 'wb') as fp:
fp.write(image_data := base64.b64decode(self.response.json()['foreground']))
try:
self.foreground = Image.open(image_data)
except Exception as e:
print(e)
else:
self.foreground = Image.open(filename)
def get_background(self):
self.original_size = Image.open(self.original_image_path).size
print(self.original_size)
for color in self.background_colors[:3]:
self.images.append(Image.new('RGBA', self.original_size, color))
def main(self):
create_dir(self.pending_path)
self.get_portrait()
self.get_background()
r, g, b, a = self.foreground.split()
for i, image in enumerate(self.images):
image.paste(self.foreground, (0, 0), mask=a)
image.save(temp := f'{self.save_path}/ZJZ_{self.background_colors[i][:2].upper()}_'
f'{os.path.basename(os.path.splitext(self.original_image_path)[0])}_'
f'{time.strftime("%Y%m%d", time.localtime())}.png')
self.image_names.append(temp)
def resize(self, width=250, color='white'):
ratio = self.original_size[1] / self.original_size[0]
height = int(width * ratio)
fore = self.foreground.resize((width, height))
image = Image.new('RGBA', (width, height), color)
image.paste(fore, (0, 0), mask=fore.split()[-1])
image.save(temp := f'{self.save_path}/ZJZ_RESIZE_{time.strftime("%Y%m%d", time.localtime())}.png')
self.image_names.append(temp)
def conversion(self):
for filename in self.image_names:
image = Image.open(filename)
output_file = os.path.splitext(filename)[0] + '.jpg'
try:
r, g, b, a = image.split()
image = Image.merge("RGB", (r, g, b))
image.convert("RGB").save(output_file, quality=50)
except Exception as e:
print("Format conversion failed", e)
def delete_invalid_image(self):
for file in os.listdir(self.save_path):
file = os.path.join(self.save_path, file)
self.valid(file)
if self.bool_invalid and 'jpg' in file:
enter = input(f'you want to delete the file "{file}"?\n')
if enter in ('y', 'Y', 'yes'):
os.remove(file)
if __name__ == "__main__":
photo = Zjz()
photo.original_image_path = r'C:\Users\Administrator\Pictures\Saved Pictures\psc2.webp'
photo.main()
# photo.resize()
photo.conversion()
# photo.delete_invalid_image()