百度AI接口的AccessToken有一个月的有效期,为了演示效果就优先获取固定写在小程序中。 大家为了后续方便。最好自动定时获取。不想借助后端语言。那就可以考虑一下微信小程序的云开发。本文就使用获取固定写在小程序相关代码中方式喽 获取AccessToken接口地址 https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjhhu#%E8%8E%B7%E5%8F%96access-token
替换URL中的APIKEY、SECRETKEY为自己应用的真实值
https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=APIKEY&client_secret=SECRETKEY
使用编程语言、浏览器、POSTMAN都可以快速获取AccessToken哦 ,将以上替换后的URL直接在浏览器地址栏输入回车即可拿到AccessToken哦 返回如下JSON字符串 我们只要access_token的值哦
{
"refresh_token": "25.123456789730ffc9dbd89ec5a4952a56.315360000.1893997048.282335-12345678",
"expires_in": 2592000,
"session_key": "9mzdAqFbzEpjT/tsQOgi4BoWEgc5jOYlr5Lau0lCBk9BNX3ed/UEEWCOunVvz8+AMf8a/IvhjWUbWpcmtTRPvYRALNSCkA==",
"access_token": "24.12345678982e904de41e99fa7c213a1f.2592000.1581229048.282335-12345678",
"scope": "brain_selfie_anime brain_image_definition_enhance public brain_all_scope brain_colourize brain_stretch_restore brain_dehaze brain_contrast_enhance brain_image_quality_enhance brain_style_trans brain_inpainting wise_adapt lebo_resource_base lightservice_public hetu_basic lightcms_map_poi kaidian_kaidian ApsMisTest_Test权限 vis-classify_flower lpq_开放 cop_helloScope ApsMis_fangdi_permission smartapp_snsapi_base iop_autocar oauth_tp_app smartapp_smart_game_openapi oauth_sessionkey smartapp_swanid_verify smartapp_opensource_openapi smartapp_opensource_recapi fake_face_detect_开放Scope vis-ocr_虚拟人物助理 idl-video_虚拟人物助理",
"session_secret": "efeb1f7cfd0330f04b81925097b61ec8"
}
微信小程序utils文件夹中增加baiduai.js 并写入如下内容
/**
* 调用百度AI示例代码
*/
let accessToken = '24.12345678982e904de41e99fa7c213a1f.2592000.1581229048.282335-12345678'//自己的accessToken 根据实际情况可以进行封装 自动获取token
let faceAnimeUrl = 'https://aip.baidubce.com/rest/2.0/image-process/v1/selfie_anime';//人像动漫化
/**
* 人像动漫化
* @param imgData 图片的base64
*/
let faceAnimeRequest = (imgData,callback)=>{
//拼接接口body参数
let params = {
image: imgData,
}
//发送接口请求
wx.request({
//拼接请求的接口地址 大家要注意access_token为URL参数 非body参数
url: faceAnimeUrl + '?access_token=' + accessToken,
data: params,
header: {
//这里根据接口文档要求来。如果要求为json则修改为 application/json
'content-type': 'application/x-www-form-urlencoded'
},
method: 'POST',
success: function (res) {
callback.success(res.data)
},
fail: function (res) {
if (callback.fail)
callback.fail()
}
})
}
把方法暴露出去
//暴露出去的接口
module.exports = {
faceAnimeRequest: faceAnimeRequest
}
/**
* 调用百度AI示例代码
*/
let accessToken = ''//自己的accessToken 根据实际情况可以进行封装 自动获取token
let faceAnimeUrl = 'https://aip.baidubce.com/rest/2.0/image-process/v1/selfie_anime';//人像动漫化
/**
* 人像动漫化
* @param imgData 图片的base64
*/
let faceAnimeRequest = (imgData,callback)=>{
//拼接接口body参数
let params = {
image: imgData,
}
//发送接口请求
wx.request({
//拼接请求的接口地址 大家要注意access_token为URL参数 非body参数
url: faceAnimeUrl + '?access_token=' + accessToken,
data: params,
header: {
//这里根据接口文档要求来。如果要求为json则修改为 application/json
'content-type': 'application/x-www-form-urlencoded'
},
method: 'POST',
success: function (res) {
callback.success(res.data)
},
fail: function (res) {
if (callback.fail)
callback.fail()
}
})
}
//暴露出去的接口
module.exports = {
faceAnimeRequest: faceAnimeRequest
}
要求是图片的base64.对于用户来说不可能让用户去提交图片的base64数据。那就需要咱们写一个上传图片的流程来替代要用户提交图片base64数据的方式
在index.wxml页面中写如下内容
<view class="page-body">
<view class="page-body-wrapper">
<image src="{{ img }}" bindtap='preview' style="width:100%;height:800rpx;" id="imageDom" mode='aspectFit' />
</view>
<button bindtap="uploads" class="up">拍照/选取图片识别</button>
<view class="footer">效果仅供娱乐。测试期间非面部图片也会返回效果</view>
</view>
没有任何样式,那就在index.wxss页面中写如下样式代码内容
.up {
color: rgb(255, 255, 255);
font-size: 20px;
font-family: 微软雅黑;
width: 200px;
height: 50px;
vertical-align: middle;
text-align: center;
line-height: 45px;
border-radius: 25px;
background-color: rgb(26, 160, 225);
}
.page-body-wrapper image{
background: #ececec;
}
image {
width: 100%;
height: 100%;
max-height: 1
}
.msg {
margin: 10px 0;
text-align: center;
}
.table {
margin-top: 10rpx;
border: 0px solid darkgray;
width: 100%;
}
.tr {
display: flex;
width: 100%;
justify-content: center;
height: 80rpx;
}
.td {
font-family: 微软雅黑;
font-size: 28rpx;
width:100%;
display: flex;
justify-content: center;
text-align: center;
align-items: center;
}
.bg-g{
background: white;
}
.baikeform{
font-size: 20rpx;
color: #c0c0c0;
border-top: 1rpx solid #eeeeee;
margin:30rpx 40rpx 0rpx 40rpx;
padding: 20rpx;
}
.th {
font-size: 28rpx;
width: 48%;
justify-content: center;
background: #3366FF;
color: #fff;
display: flex;
height: 80rpx;
align-items: center;
}
.preview-tips {
margin: 50rpx 0 30rpx;
}
.video {
margin: 20rpx auto;
width: 100%;
height: 300px;
}
switch{
zoom: 0.8;
}
page {
background-color: #F8F8F8;
height: 100%;
font-size: 32rpx;
line-height: 1.6;
}
.weui-cell_ft{
font-size: 32rpx;
}
.page-body-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
.btn-area {
margin-top: 40rpx;
box-sizing: border-box;
width: 100%;
padding: 0 30rpx;
}
.footer{
font-size: 30rpx;
text-align: center;
color: #7367F0;
}
会显示如下的效果图
需要index.js 引入baiduai.js文件、data中增加img变量,对按钮增加事件、对用户选择的图片进行大小判断
小帅这里就一气呵成写完了哈。
var app = getApp();
//引入baiduai.js
var api = require('../../utils/baiduai.js');
Page({
data: {
motto: '动漫化身',
img: ''
},
onShareAppMessage: function () {
return {
title: '动漫化身',
path: '/pages/index/index',
imageUrl: '../../images/sharefaceanime.jpg',
success: function (res) {
if (res.errMsg == 'shareAppMessage:ok') {
wx.showToast({
title: '分享成功',
icon: 'success',
duration: 500
});
}
},
fail: function (res) {
if (res.errMsg == 'shareAppMessage:fail cancel') {
wx.showToast({
title: '分享取消',
icon: 'loading',
duration: 500
})
}
}
}
},
//选择图片绑定事件
uploads: function () {
var that = this
var takephonewidth
var takephoneheight
wx.chooseImage({
count: 1, // 默认9
sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
wx.getImageInfo({
src: res.tempFilePaths[0],
success(res) {
takephonewidth = res.width,
takephoneheight = res.height
}
})
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
if (res.tempFiles[0].size > (4096 * 1024)) {
wx.showToast({
title: '图片文件过大哦',
icon: 'none',
mask: true,
duration: 1500
})
} else {
wx.showLoading({
title: "分析中...",
mask: true
}),
that.setData({
img: res.tempFilePaths[0]
})
}
//根据上传的图片读取图片的base64
var fs = wx.getFileSystemManager();
fs.readFile({
filePath: res.tempFilePaths[0].toString(),
encoding: 'base64',
success(res) {
//获取到图片的base64 进行请求人脸动漫化接口
api.faceAnimeRequest(res.data, {
success(res) {
wx.hideLoading();
that.setData({
img: 'data:image/png;base64,' + res.image
})
}
})
}
})
},
})
},
/**
* 点击查看图片,可以进行保存
*/
preview(e) {
var that = this;
wx.previewImage({
urls: [that.data.img],
current: that.data.img
})
}
});
前面获取的AccessToken需要用到哦
FileUtil 、 Base64Util、 HttpUtil 是百度官方提供的。小帅整理的下载地址在这里 http://aixiaoshuai.mydoc.io/?t=234826
import com.alibaba.fastjson.JSONObject;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Base64;
/**
* @Description 人脸动漫化示例代码
* @author 小帅丶
* @className FaceAnimeAPISample
* @Date 2020/1/10
**/
public class FaceAnimeAPISample {
/** 编码格式 */
private static String ENCODING_UTF_8 = "UTF-8";
public static void main(String[] args) throws Exception{
/** 接口所需的accessToken */
String accessToken = "";
/** 接口地址 */
String api_url = "https://aip.baidubce.com/rest/2.0/image-process/v1/selfie_anime";
/** 图片地址 */
String imgaePath = "F:\\testimg\\demo-card-2.jpg";
/** 图片转byte */
byte[] imageByte = FileUtil.readFileByBytes(imgaePath);
/** 图片byte转base64 */
String imgBase64 = Base64Util.encode(imageByte);
/** 组装接口所需的参数 */
String param = "image="+ URLEncoder.encode(imgBase64, ENCODING_UTF_8);
/** 请求接口返回的内容 */
String result = HttpUtil.post(api_url, accessToken, param);
/**看过接口文档就清楚返回的为图片的base64。并不是图片地址或其他。需要我们额外处理一下。
* 小帅这边就使用fastjson把接口内容转换成Object 读取image的值(即图片的base64) 进行转存成图片文件
*/
JSONObject object = JSONObject.parseObject(result);
//获取图片的base64 并保存成图片文件
GenerateImage(object.getString("image"),"F:\\testimg\\demo-card-2110.jpg");
}
/**
* base64字符串转化成图片
* @param imgStr 接口返回的图片base64数据
* @param imgFilePath 即将要保存的图片的本地路径包含文件名称和格式 例如:F:/generateimage.jpg
* @return
*/
public static boolean GenerateImage(String imgStr, String imgFilePath) { // 对字节数组字符串进行Base64解码并生成图片
if (imgStr == null) // 图像数据为空
return false;
Base64.Decoder decoder = Base64.getDecoder();
try {
// Base64解码
byte[] b = decoder.decode(imgStr);
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {// 调整异常数据
b[i] += 256;
}
}
// 生成jpeg图片
OutputStream out = new FileOutputStream(imgFilePath);// 新生成的图片
out.write(b);
out.flush();
out.close();
System.out.println("保存成功" + imgFilePath);
return true;
} catch (Exception e) {
System.out.println("出错了" + e.getMessage());
return false;
}
}
}
前面获取的AccessToken需要用到哦
import urllib3,base64
import json
from urllib.parse import urlencode
# 前面获取到的AccessToken
access_token=''
http=urllib3.PoolManager()
url='https://aip.baidubce.com/rest/2.0/image-process/v1/selfie_anime?access_token='+access_token
f = open('F:/testimg/demo-card-2.jpg','rb')
# 参数image:图像base64编码
img = base64.b64encode(f.read())
params={'image':img}
# 对base64数据进行urlencode处理
params=urlencode(params)
request=http.request('POST',
url,
body=params,
headers={'Content-Type':'application/x-www-form-urlencoded'})
# 对返回的byte字节进行处理。Python3输出位串,而不是可读的字符串,需要进行转换
result = str(request.data,'utf-8')
# 使用json库 字符串转字典
resultObject = json.loads(result)
# 保存为图片文件
imgByte = base64.b64decode(resultObject['image'])
newFile = open('F:/testimg/demo-card-2110py.jpg','wb')
newFile.write(imgByte)
newFile.close()