原本用小程序写了一个本地化的图片利用,不存在服务端的交互行为
后果提交审核的时候还是被打回了
好的!马上整改
利用的交互大略就是这样
咱们须要在抉择图片后
对图片做一次平安校验
启用云开发
当初咱们须要一个 后端接口 来实现图片的 平安校验 性能
这时候长期搭个 Node 服务如同不太事实
又不是什么正经我的项目
于是就想到了微信的云开发性能
用起来实在方便快捷
至于图片的校验办法
间接用云函数调用 security.imgSecCheck 接口就好了
流程
chooseImage() {
/// 用户抉择图片
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: async res => {if (res.errMsg === 'chooseImage:ok') {wx.showLoading({ title: '图片加载中'})
// 获取图片长期地址
const path = res.tempFilePaths[0]
// 将图片地址实例化为图片
const image = await loadImage(path, this.canvas)
// 压缩图片
const filePath = await compress.call(this, image, 'canvas_compress')
// 校验图片合法性
const imgValid = await checkImage(filePath)
wx.hideLoading()
if (!imgValid) return
// 图片平安检测通过,执行后续操作
...
}
})
}
图片压缩
因为 security.imgSecCheck 对图片有尺寸限度
所以在图片上传前要先对超出尺寸的图片进行压缩解决
根本逻辑就是
超出尺寸的图片等比例放大就好了
咱们先要有一个 canvas 元素
用来解决须要压缩的图片
<template>
<view class="menu-background">
<view class="item replace" bindtap="chooseImage">
<i class="iconfont icon-image"></i>
<text class="title"> 图片 </text>
<text class="sub-title"> 图片仅供本地应用 </text>
</view>
//
// canvas
//
<canvas
type="2d"
id="canvas_compress"
class="canvas-compress"
style="width: {{canvasCompress.width}}px; height: {{canvasCompress.height}}px"
/>
</view>
</template>
将 canvas 移到视线不可见到地位
.canvas-compress
position absolute
left 0
top 1000px
图片进行压缩解决
/**
* 压缩图片
* 将尺寸超过标准的图片最小限度压缩
* @param {Image} image 须要压缩的图片实例
* @param {String} canvasId 用来解决压缩图片的 canvas 对应的 canvasId
* @param {Object} config 压缩的图片标准 -> {maxWidth 最大宽度, maxHeight 最小宽度}
* @return {Promise} promise 返回 压缩后的 图片门路
*/
export default function (image, canvasId, config = { maxWidth: 750, maxHeight: 1334}) {
// 援用的组件传入的 this 作用域
const _this = this
return new Promise((resolve, reject) => {
// 获取图片原始宽高
let width = image.width
let height = image.height
// 宽度 > 最大限宽 -> 重置尺寸
if (width > config.maxWidth) {
const ratio = width / config.maxWidth
width = config.maxWidth
height = height / ratio
}
// 高度 > 最大限高度 -> 重置尺寸
if (height > config.maxHeight) {
const ratio = height / config.maxHeight
height = config.maxHeight
width = width / ratio
}
// 设置 canvas 的 css 宽高
_this.canvasCompress.width = width
_this.canvasCompress.height = height
const query = this.createSelectorQuery()
query
.select(`#${canvasId}`)
.fields({node: true, size: true})
.exec(async res => {
// 获取 canvas 实例
const canvas = res[0].node
// 获取 canvas 绘图上下文
const ctx = canvas.getContext('2d')
// 依据设施 dpr 解决尺寸
const dpr = wx.getSystemInfoSync().pixelRatio
canvas.width = width * dpr
canvas.height = height * dpr
ctx.scale(dpr, dpr)
// 将图片绘制到 canvas
ctx.drawImage(image, 0, 0, width, height)
// 将 canvas 图片上传到微信临时文件
wx.canvasToTempFilePath({
canvas,
x: 0,
y: 0,
destWidth: width,
destHeight: height,
complete (res) {if (res.errMsg === 'canvasToTempFilePath:ok') {
// 返回临时文件门路
resolve(res.tempFilePath)
}
},
fail(err) {reject(err)
}
})
})
})
}
图片平安校验
云函数 checkImage.js
const cloud = require('wx-server-sdk')
cloud.init({env: cloud.DYNAMIC_CURRENT_ENV})
/**
* 校验图片合法性
* @param {*} event.fileID 微信云存储的图片 ID
* @return {Number} 0: 校验失败;1: 校验通过
*/
exports.main = async (event, context) => {
const contentType = 'image/png'
const fileID = event.fileID
try {
// 依据 fileID 下载图片
const file = await cloud.downloadFile({fileID})
const value = file.fileContent
// 调用 imgSecCheck 借口,校验不通过接口会抛错
// 必要参数 media {contentType, value}
const result = await cloud.openapi.security.imgSecCheck({
media: {
contentType,
value
}
})
return 1
} catch (err) {return 0}
}
组件调用云函数封装
/**
* 校验图片是否存在敏感信息
* @param {String} filePath
* @return {Promise} promise 返回校验后果
*/
export default function (filePath) {return new Promise((resolve, reject) => {
// 先将图片上传到云开发存储
wx.cloud.uploadFile({cloudPath: `${new Date().getTime()}.png`,
filePath,
success (res) {
// 调用云函数 -checkImage
wx.cloud.callFunction({
name: 'checkImage',
data: {fileID: res.fileID},
success (res) {
// res.result -> 0: 存在敏感信息;1: 校验通过
resolve(res.result)
if (!res.result) {
wx.showToast({
title: '图片可能含有敏感信息, 请从新抉择',
icon: 'none'
})
}
},
fail (err) {reject(err)
}
})
},
fail (err) {reject(err)
}
})
})
}
本文 demo
本文代码仓库
https://github.com/luosijie/f…