> 文档中心 > 基于CS架构的鸿蒙应用|图片风格样式迁移程序

基于CS架构的鸿蒙应用|图片风格样式迁移程序

本项目基于CS架构,利用Java语言,在鸿蒙开发工具DevEco Studio中开发了一款能够进行图片风格样式迁移的程序,实现对图片添加山水画风格滤镜和梵高风格滤镜的功能。本项目最终可以部署在实机上进行使用。​​​​​​​

 应用使用实机展示视频:

【鸿蒙HarmonyOS软件开发】图片样式迁移程序|真机调试|调用图库相机_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1ER4y1P7qT

1 总体设计

图片风格样式迁移是一项利用另一图像的样式重建图像的技术。在该领域内,实现风格迁移的算法有很多,如使用CNN、GAN来生成艺术风格的图像等。Jun-Yan Zhu等人在文献[1]中提出一种利用CycleGAN网络进行图片样式迁移的方法。该方法的优点在于,利用CycleGAN能够实现无配对的两个图片集的训练,即只需要获取两类具有不同特征的数据集,就可以作为训练集进行训练。训练好的模型既可以在桌面端使用,也可以移植到移动设备上,实现一般滤镜相机的功能。

操作系统是手机为首等电子产品的灵魂,到目前为止我国没有一家科技公司拥有独立自主的操作系统。华为在美国的打压之下,不屈不挠,推出了鸿蒙操作系统。为了向鸿蒙生态的发展尽一份微薄之力,本程序基于风格迁移预训练模型,在鸿蒙系统中实现图片风格样式迁移的功能。

1.1 系统架构

本程序系统架构如所示。

图 1 系统架构图

1.2 系统流程

系统流程如图 2所示。

图 2 系统流程图

2 开发环境

本部分包括开发工具及开发语言两部分。其中,开发环境包括前端开发工具与后端开发工具;前端开发语言采用Java与XML(Extensible Markup Language),后端开发语言采用Python。

2.1 开发工具

2.1.1 前端开发工具

前端应用开发使用DevEco Studio3.0 Beta2开发工具。开发工具与项目的版本信息如表格 1所示:

表格 1前端开发版本信息

属性

数值

DevEco Studio Build Version

3.0.0.803

Gradle Version

7.3

OHOS hap plugin

3.0.5.2

Compile SDK Version

7

Compatible API Version

5

项目前端部分的应用目录结构如图 3所示,其中com.examples.stylemigration路径下存放的是提供与用户交互能力的PageAbility与DataAbility文件,与之对应的AbilitySlice文件存放于com.examples.stylemigration/slice目录下。com.examples.stylemigration/utils目录下存放的是封装好的函数库,MyFun中包含了根据时间生成随机文件名的函数,myHTTP中则包含与Http通信相关的函数。控制UI界面的XML布局文件存放于resources/base/layout目录下,UI布局中使用的一些资源文件则存放在resources/base/media目录下。

图 3 前端应用目录结构

2.1.2 后端开发工具

后端服务器开发在Vs Code中进行,Python环境及主要函数库版本如表格 2所示:

表格 2 后端开发版本信息

属性

数值

Python Version

3.8.10

Torch

1.11.0

Flask

2.1.1

Pillow

9.1.0

项目后端部分的服务目录结构如图 4所示,其中checkpoints目录下存放的是已经训练好的迁移模型,包括梵高风格与山水画风格。results目录下存放的是迁移后的图片。web.py文件是后端程序的入口,用于启动服务器,响应http请求,并调用模型进行迁移。

图 4 后端服务目录结构

项目最终部署在阿里云ECS上,系统为Ubuntu 20.04.4 LTS。

2.2 开发语言

2.2.1 前端开发语言

DevEco Studio支持多种语言的代码开发与调试。由于之前曾学习过面向对象的编程,并尝试过微信小程序的开发,本项目使用Java语言编写逻辑代码,并使用XML语言进行UI布局设计。

2.2.2 后端开发语言

本项目后端部分使用Python语言开发,原因如下:

  1. 迁移模型的训练及测试是基于Python语言编写的Pytorch框架,采用Python开发后端,在函数调用方面较为便利。
  2. 考虑到前端使用的Http需求不高,故本项目采用Flask(一个使用Python编写的轻量级Web应用框架)实现[2]。

3. 开发实现

本项目开发包括两部分:UI设计开发与程序逻辑开发,其中UI设计在前端实现,程序逻辑则分为前端实现与后端实现。

3.1 UI设计开发

3.1.1 UI效果

图 5 程序主要UI效果图(1-6)

本项目的UI效果如图 5所示。图 5-1为程序主界面,用户可通过点击导航至4个子功能页面(山水画风格迁移、梵高风格迁移、迁移原理、版本信息)。图 5-2为山水画风格迁移界面,可通过点击按钮来进行图片选取、图片迁移、返回主界面等操作。图 5-3为获取迁移结果后的山水画风格迁移界面。图 5-4与图 5-5为梵高风格迁移界面,其布局与山水画风格的类似。图 5-6为版本信息界面。

 图 6 UI资源文件

UI界面中使用到的图片、背景等文件存放在resources/base/media目录下。

3.2 程序逻辑开发

本项目的前后端交互逻辑如图 7所示。用户通过手机(客户端)选择图片上传至后端服务器(服务端)后,服务端调用深度学习模型进行迁移,将迁移后的图片回传至客户端,并进行展示。

图 7 前后端交互逻辑

3.2.1 前端开发

在本节,对前端程序逻辑的解释将按照各个页面的顺序展开。

1. 主界面——MainAbilitySlice

主界面主要实现的功能为,在用户点击按钮时跳转至对应界面。实现的方法比较简单,只需为按钮绑定事件监听,当监听到按钮按下时,调用presentForResult()方法完成导航即可。实现该逻辑的核心代码如下:

 图 8 页面导航核心代码

为了使界面更加美观,在界面生命周期开始时设置状态栏隐藏及导航栏透明:

图 9 状态栏隐藏及导航栏透明核心代码

2. 山水画风格迁移界面——LandscapeSlice

山水画风格迁移界面主要实现的功能包括图库选择照片、相机拍摄照片、上传图片、下载图片、储存至图库5个功能。


图库选择照片[3]:用户点击“图库”按钮后,利用HarmonyOS提供的DataAbility能力,调用startAbilityForResult()方法跳转至外部应用“图库”。用户在选择图片后,执行onAbilityResult()方法的重载,将用户选择的图片分别转换为位图与byte数组,前者用于更新UI,后者则用于图片上传操作。

图 10 图库跳转及返回结果处理核心代码

相机拍摄照片:用户点击“相机”按钮后,利用HarmonyOS提供的PageAbility能力,调用presentForResult()方法跳转至TakePhotoAbilitySlice()界面,进行拍照。完成拍照操作后,执行onResult()方法的重载,将用户拍摄的图片分别转换为位图与byte数组,前者用于更新UI,后者则用于图片上传操作。

图 11 相机跳转及返回结果处理核心代码

上传图片[4]:用户点击“迁移”按钮,程序将选取的照片读取为FileInputStream类型数据,转换为byte字节流,或直接读取字节流形式的图片。随后,启动一个新的子线程,请求HTTP通信,请求方法为POST,以上传图片字节流。

图 12 上传图片核心代码

下载图片[5]:程序执行上传图片的POST请求后,将等待迁移结果,并提交GET请求。后端响应该请求,同样以字节流的方式将迁移后图片传输至前端,前端将字节流转换为PixelMap位图格式,储存至相册,并调用HarmonyOS中JavaUI的setPixelMap()方法,实现UI界面的更新。

图 13 下载图片核心代码

储存图库:鸿蒙设备图库中的图片默认存放在DCIM目录下,因此,只需将读取到已迁移的图片从字节流转换为jpeg格式即可。需要注意的是,由于需要进行写入操作,需要在config.json中申请储存权限。

图 14 储存图库核心代码

在储存时,根据时间为图片随机生成唯一的文件名,以防因文件名重复导致原有照片被覆盖。

图 15 随机生成文件名

3. 梵高风格迁移界面——VangoghAbilitySlice

梵高风格迁移界面与山水画风格迁移界面的代码逻辑几乎完全一致,唯一不同的地方在于HTTP访问的URL不同,故此处不再赘叙。

4. 迁移原理界面——TheoryAbilitySlice

迁移原理界面主要向用户介绍样式迁移技术的原理。由于知乎上的一篇回答[6]已经给出了非常详尽的介绍,而HarmonyOS提供了WebView能力,能够在应用中访问网页。因此,可直接调用了WebView组件,在界面中展示上述知乎回答。

图 16 迁移原理界面核心代码

5. 版本信息界面——VersionAbilitySlice

版本信息同样调用WebView组件,访问在后端搭建的html网页,向用户展示本项目的版本信息、开发进度等内容。

图 17 版本信息界面核心代码

6. 相机界面——TakePhotoAbilitySlice[7]

相机界面主要用于为本应用提供基本的相机API接口,用于访问相机硬件,呈现拍摄界面,并将所拍摄照片保存至程序缓存中。

在使用相机前,首先申请以下功能权限:

表格 3 相机功能申请权限

权限名称

权限属性值

备注

相机权限

ohos.permission.CAMERA

必选

录音权限

ohos.permission.MICROPHONE

可选

储存权限

ohos.permission.WRITE_USER_STORAGE

必选

位置权限

ohos.permission.LOCATION

可选

实现以上功能的核心代码如下:

图 18 相机界面核心代码

3.2.2 后端开发

后端开发利用Flask框架搭建服务器,实现响应POST、GET请求、调用模型进行迁移的功能。

  • 响应POST请求:从POST请求的body中读取图片字节流数据,然后利用PIL库储存为png格式的图片。
  • 调用模型:根据前端访问的URL地址调用Test()函数,若路由为/upload/landscape,则进行山水画迁移;若路由为/upload/vangogh,则进行梵高风格迁移。

图 19 响应POST请求并进行迁移核心代码

  • 响应GET请求:接受前端GET请求后,读取迁移后图片,将其转换为字节流,放入response中返回前端。

图 20 响应GET请求核心代码

4. 测试应用

本部分包括图片风格样式迁移程序的调试及结果展示。

4.1 程序调试

项目编译成功后,DevEco提供了几种调试方式可供选择。

(1)真机调试;

(2)远程真机调试;

(3)模拟机调试。

本项目使用真机调试,所使用机型为Huawei P40 Pro。

4.2 结果展示

图 21 主页界面

进入应用后,首先是主页界面。该界面展示了本应用的四个功能,包含两种风格迁移、迁移原理介绍与版本信息陈列。

 图 22 山水画风格迁移界面

山水画风格迁移界面分为图片展示区域与按钮交互区域两部分。在图片展示区域,呈现原图与迁移后的图片。在按钮交互区域,用户可点击图库按钮从图库中选择待迁移照片,也可点击相机按钮,对拍摄的照片进行样式迁移。点击迁移按钮,可将图片进行转换。稍等片刻后,迁移后的图片将呈现在界面中,并自动保存至图库。点击返回,可退回至主页界面。

图 23 梵高风格迁移界面

梵高风格迁移界面布局及功能,与山水画风格迁移界面类似。

图 24 迁移原理界面与版本信息界面

在迁移原理界面,本应用呈现了一个外部网页,用户可查看到本应用实现样式迁移的原理。

在版本信息界面,用户可看到本应用的开发日志及开发人员信息。

用户使用流程如下:

图 25 用户使用流程

5. 问题分析

在程序开发过程中主要遇到了以下问题:

5.1 真机调试签名错误

问题描述:真机调试运行后出现:INSTALL_FAILED_APP_SOURCE_NOT_TRUSTED 异常提示。

解决方法:这是因为在真机设备中调试/运行的时候,该Hap的签名信息中不包含当前真机设备的UDID信息导致的。通过DevEco Studio的自动化签名功能进行签名即可解决。

图 26 自动化签名工具

点击File > Project Structure > Project > Signing Configs,打开签名配置页面,勾选“Automatically generate signing”,等待重新签名然后,然后点击OK即可。

5.2 访问图库偶尔会导致闪退

问题描述:跳转至图库或文件管理后,没有选择图片,直接返回会导致程序闪退。

解决方案:这是因为没有考虑到onAbilityResult()方法中返回为空的情况。只需在该方法中加入判断是否非空的语句即可:

图 27 处理返回空值

5.3 找不到文件路径

问题描述:通过引用ID的方式无法访问储存在resources/base目录以外的资源文件。

解决方案:这是因为只有base目录下的资源文件才会被编译成二进制文件,并被赋予资源文件ID。一方面,可将其他位置的静态资源文件放入base目录下。另一方面,对于程序运行中的动态资源文件,可以利用FileDescriptor类,通过传入资源文件的URI(Uniform Resource Identifier,统一资源标识符)来访问。

小注:实际上这个地方是真机调试与模拟器调试之间最大的不同点。模在拟器调试中,对于大部分资源文件,都可以通过相对路径或绝对路径的方式进行访问。而在真机调试中,系统的目录结构与开发环境中的结构有较大差异,因此往往需要通过HarmonyOS提供的一些文件操作类来实现访问。

6. 实验总结

目前该程序仍存在一些需要完善的地方。例如,如果该程序投入商用,需要增添一个用于收集用户信息的登陆界面;考虑到安全问题,不能采用http明文通信,而是应当采用https等加密协议进行通信。此外,用户在相机界面完成照片拍摄后返回主界面,再次进入风格迁移界面并调用相机时,会出现闪退的情况。上述问题将在日后的工作中进行改进。

参考资料

  1. Zhu J Y , Park T , Isola P , et al. Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks[J]. IEEE, 2017.
  2. Flask中文文档欢迎来到 Flask 的世界 — Flask 中文文档 (2.0.2)https://dormousehole.readthedocs.io/en/latest/index.html
  3. 鸿蒙跳转到图库或文件 鸿蒙跳转到图库或者文件选择图片并显示到Image控件中_华为开发者联盟的技术博客_51CTO博客鸿蒙跳转到图库或者文件选择图片并显示到Image控件中,今天有个坛友问跳转到文件和图库如何将选择的图片读取出来在Image控件中显示,我这里分享一下解决思路。首先当然是建个布局页面,页面上放个按钮和图片控件,如下代码123456789101112131415161718192021<DirectionalLayout    xmlns:ohos="http:/https://blog.51cto.com/u_14772288/2857920
  4. Java POST上传图片java http 上传_Java使用HttpURLConnection上传文件_一点能源的博客-CSDN博客https://blog.csdn.net/weixin_35674742/article/details/114192180
  5. Java GET下载图片java http get 图片_Http协议Get方式获取图片_便洁宝的博客-CSDN博客https://blog.csdn.net/weixin_35878683/article/details/114192153
  6. CycleGAN原理解析CycleGAN原理以及代码全解析 - 知乎https://zhuanlan.zhihu.com/p/37198143
  7. 相机设备开发指导鸿蒙开发教程w3c,鸿蒙OS 相机设备开发指导_流川枫海的博客-CSDN博客https://blog.csdn.net/weixin_31414515/article/details/117418109