万粉博主推荐,微信小程序 +Flask 后端调用 AnimeGanV2

67af3215febeac43e71b6463db5a12c7.gif

作者 | Yunlord

博客 | Yunlord

做一个小程序,直接在手机端就能一键生成专属于自己的动漫头像,下面是展示效果!!!

8ce3ae56a4716b18df440a77275c8358.gif

74f6abf75c232b3343bc90a230d1f2af.png

核心功能设计

该小程序想要实现的是将微信头像或者选择相册中的照片动漫化,所以拆解需求后,整理的核心功能如下:

  • 授权登录获取头像及昵称

  • 选择相册中的图片

  • 点击动漫化按钮,调用Flask后端生成图像

  • 保存图像

94257b98734efdf2611da8f1d04f7429.png

微信小程序前端实现步骤

首先新建一个空白的微信小程序项目。

1、登录界面

在 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>

在 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界面。

效果如下:

6718c797c130a5e87cd391e1b0e970ba.gif

2、avantar页面

在该页面进行选取照片以及头像动漫化。

在 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)
        }
      })
    },

fcd1cb2bcb98067412848089ae755a0e.png

Flask后端实现步骤

1、配置RESTful路由方法

@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传回去。

2、调用AnimeGanv2实现动漫化

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实现图像动漫化。   

最后实现效果:

40b4c59595ee5af4df97490da46308ea.png

a7091e02d94886d088f6002d60f51d2e.png

总结

其实这个小程序实现起来并不是很难,只需要配置基础的深度学习环境和Flask编程就好了,再了解一些小程序基本的api,就能够开发出来,大家有时间的可以去试试,后台我已经搭好了,大家可以直接使用,可以看看效果。有什么问题可以在评论区留言~

d1e7d957b0e6fa23fa5de24ebd0c5b29.gif

技术

用技术实现时序羽毛球动作预测

资讯

AI在嘈杂环境中看唇语识别理解

技术

50行python代码制作数据大屏

资讯

GPT-3平替版语言模型,性能更优化

a41effe4bbaa6af2315d50bdb1829a57.png

分享

02956fcd5456eced75c87a27bd11bdf2.png

点收藏

9cfb9baa415086a047a5ee45cee07882.png

点点赞

01a89bd3a91dbfd443571d7370cc11c0.png

点在看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值