上一篇文章封装和使用了文本情感分析功能,这一篇更进一步,封装了滤镜和通用OCR功能。
与上一篇不同的是,传递文本信息只需要将文本编码到URL中,用GET方式请求数据。图片体积图片需要先对图片进行base64编码,然后例行生成md5摘要字符串,之后使用POST方法请求数据。考虑到两种请求方式的不同,在上一篇的基础上,我对基类的接口进行了扩展,分别对两种不同的请求数据方式,设计了两个不同的接口get_url和get_params。
UML类图:
qqaibase.py
'''
date:2019.7.7
copyright:buaalzm
'''
import time
import random
import string
from abc import ABCMeta, abstractmethod
class QQAIBase():
__metaclass__ = ABCMeta
param_dict = {}
def __init__(self, app_id, app_key):
self.param_dict['app_id'] = app_id
self.param_dict['app_key'] = app_key
def basic_param_init(self):
'''请求时间戳(秒级),用于防止请求重放(保证签名5分钟有效)'''
t = time.time()
self.param_dict['time_stamp'] = str(int(t))
'''请求随机字符串,用于保证签名不可预测'''
self.param_dict['nonce_str'] = ''.join(random.sample(string.ascii_letters + string.digits, 10))
@abstractmethod
def get_url(self):
pass
@abstractmethod
def get_content(self):
pass
@abstractmethod
def get_params(self):
pass
vision_imgfilter.py
'''
date:2019.7.7
copyright:buaalzm
'''
from qqaibase import QQAIBase
import hashlib
import requests
from bs4 import BeautifulSoup
import json
from urllib.parse import quote
import base64
import random
class VisionImgFilter(QQAIBase):
interface_url = "https://api.ai.qq.com/fcgi-bin/vision/vision_imgfilter" # API地址
def get_params(self, image, filter):
self.basic_param_init()
'''图片用base64编码'''
base64_data = base64.b64encode(image)
params = {'app_id': self.param_dict['app_id'],
'image': base64_data,
'time_stamp': self.param_dict['time_stamp'],
'nonce_str': self.param_dict['nonce_str'],
'filter': str(filter),
'session_id': str(random.randint(1, 9999999))
}
self.param_dict['image'] = base64_data
sign_before = ''
# 要对key排序再拼接
for key in sorted(params):
# 键值拼接过程value部分需要URL编码,URL编码算法用大写字母,例如%E8。quote默认大写。
sign_before += '{}={}&'.format(key, quote(params[key], safe=''))
# 将应用密钥以app_key为键名,拼接到字符串sign_before末尾
sign_before += 'app_key={}'.format(self.param_dict['app_key'])
'''计算MD5摘要,得到签名字符串'''
sign = hashlib.md5(sign_before.encode('utf-8')).hexdigest()
sign = sign.upper()
params['sign'] = sign
return params
def get_content(self, image, filter):
params = self.get_params(image, filter)
try:
r = requests.post(self.interface_url, data=params)
soup = BeautifulSoup(r.text, 'lxml')
allcontents = soup.select('body')[0].text.strip()
allcontents_json = json.loads(allcontents) # str转成dict
image_data = base64.b64decode(allcontents_json["data"]['image'])
with open("filtered_image.jpg", 'wb') as f:
f.write(image_data)
except:
print('exception occur')
if __name__ == '__main__':
img_filter = VisionImgFilter('2118177424', 'dTBQojzFDaabB0A2')
with open('D:/ico/mmexport1547432113759.jpg', 'rb')as f:
img_filter.get_content(f.read(), 1)
原始图像:
处理后:
ocr_generalocr.py
'''
date:2019.7.7
copyright:buaalzm
'''
from qqaibase import QQAIBase
import hashlib
import requests
from bs4 import BeautifulSoup
import json
from urllib.parse import quote
import base64
class GeneralOCR(QQAIBase):
interface_url = "https://api.ai.qq.com/fcgi-bin/ocr/ocr_generalocr" # API地址
def get_params(self, image):
self.basic_param_init()
'''图片用base64编码'''
base64_data = base64.b64encode(image)
params = {'app_id': self.param_dict['app_id'],
'image': base64_data,
'time_stamp': self.param_dict['time_stamp'],
'nonce_str': self.param_dict['nonce_str'],
}
self.param_dict['image'] = base64_data
sign_before = ''
# 要对key排序再拼接
for key in sorted(params):
# 键值拼接过程value部分需要URL编码,URL编码算法用大写字母,例如%E8。quote默认大写。
sign_before += '{}={}&'.format(key, quote(params[key], safe=''))
# 将应用密钥以app_key为键名,拼接到字符串sign_before末尾
sign_before += 'app_key={}'.format(self.param_dict['app_key'])
'''计算MD5摘要,得到签名字符串'''
sign = hashlib.md5(sign_before.encode('utf-8')).hexdigest()
sign = sign.upper()
params['sign'] = sign
return params
def get_content(self, image):
params = self.get_params(image)
try:
r = requests.post(self.interface_url, data=params)
soup = BeautifulSoup(r.text, 'lxml')
allcontents = soup.select('body')[0].text.strip()
allcontents_json = json.loads(allcontents) # str转成dict
return allcontents_json["data"]
except:
print('exception occur')
if __name__ == '__main__':
img_filter = GeneralOCR('2118233756', 'YSh9DEi7NNIH8Eiq')
with open('1.jpg', 'rb')as f:
image_data = f.read()
for item in img_filter.get_content(image_data)['item_list']:
print(item['itemstring'])
原始图像:
输出结果: