風月無边 發表於 2019-12-5 19:36:00

014 Python公众号开发(二)—颜值检测

<div id="cnblogs_post_body" class="blogpost-body cnblogs-markdown">
<p>上篇文章,我们把自己的程序接入了微信公众号,并且能把用户发送的文本及图片文件原样返回。今天我们把用户的图片通过腾讯的AI平台分析后再返回给用户。</p>
<p><strong>为了防止我的文章被到处转载,贴一下我的公众号【智能制造社区】,欢迎大家关注。</strong></p>
<p><strong>github仓库地址https://github.com/injetlee/Python/tree/master/wechat</strong></p>
<h2 id="效果图">效果图</h2>
<p><img src="https://img2018.cnblogs.com/blog/1182889/201906/1182889-20190611093032360-1541913277.png" alt="效果1.png"></p>
<p><img src="https://img2018.cnblogs.com/blog/1182889/201906/1182889-20190611093050972-1310752871.jpg" alt="效果2.jpg"></p>
<p><img src="https://img2018.cnblogs.com/blog/1182889/201906/1182889-20190611093111381-1886559310.jpg" alt="效果3.jpg"></p>
<h2 id="一.-接入腾讯ai平台">一. 接入腾讯AI平台</h2>
<p>我们先看一下官方人脸检测与分析接口的描述:</p>
<p>检测给定图片(Image)中的所有人脸(Face)的位置和相应的面部属性。位置包括(x, y, w, h),面部属性包括性别(gender), 年龄(age), 表情(expression), 魅力(beauty), 眼镜(glass)和姿态(pitch,roll,yaw)。</p>
<p>请求参数包括下面几个:</p>
<ul>
<li>app_id 应用标识,我们在AI平台注册后就可以得到app_id</li>
<li>time_stamp 时间戳</li>
<li>nonce_str 随机字符串</li>
<li>sign 签名信息,需要我们自己去计算</li>
<li>image 需要检测的图片(上限1M)</li>
<li>mode 检测模式</li>
</ul>
<h3 id="接口鉴权构造请求参数">1.接口鉴权,构造请求参数</h3>
<p>官方给了我们接口鉴权的计算方法。</p>
<ol>
<li>将&lt;key, value&gt;请求参数对按key进行字典升序排序,得到有序的参数对列表N</li>
<li>将列表N中的参数对按URL键值对的格式拼接成字符串,得到字符串T(如:key1=value1&amp;key2=value2),URL键值拼接过程value部分需要URL编码,URL编码算法用大写字母,例如%E8,而不是小写%e8</li>
<li>将应用密钥以app_key为键名,组成URL键值拼接到字符串T末尾,得到字符串S(如:key1=value1&amp;key2=value2&amp;app_key=密钥)</li>
<li>对字符串S进行MD5运算,将得到的MD5值所有字符转换成大写,得到接口请求签名</li>
</ol>
<h3 id="请求接口地址">2.请求接口地址</h3>
<p>请求接口信息,我们用 requests 发送请求,会得到返回的 json 格式的图像信息<code>pip install requests</code>安装requests。</p>
<h3 id="处理返回的信息">3.处理返回的信息</h3>
<p>处理返回的信息,把信息展示在图片上,再把处理后的图片保存。这里我们用到 opencv ,和 pillow 两个库<code>pip install pillow</code>和<code>pip install opencv-python</code>来安装。</p>
<p>开始编写代码,我们新建一个face_id.py 文件来对接AI平台,并且返回检测后的图像数据。</p>
<pre class="python"><code class="hljs"><span class="hljs-keyword">import</span> time
<span class="hljs-keyword">import</span> random
<span class="hljs-keyword">import</span> base64
<span class="hljs-keyword">import</span> hashlib
<span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">from</span> urllib.parse <span class="hljs-keyword">import</span> urlencode
<span class="hljs-keyword">import</span> cv2
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
<span class="hljs-keyword">from</span> PIL <span class="hljs-keyword">import</span> Image, ImageDraw, ImageFont
<span class="hljs-keyword">import</span> os


<span class="hljs-comment"># 一.计算接口鉴权,构造请求参数</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">random_str</span><span class="hljs-params">()</span>:</span>
    <span class="hljs-string">'''得到随机字符串nonce_str'''</span>
    str = <span class="hljs-string">'abcdefghijklmnopqrstuvwxyz'</span>
    r = <span class="hljs-string">''</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">15</span>):
      index = random.randint(<span class="hljs-number">0</span>,<span class="hljs-number">25</span>)
      r += str
    <span class="hljs-keyword">return</span> r


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">image</span><span class="hljs-params">(name)</span>:</span>
    <span class="hljs-keyword">with</span> open(name, <span class="hljs-string">'rb'</span>) <span class="hljs-keyword">as</span> f:
      content = f.read()
    <span class="hljs-keyword">return</span> base64.b64encode(content)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_params</span><span class="hljs-params">(img)</span>:</span>
    <span class="hljs-string">'''组织接口请求的参数形式,并且计算sign接口鉴权信息,
    最终返回接口请求所需要的参数字典'''</span>
    params = {
      <span class="hljs-string">'app_id'</span>: <span class="hljs-string">'1106860829'</span>,
      <span class="hljs-string">'time_stamp'</span>: str(int(time.time())),
      <span class="hljs-string">'nonce_str'</span>: random_str(),
      <span class="hljs-string">'image'</span>: img,
      <span class="hljs-string">'mode'</span>: <span class="hljs-string">'0'</span>

    }

    sort_dict = sorted(params.items(), key=<span class="hljs-keyword">lambda</span> item: item[<span class="hljs-number">0</span>], reverse=<span class="hljs-keyword">False</span>)<span class="hljs-comment"># 排序</span>
    sort_dict.append((<span class="hljs-string">'app_key'</span>, <span class="hljs-string">'P8Gt8nxi6k8vLKbS'</span>))<span class="hljs-comment"># 添加app_key</span>
    rawtext = urlencode(sort_dict).encode()<span class="hljs-comment"># URL编码</span>
    sha = hashlib.md5()
    sha.update(rawtext)
    md5text = sha.hexdigest().upper()<span class="hljs-comment"># 计算出sign,接口鉴权</span>
    params[<span class="hljs-string">'sign'</span>] = md5text<span class="hljs-comment"># 添加到请求参数列表中</span>
    <span class="hljs-keyword">return</span> params

<span class="hljs-comment"># 二.请求接口URL</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">access_api</span><span class="hljs-params">(img)</span>:</span>
    print(img)
    frame = cv2.imread(img)
    nparry_encode = cv2.imencode(<span class="hljs-string">'.jpg'</span>, frame)[<span class="hljs-number">1</span>]
    data_encode = np.array(nparry_encode)
    img_encode = base64.b64encode(data_encode)<span class="hljs-comment"># 图片转为base64编码格式</span>
    url = <span class="hljs-string">'https://api.ai.qq.com/fcgi-bin/face/face_detectface'</span>
    res = requests.post(url, get_params(img_encode)).json()<span class="hljs-comment"># 请求URL,得到json信息</span>
    <span class="hljs-comment"># 把信息显示到图片上</span>
    <span class="hljs-keyword">if</span> res[<span class="hljs-string">'ret'</span>] == <span class="hljs-number">0</span>:<span class="hljs-comment"># 0代表请求成功</span>
      pil_img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))<span class="hljs-comment"># 把opencv格式转换为PIL格式,方便写汉字</span>
      draw = ImageDraw.Draw(pil_img)
      <span class="hljs-keyword">for</span> obj <span class="hljs-keyword">in</span> res[<span class="hljs-string">'data'</span>][<span class="hljs-string">'face_list'</span>]:
            img_width = res[<span class="hljs-string">'data'</span>][<span class="hljs-string">'image_width'</span>]<span class="hljs-comment"># 图像宽度</span>
            img_height = res[<span class="hljs-string">'data'</span>][<span class="hljs-string">'image_height'</span>]<span class="hljs-comment"># 图像高度</span>
            <span class="hljs-comment"># print(obj)</span>
            x = obj[<span class="hljs-string">'x'</span>]<span class="hljs-comment"># 人脸框左上角x坐标</span>
            y = obj[<span class="hljs-string">'y'</span>]<span class="hljs-comment"># 人脸框左上角y坐标</span>
            w = obj[<span class="hljs-string">'width'</span>]<span class="hljs-comment"># 人脸框宽度</span>
            h = obj[<span class="hljs-string">'height'</span>]<span class="hljs-comment"># 人脸框高度</span>
            <span class="hljs-comment"># 根据返回的值,自定义一下显示的文字内容</span>
            <span class="hljs-keyword">if</span> obj[<span class="hljs-string">'glass'</span>] == <span class="hljs-number">1</span>:<span class="hljs-comment"># 眼镜</span>
                glass = <span class="hljs-string">'有'</span>
            <span class="hljs-keyword">else</span>:
                glass = <span class="hljs-string">'无'</span>
            <span class="hljs-keyword">if</span> obj[<span class="hljs-string">'gender'</span>] &gt;= <span class="hljs-number">70</span>:<span class="hljs-comment"># 性别值从0-100表示从女性到男性</span>
                gender = <span class="hljs-string">'男'</span>
            <span class="hljs-keyword">elif</span> <span class="hljs-number">50</span> &lt;= obj[<span class="hljs-string">'gender'</span>] &lt; <span class="hljs-number">70</span>:
                gender = <span class="hljs-string">"娘"</span>
            <span class="hljs-keyword">elif</span> obj[<span class="hljs-string">'gender'</span>] &lt; <span class="hljs-number">30</span>:
                gender = <span class="hljs-string">'女'</span>
            <span class="hljs-keyword">else</span>:
                gender = <span class="hljs-string">'女汉子'</span>
            <span class="hljs-keyword">if</span> <span class="hljs-number">90</span> &lt; obj[<span class="hljs-string">'expression'</span>] &lt;= <span class="hljs-number">100</span>:<span class="hljs-comment"># 表情从0-100,表示笑的程度</span>
                expression = <span class="hljs-string">'一笑倾城'</span>
            <span class="hljs-keyword">elif</span> <span class="hljs-number">80</span> &lt; obj[<span class="hljs-string">'expression'</span>] &lt;= <span class="hljs-number">90</span>:
                expression = <span class="hljs-string">'心花怒放'</span>
            <span class="hljs-keyword">elif</span> <span class="hljs-number">70</span> &lt; obj[<span class="hljs-string">'expression'</span>] &lt;= <span class="hljs-number">80</span>:
                expression = <span class="hljs-string">'兴高采烈'</span>
            <span class="hljs-keyword">elif</span> <span class="hljs-number">60</span> &lt; obj[<span class="hljs-string">'expression'</span>] &lt;= <span class="hljs-number">70</span>:
                expression = <span class="hljs-string">'眉开眼笑'</span>
            <span class="hljs-keyword">elif</span> <span class="hljs-number">50</span> &lt; obj[<span class="hljs-string">'expression'</span>] &lt;= <span class="hljs-number">60</span>:
                expression = <span class="hljs-string">'喜上眉梢'</span>
            <span class="hljs-keyword">elif</span> <span class="hljs-number">40</span> &lt; obj[<span class="hljs-string">'expression'</span>] &lt;= <span class="hljs-number">50</span>:
                expression = <span class="hljs-string">'喜气洋洋'</span>
            <span class="hljs-keyword">elif</span> <span class="hljs-number">30</span> &lt; obj[<span class="hljs-string">'expression'</span>] &lt;= <span class="hljs-number">40</span>:
                expression = <span class="hljs-string">'笑逐颜开'</span>
            <span class="hljs-keyword">elif</span> <span class="hljs-number">20</span> &lt; obj[<span class="hljs-string">'expression'</span>] &lt;= <span class="hljs-number">30</span>:
                expression = <span class="hljs-string">'似笑非笑'</span>
            <span class="hljs-keyword">elif</span> <span class="hljs-number">10</span> &lt; obj[<span class="hljs-string">'expression'</span>] &lt;= <span class="hljs-number">20</span>:
                expression = <span class="hljs-string">'半嗔半喜'</span>
            <span class="hljs-keyword">elif</span> <span class="hljs-number">0</span> &lt;= obj[<span class="hljs-string">'expression'</span>] &lt;= <span class="hljs-number">10</span>:
                expression = <span class="hljs-string">'黯然伤神'</span>
            delt = h // <span class="hljs-number">5</span><span class="hljs-comment"># 确定文字垂直距离</span>
            <span class="hljs-comment"># 写入图片</span>
            <span class="hljs-keyword">if</span> len(res[<span class="hljs-string">'data'</span>][<span class="hljs-string">'face_list'</span>]) &gt; <span class="hljs-number">1</span>:<span class="hljs-comment"># 检测到多个人脸,就把信息写入人脸框内</span>
                font = ImageFont.truetype(<span class="hljs-string">'yahei.ttf'</span>, w // <span class="hljs-number">8</span>, encoding=<span class="hljs-string">'utf-8'</span>)<span class="hljs-comment"># 提前把字体文件下载好</span>
                draw.text((x + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span>), <span class="hljs-string">'性别 :'</span> + gender, (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
                draw.text((x + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span> + delt * <span class="hljs-number">1</span>), <span class="hljs-string">'年龄 :'</span> + str(obj[<span class="hljs-string">'age'</span>]), (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
                draw.text((x + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span> + delt * <span class="hljs-number">2</span>), <span class="hljs-string">'表情 :'</span> + expression, (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
                draw.text((x + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span> + delt * <span class="hljs-number">3</span>), <span class="hljs-string">'魅力 :'</span> + str(obj[<span class="hljs-string">'beauty'</span>]), (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
                draw.text((x + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span> + delt * <span class="hljs-number">4</span>), <span class="hljs-string">'眼镜 :'</span> + glass, (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
            <span class="hljs-keyword">elif</span> img_width - x - w &lt; <span class="hljs-number">170</span>:<span class="hljs-comment"># 避免图片太窄,导致文字显示不完全</span>
                font = ImageFont.truetype(<span class="hljs-string">'yahei.ttf'</span>, w // <span class="hljs-number">8</span>, encoding=<span class="hljs-string">'utf-8'</span>)
                draw.text((x + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span>), <span class="hljs-string">'性别 :'</span> + gender, (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
                draw.text((x + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span> + delt * <span class="hljs-number">1</span>), <span class="hljs-string">'年龄 :'</span> + str(obj[<span class="hljs-string">'age'</span>]), (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
                draw.text((x + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span> + delt * <span class="hljs-number">2</span>), <span class="hljs-string">'表情 :'</span> + expression, (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
                draw.text((x + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span> + delt * <span class="hljs-number">3</span>), <span class="hljs-string">'魅力 :'</span> + str(obj[<span class="hljs-string">'beauty'</span>]), (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
                draw.text((x + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span> + delt * <span class="hljs-number">4</span>), <span class="hljs-string">'眼镜 :'</span> + glass, (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
            <span class="hljs-keyword">else</span>:
                font = ImageFont.truetype(<span class="hljs-string">'yahei.ttf'</span>, <span class="hljs-number">20</span>, encoding=<span class="hljs-string">'utf-8'</span>)
                draw.text((x + w + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span>), <span class="hljs-string">'性别 :'</span> + gender, (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
                draw.text((x + w + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span> + delt * <span class="hljs-number">1</span>), <span class="hljs-string">'年龄 :'</span> + str(obj[<span class="hljs-string">'age'</span>]), (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
                draw.text((x + w + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span> + delt * <span class="hljs-number">2</span>), <span class="hljs-string">'表情 :'</span> + expression, (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
                draw.text((x + w + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span> + delt * <span class="hljs-number">3</span>), <span class="hljs-string">'魅力 :'</span> + str(obj[<span class="hljs-string">'beauty'</span>]), (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)
                draw.text((x + w + <span class="hljs-number">10</span>, y + <span class="hljs-number">10</span> + delt * <span class="hljs-number">4</span>), <span class="hljs-string">'眼镜 :'</span> + glass, (<span class="hljs-number">76</span>, <span class="hljs-number">176</span>, <span class="hljs-number">80</span>), font=font)

            draw.rectangle((x, y, x + w, y + h), outline=<span class="hljs-string">"#4CB050"</span>)<span class="hljs-comment"># 画出人脸方框</span>
            cv2img = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)<span class="hljs-comment"># 把 pil 格式转换为 cv</span>
            cv2.imwrite(<span class="hljs-string">'faces/{}'</span>.format(os.path.basename(img)), cv2img)<span class="hljs-comment"># 保存图片到 face 文件夹下</span>
            <span class="hljs-keyword">return</span> <span class="hljs-string">'检测成功'</span>
    <span class="hljs-keyword">else</span>:
      <span class="hljs-keyword">return</span> <span class="hljs-string">'检测失败'</span></code></pre>
<p>到这里我们的人脸检测接口接入及图片处理就完成了。之后在收到用户发送的图片信息后,调用这个函数,把处理后的图片返回给用户就可以。</p>
<h2 id="返回图片给用户">返回图片给用户</h2>
<p>当收到用户图片时,需要以下几个步骤:</p>
<h3 id="保存图片">保存图片</h3>
<p>当接收到用户图片后,我们要先把图片保存起来,之后才能去调用人脸分析接口,把图片信息传递过去,我们需要编写一个 img_download 函数来下载图片。详见下方代码</p>
<h3 id="调用人脸分析接口">调用人脸分析接口</h3>
<p>图片下载后,调用 face_id.py 文件里的接口函数,得到处理后的图片。</p>
<h3 id="上传图片">上传图片</h3>
<p>检测结果是一张新的图片,要把图片发送给用户我们需要一个 Media_ID,要获取Media_ID必须先把图片上传为临时素材,所以这里我们需要一个img_upload函数来上传图片,并且在上传时需要用到一个access_token,我们通过一个函数来获取.** 获取access_token必须要把我们自己的IP地址加入白名单,否则是获取不到的。请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,可以在http://ip.qq.com/查看本机的IP地址**</p>
<p>开始编写代码,我们新建一个 utils.py 来下载、上传图片</p>
<pre class="python"><code class="hljs"><span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">import</span> json
<span class="hljs-keyword">import</span> threading
<span class="hljs-keyword">import</span> time
<span class="hljs-keyword">import</span> os

token = <span class="hljs-string">''</span>
app_id = <span class="hljs-string">'wxfc6adcdd7593a712'</span>
secret = <span class="hljs-string">'429d85da0244792be19e0deb29615128'</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">img_download</span><span class="hljs-params">(url, name)</span>:</span>
    r = requests.get(url)
    <span class="hljs-keyword">with</span> open(<span class="hljs-string">'images/{}-{}.jpg'</span>.format(name, time.strftime(<span class="hljs-string">"%Y_%m_%d%H_%M_%S"</span>, time.localtime())), <span class="hljs-string">'wb'</span>) <span class="hljs-keyword">as</span> fd:
      fd.write(r.content)
    <span class="hljs-keyword">if</span> os.path.getsize(fd.name) &gt;= <span class="hljs-number">1048576</span>:
      <span class="hljs-keyword">return</span> <span class="hljs-string">'large'</span>
    <span class="hljs-comment"># print('namename', os.path.basename(fd.name))</span>
    <span class="hljs-keyword">return</span> os.path.basename(fd.name)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_access_token</span><span class="hljs-params">(appid, secret)</span>:</span>
    <span class="hljs-string">'''获取access_token,100分钟刷新一次'''</span>

    url = <span class="hljs-string">'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&amp;appid={}&amp;secret={}'</span>.format(appid, secret)
    r = requests.get(url)
    parse_json = json.loads(r.text)
    <span class="hljs-keyword">global</span> token
    token = parse_json[<span class="hljs-string">'access_token'</span>]
    <span class="hljs-keyword">global</span> timer
    timer = threading.Timer(<span class="hljs-number">6000</span>, get_access_token)
    timer.start()


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">img_upload</span><span class="hljs-params">(mediaType, name)</span>:</span>
    <span class="hljs-keyword">global</span> token
    url = <span class="hljs-string">"https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&amp;type=%s"</span> % (token, mediaType)
    files = {<span class="hljs-string">'media'</span>: open(<span class="hljs-string">'{}'</span>.format(name), <span class="hljs-string">'rb'</span>)}
    r = requests.post(url, files=files)
    parse_json = json.loads(r.text)
    <span class="hljs-keyword">return</span> parse_json[<span class="hljs-string">'media_id'</span>]

get_access_token(app_id, secret)</code></pre>
<h2 id="返回给用户">返回给用户</h2>
<p>我们简单修改下收到图片后的逻辑,收到图片后经过人脸检测,上传获得Media_ID,我们要做的就是把图片返回给用户即可。直接看connect.py的代码</p>
<pre class="python"><code class="hljs"><span class="hljs-keyword">import</span> falcon
<span class="hljs-keyword">from</span> falcon <span class="hljs-keyword">import</span> uri
<span class="hljs-keyword">from</span> wechatpy.utils <span class="hljs-keyword">import</span> check_signature
<span class="hljs-keyword">from</span> wechatpy.exceptions <span class="hljs-keyword">import</span> InvalidSignatureException
<span class="hljs-keyword">from</span> wechatpy <span class="hljs-keyword">import</span> parse_message
<span class="hljs-keyword">from</span> wechatpy.replies <span class="hljs-keyword">import</span> TextReply, ImageReply

<span class="hljs-keyword">from</span> utils <span class="hljs-keyword">import</span> img_download, img_upload
<span class="hljs-keyword">from</span> face_id <span class="hljs-keyword">import</span> access_api


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Connect</span><span class="hljs-params">(object)</span>:</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">on_get</span><span class="hljs-params">(self, req, resp)</span>:</span>
      query_string = req.query_string
      query_list = query_string.split(<span class="hljs-string">'&amp;'</span>)
      b = {}
      <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> query_list:
            b] = i.split(<span class="hljs-string">'='</span>)[<span class="hljs-number">1</span>]

      <span class="hljs-keyword">try</span>:
            check_signature(token=<span class="hljs-string">'lengxiao'</span>, signature=b[<span class="hljs-string">'signature'</span>], timestamp=b[<span class="hljs-string">'timestamp'</span>], nonce=b[<span class="hljs-string">'nonce'</span>])
            resp.body = (b[<span class="hljs-string">'echostr'</span>])
      <span class="hljs-keyword">except</span> InvalidSignatureException:
            <span class="hljs-keyword">pass</span>
      resp.status = falcon.HTTP_200

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">on_post</span><span class="hljs-params">(self, req, resp)</span>:</span>
      xml = req.stream.read()
      msg = parse_message(xml)
      <span class="hljs-keyword">if</span> msg.type == <span class="hljs-string">'text'</span>:
            print(<span class="hljs-string">'hello'</span>)
            reply = TextReply(content=msg.content, message=msg)
            xml = reply.render()
            resp.body = (xml)
            resp.status = falcon.HTTP_200
      <span class="hljs-keyword">elif</span> msg.type == <span class="hljs-string">'image'</span>:
            name = img_download(msg.image, msg.source)<span class="hljs-comment"># 下载图片</span>
            print(name)
            r = access_api(<span class="hljs-string">'images/'</span> + name)
            <span class="hljs-keyword">if</span> r == <span class="hljs-string">'检测成功'</span>:
                media_id = img_upload(<span class="hljs-string">'image'</span>, <span class="hljs-string">'faces/'</span> + name)<span class="hljs-comment"># 上传图片,得到 media_id</span>
                reply = ImageReply(media_id=media_id, message=msg)
            <span class="hljs-keyword">else</span>:
                reply = TextReply(content=<span class="hljs-string">'人脸检测失败,请上传1M以下人脸清晰的照片'</span>, message=msg)
            xml = reply.render()
            resp.body = (xml)
            resp.status = falcon.HTTP_200

app = falcon.API()
connect = Connect()
app.add_route(<span class="hljs-string">'/connect'</span>, connect)
</code></pre>
<p>至此我们的工作就做完了,我们的公众号可以进行颜值检测了。本来我打算用在自己公众号上的,但是还存在下面几个问题,所以没有使用。</p>
<ol>
<li>
<p>微信的机制,我们的程序必须在5s内给出响应。不然就会报'公众号提供的服务出现故障'。然而处理图片有时会比较慢,经常会超过5s。所以正确的处理方式应该是拿到用户的请求后立即返回一个空字符串表示我们收到了,之后单独创建一个线程去处理图片,当图片处理完后通过客服接口发送给用户。可惜的是未认证的公众号没有客服接口,所以没办法,超过5s就会报错。</p>
</li>
<li>
<p>无法自定义菜单,一旦启用了自定义开发,菜单也需要自定义配置,但是未认证的公众号没有权限通过程序来配置菜单,只能在微信后台配置。</p>
</li>
</ol>
<p>所以,我并没有在我的公众号上启用这个程序,但是如果有认证的公众号,可以尝试开发各种好玩的功能。</p>
</div><br><br>
来源:https://www.cnblogs.com/abdm-989/p/11991394.html
頁: [1]
查看完整版本: 014 Python公众号开发(二)—颜值检测