Loading... 事情经过是这样的,这段时间在开发一个二维码美化小程序,昨天中午修复了一个bug后提交给微信审核,晚上收到审核结果后惊呆了,居然没有通过,毕竟自己只是增加了一个setTimeout方法,看到驳回原因后觉得还是挺有意思的: ![小程序驳回原因截图][1] 看完之后理解了,小程序审核人员在小程序里面上传了张18禁图片,然后告诉我,你这样不行啊,怎么能不进行图片鉴黄呢,万一带坏了小盆友该怎么办。那为什么之前的审核你都给通过了?第一次做图片工具类的小程序,还真是没想到审核会有这波操作。行吧行吧,看在你是腾讯的份上(其实是鉴黄接口不收费,虽然云函数超过免费额度后会收费,但是价格还能接受),你要加就给你加呗。 ![马化腾][2] # 1、准备工作 > security.imgSecCheck文档:[https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/sec-check/security.imgSecCheck.html][3] 看了一下security.imgSecCheck文档,发现调用图片内容安全识别接口有两种方式,第一种是通过HTTPS 调用,第二种是云调用。虽然第一种可以通过直接请求接口调用,但是需要使用access_token,个人感觉还是比较麻烦的,所以选择了云调用。 使用云调用第一步就是需要开通云开发功能,具体开通流程这里就不进行描述了,选择免费的就行(顺带吐槽一下云开发开始割韭菜啦,具体可以参考别人写的文章:[小程序云开发新版套餐解读][4])。 # 2. 配置云开发 由于这个小程序之前在创建的时候没有勾选云开发,所以需要自己配置一下。 首先是在根目录下的`project.config.json`中设置云函数目录: ```json "cloudfunctionRoot": "cloud/" ``` 然后在根目录下创建`cloud`文件夹,创建完成后,这个文件夹右下角会带有一个云图标:  # 3、创建云函数 在微信开发者工具中右击刚才创建的文件夹,点击新建Node.js云函数,创建一个新的云函数,我这边创建的云函数名称是imgSecCheck,然后在这个云函数目录下的`config.json`中配置api权限: ```json { "permissions": { "openapi": [ "security.imgSecCheck" ] } } ``` # 4、编写云函数 由于这个小程序中的图片是在本地进行编辑和保存,不需要上传到服务器,所以直接将图片直接传给接口就行了,在imgSecCheck目录下的`index.js`文件中编写云函数: ```js // 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init({ env: 'your env' }) // 云函数入口函数 exports.main = async (event, context) => { try { const res = await cloud.openapi.security.imgSecCheck({ media: { contentType: 'image/png', value: Buffer.from(event.value) } }) return res } catch (error) { return error } } ``` 其中`env`的值可以在开发者工具-云开发-设置-环境ID中拿到,然后将这个云函数进行上传:  # 5、小程序端调用 上传完成后即可在小程序端调用,下方为从相册选取图片后进行图片内容安全识别的一个demo: ```js wx.chooseImage({ count: 1, // 默认9 sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ['album'], // 可以指定来源是相册还是相机,默认二者都有 success(res) { const src = res.tempFilePaths[0] wx.getFileSystemManager().readFile({ filePath: src, success: buffer => { wx.showLoading({ title: '图片合规性检查中', mask: true }) wx.cloud.callFunction({ name: 'imgSecCheck', // 之前创建的云函数名称 data: { value: buffer.data // 传入的值 } }).then(res => { wx.hideLoading() if (res.result.errCode === 87014) { wx.showToast({ title: '图片违规,请重新上传其他图片', icon: 'none' }) } else if (res.result.errCode === 0) { // 图片内容正常 TODO } else { wx.showToast({ title: '检测出错,错误码为:' + res.result.errCode, icon: 'none' }) } }).catch(error => { wx.hideLoading() console.log(error) wx.showToast({ title: `检测出错,请重试`, icon: 'none' }) }) } }) } }) ``` # 6、遇到问题 编写完小程序端代码后,使用起来很顺利,看官方描述图片大小限制为1m,然后用PS生成了一张5M左右的图片上传识别,本来准备看一下超过大小限制后的报错信息,没想到云函数正确返回了数据,完美,提交代码。 提交后使用真机测试体验版,发现怎么上传都没有用,然后使用真机调试看了一下报错信息:  看了一会[云开发错误码](https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference/errcode.html)后没有得到有效的信息,以为是图片大小超过了1M,便多尝试了几张图片,发现结果都是一样的,直到上传了一张几乎为纯白色的图片接口才返回数据。计算了一下这些图片的大小,发现只有几十k大小的图片才有几率能被接口识别,超过100k大小的图片都是报错。文档中说好的图片大小限制为1m呢? # 7、更换实现方法 在经历了一系列百度搜索后,自己依旧没有找到问题的解决办法(有知道问题所在原因的小伙伴还希望在评论区指导一下),便决定更换一种实现方法,先将图片上传到云端,然后然云函数在云端下载上传后的图片进行识别。 # 8、开通存储功能 在微信开发者工具-云开发-存储中开通云存储功能,然后新建一个temp文件夹:  # 9、修改小程序端代码 先将图片上传,获取到文件id后传给云函数: ```js wx.chooseImage({ count: 1, // 默认9 sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ['album'], // 可以指定来源是相册还是相机,默认二者都有 success(res) { const src = res.tempFilePaths[0] wx.showLoading({ title: '上传中', mask: true }) wx.cloud.uploadFile({ // 指定上传到的云路径 cloudPath: 'temp/' + new Date().getTime() + "-" + Math.floor(Math.random() * 1000), // 指定要上传的文件的小程序临时文件路径 filePath: src, // 成功回调 success: res => { wx.hideLoading() const fileID = res.fileID wx.showLoading({ title: '图片合规性检查中', mask: true }) wx.cloud.callFunction({ name: 'imgSecCheck', // 之前创建的云函数名称 data: { value: fileID // 传入的值 } }).then(res => { wx.hideLoading() if (res.result.errCode === 87014) { wx.showToast({ title: '图片违规,请重新上传其他图片', icon: 'none' }) } else if (res.result.errCode === 0) { // 图片内容正常 TODO } else { wx.showToast({ title: '检测出错,错误码为:' + res.result.errCode, icon: 'none' }) } }).catch(error => { wx.hideLoading() console.log(error) wx.showToast({ title: `检测出错,请重试`, icon: 'none' }) }) }, fail: error => { wx.hideLoading() console.log(error) wx.showToast({ title: '图片上传出错,请重试', icon: 'none' }) } }) } }) ``` # 10、修改云函数 云函数首先拿到文件id下载文件,然后再进行图片内容识别。由于我这边图片用完后不需要保存,所以在识别完成后将图片删除,以免占用过多的免费存储空间: ```js // 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init({ env: 'your env' }) // 云函数入口函数 exports.main = async (event, context) => { const file = await cloud.downloadFile({ fileID: event.value }) try { const res = await cloud.openapi.security.imgSecCheck({ media: { contentType: 'image/png', value: file.fileContent } }) cloud.deleteFile({ fileList: [event.value] }) return res } catch (error) { return error } } ``` # 11、体验 最终效果可以扫描下方小程序码,然后在自定义二维码-自定义背景图-生成图片中体验。  [1]: https://imgs.bwmelon.com/20210130223314139.png [2]: https://imgs.bwmelon.com/202101302257149.png [3]: https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/sec-check/security.imgSecCheck.html [4]: https://developers.weixin.qq.com/community/develop/article/doc/00062688754b70b3729b11bae51813 最后修改:2021 年 01 月 31 日 02 : 29 PM © 允许规范转载 赞赏 如果觉得我的文章对你有用,请随意赞赏 ×Close 赞赏作者 扫一扫支付 支付宝支付 微信支付