赞
踩
之前写了篇文章《超越前作,实现动漫风格迁移——AnimeGANv2》,里面提到使用AnimeGANv2实现人物动漫化,生成一个独一无二对自己价值珍贵的头像。不过操作起来有亿点点麻烦,所以希望做一个小程序,直接在手机端就能一键生成专属于自己的动漫头像,下面是展示效果!!!
该小程序想要实现的是将微信头像或者选择相册中的照片动漫化,所以拆解需求后,整理的核心功能如下:
首先新建一个空白的微信小程序项目,详细步骤可以参考之前《Python+微信小程序开发(一)了解和环境搭建》的文章。
在pages/index/index.wxml设计页面:
- <view wx:if="{{canIUse}}">
- <view class='header'>
- <view class="userinfo-avatar">
- <open-data type="userAvatarUrl"></open-data>
- </view>
- </view>
- <view class="content">
- <view>申请获取以下权限</view>
- <text>获得您的公开信息(昵称,头像等)</text>
- </view>
- <button wx:if="{{canIUse}}" class="loginBtn" type="primary" lang="zh_CN" bindtap="bindGetUserProfile" >
- 授权登录
- </button>
- </view>
在pages/index/index.js添加用户信息验证:
- bindGetUserProfile(e) //当用户点击授权登录按钮触发 bindGetUserInfo函数
- {
- var that=this
- wx.getUserProfile({
- desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
- success: (res) => {
- // console.log(res.userInfo)
- var avantarurl=res.userInfo.avatarUrl;
- wx.navigateTo({
- url: '../../pages/change/change?url='+ avantarurl ,
- })
- },
- fail:(res)=>{
- console.log(1)
- }
- })
-
- },
其中将头像的url传递给avanta界面。
效果如下:
在该页面进行选取照片以及头像动漫化。
在pages/avantar/avantar.wxml设计页面:
- <!--pages/avantar/avantar.wxml-->
- <view class='preview'>
- <view class="Imgtag">
- <image class="tag" src='{{prurl}}' mode='aspectFit'></image>
- </view>
- <view class="bottomAll">
- <button bindtap='selectImg' class="saveBtn">选择图片</button>
- <button bindtap='generateAvantar' class="saveBtn">动漫化</button>
- <button bindtap='save' class="saveBtn">保存头像</button>
- </view>
- </view>
在pages/avantar/avantar.js定义函数:
其中onload函数接收index传递的url。
- onLoad: function (options) {
- if(options.url){
- // console.log(options.url)
- var path = this.headimgHD(options.url)
- console.log(path)
- this.setData({
- image:path,
- // image1:path,
- // baseURL:path
- })
- }
其中chooseImage函数实现选择图片。
- chooseImage() {
- var that = this;
- wx.showActionSheet({
- itemList: ['从相册中选择', '拍照'],
- itemColor: "#FAD143",
- success: function (res) {
- if (!res.cancel) {
- wx.showLoading({
- title: '正在读取...',
- })
- if (res.tapIndex == 0) {
- that.chooseWxImage1('album', 1)
- } else if (res.tapIndex == 1) {
- that.chooseWxImage1('camera', 1)
- }
- }
- }
- })
- },
savePic函数保存照片。
- savePic(e) {
- let that = this
- var baseImg = that.data.baseImg
- //保存图片
- var save = wx.getFileSystemManager();
- var number = Math.random();
- save.writeFile({
- filePath: wx.env.USER_DATA_PATH + '/pic' + number + '.png',
- data: baseImg,
- encoding: 'base64',
- success: res => {
- wx.saveImageToPhotosAlbum({
- filePath: wx.env.USER_DATA_PATH + '/pic' + number + '.png',
- success: function (res) {
- wx.showToast({
- title: '保存成功',
- })
- },
- fail: function (err) {
- console.log(err)
- }
- })
- console.log(res)
- },
- fail: err => {
- console.log(err)
- }
- })
- },
generateAvantar函数调用postdata函数实现头像动漫化。
- generateAvantar:function(e){
- var that = this
- console.log(that.data.prurl)
- wx.uploadFile({
- url: 'http://127.0.0.1:8090/postdata',
- filePath: that.data.prurl,
- name: 'content',
- success: function (res) {
- console.log(res.data);
- var resurl=JSON.parse(res.data)['resurl']
-
- that.setData({
- prurl: resurl
- })
- if (res) {
-
- wx.showToast({
- title: '转换完成',
- duration: 3000
- });
- }
- },
- fail: (res) =>{
- console.log('fail===',res)
- }
- })
- },
- @app.route('/postdata', methods=['POST'])
- def postdata():
- f = request.files['content']
- print(f)
- user_input = request.form.get("name")
- basepath = os.path.dirname(__file__) # 当前文件所在路径
- src_imgname = str(uuid.uuid1()) + ".jpg"
- upload_path = os.path.join(basepath, 'static/srcImg/')
-
- if os.path.exists(upload_path)==False:
- os.makedirs(upload_path)
- f.save(upload_path + src_imgname)
- # img = cv2.imread(upload_path + src_imgname, 1)
-
- save_path = os.path.join(basepath, 'static/resImg/')
- if os.path.exists(save_path) == False:
- os.makedirs(save_path)
- generateAvantar(src_imgname,upload_path,save_path)
- resSets["value"] = 10
- resSets["resurl"] = "http://127.0.0.1:8090" +'/static/resImg/' + src_imgname
- return json.dumps(resSets, ensure_ascii=False)
该代码主要接受前端传来的图片url,进行处理并且通过json传回去。
- net = Generator()
- net.load_state_dict(torch.load(args.checkpoint, map_location="cpu"))
- net.to(args.device).eval()
- # print(f"model loaded: {args.checkpoint}")
-
- # os.makedirs(args.output_dir, exist_ok=True)
-
- def load_image(image_path, x32=False):
- img = cv2.imread(image_path).astype(np.float32)
- img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
- h, w = img.shape[:2]
-
- if x32: # resize image to multiple of 32s
- def to_32s(x):
- return 256 if x < 256 else x - x%32
- img = cv2.resize(img, (to_32s(w), to_32s(h)))
-
- img = torch.from_numpy(img)
- img = img/127.5 - 1.0
- return img
-
- def generateAvantar(src_imgname,upload_path,save_path):
-
- image = load_image((upload_path+src_imgname), args.x32)
- with torch.no_grad():
- input = image.permute(2, 0, 1).unsqueeze(0).to(args.device)
- out = net(input, args.upsample_align).squeeze(0).permute(1, 2, 0).cpu().numpy()
- out = (out + 1)*127.5
- out = np.clip(out, 0, 255).astype(np.uint8)
- cv2.imwrite(os.path.join(save_path, src_imgname), cv2.cvtColor(out, cv2.COLOR_BGR2RGB))
该代码主要是调用AnimeGanv2实现图像动漫化。
最后实现效果:
其实这个小程序实现起来并不是很难,只需要配置基础的深度学习环境和Flask编程就好了,再了解一些小程序基本的api,就能够开发出来,大家有时间的可以去试试,后台我已经搭好了,大家可以直接使用,可以看看效果。有什么问题可以在评论区留言,或者通过下方链接联系我。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。