基于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语言开发,原因如下:
- 迁移模型的训练及测试是基于Python语言编写的Pytorch框架,采用Python开发后端,在函数调用方面较为便利。
- 考虑到前端使用的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等加密协议进行通信。此外,用户在相机界面完成照片拍摄后返回主界面,再次进入风格迁移界面并调用相机时,会出现闪退的情况。上述问题将在日后的工作中进行改进。
参考资料
- Zhu J Y , Park T , Isola P , et al. Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks[J]. IEEE, 2017.
- Flask中文文档欢迎来到 Flask 的世界 — Flask 中文文档 (2.0.2)https://dormousehole.readthedocs.io/en/latest/index.html
- 鸿蒙跳转到图库或文件 鸿蒙跳转到图库或者文件选择图片并显示到Image控件中_华为开发者联盟的技术博客_51CTO博客鸿蒙跳转到图库或者文件选择图片并显示到Image控件中,今天有个坛友问跳转到文件和图库如何将选择的图片读取出来在Image控件中显示,我这里分享一下解决思路。首先当然是建个布局页面,页面上放个按钮和图片控件,如下代码123456789101112131415161718192021<DirectionalLayout xmlns:ohos="http:/https://blog.51cto.com/u_14772288/2857920
- Java POST上传图片java http 上传_Java使用HttpURLConnection上传文件_一点能源的博客-CSDN博客https://blog.csdn.net/weixin_35674742/article/details/114192180
- Java GET下载图片java http get 图片_Http协议Get方式获取图片_便洁宝的博客-CSDN博客https://blog.csdn.net/weixin_35878683/article/details/114192153
- CycleGAN原理解析CycleGAN原理以及代码全解析 - 知乎https://zhuanlan.zhihu.com/p/37198143
- 相机设备开发指导鸿蒙开发教程w3c,鸿蒙OS 相机设备开发指导_流川枫海的博客-CSDN博客https://blog.csdn.net/weixin_31414515/article/details/117418109