HarmonyOS APP实战-基于Image Kit的图像处理APP - 第1篇:环境搭建与项目初始化

HarmonyOS APP实战-基于Image Kit的图像处理APP - 第1篇:环境搭建与项目初始化
HarmonyOS APP实战-基于Image Kit的图像处理APP - 第1篇环境搭建与项目创建1. 开篇周末的午后你翻出手机里一张老照片想调整一下色调、裁掉多余的部分却发现系统相册自带的编辑功能太简单而那些功能强大的专业修图APP不是需要付费订阅就是广告满天飞。如果能亲手打造一款属于自己的图像处理工具把官方文档里那些“图片解码”“色彩矩阵”“像素操作”的能力都用起来那该多好这正是我们接下来要一起完成的事情。本系列将基于HarmonyOS的Image Kit图片处理服务从零开发一个功能完整的图像处理APP。它至少包含图片选择、解码展示、缩放裁剪、旋转翻转、滤镜调色、编码导出、批量处理、水印叠加和历史记录管理等实用功能。本篇作为整个系列的开篇主要任务是打好地基安装并配置DevEco Studio开发环境创建HarmonyOS工程配置必要的文件读写权限并搭建底部Tab导航框架首页、编辑、我的。后续所有功能的开发都将在这个骨架上生长。2. 核心实现2.1 基础配置权限声明与模块导入HarmonyOS应用的权限声明在module.json5文件中。我们要开发的APP需要读取和写入用户设备上的图片文件因此必须声明ohos.permission.READ_MEDIA和ohos.permission.WRITE_MEDIA两个权限。代码块1module.json5权限配置{ module: { name: entry, type: entry, description: $string:module_desc, mainElement: EntryAbility, deviceTypes: [ phone ], requestPermissions: [ { name: ohos.permission.READ_MEDIA, // 读取媒体文件权限用于从相册选择图片 reason: $string:permission_read_media_reason, // 向用户展示的权限申请理由 usedScene: { abilities: [ EntryAbility ], // 权限在EntryAbility中使用 when: always // 始终可用 } }, { name: ohos.permission.WRITE_MEDIA, // 写入媒体文件权限用于保存处理后的图片到相册 reason: $string:permission_write_media_reason, usedScene: { abilities: [ EntryAbility ], when: always } } ], // ... 其他配置项 } }关键点说明requestPermissions字段用于声明应用需要申请的敏感权限。权限的name必须与官方文档中定义的常量完全一致不能拼写错误。reason字段对应resources/base/element/string.json中的字符串资源用于向用户解释为什么要使用该权限。usedScene用于定义权限在哪个Ability中被使用以及使用场景前台或后台有助于用户理解权限用途。同时需要在resources/base/element/string.json中添加权限申请理由的字符串资源{string:[{name:permission_read_media_reason,value:用于从相册选择图片进行编辑},{name:permission_write_media_reason,value:用于将编辑后的图片保存到相册}]}2.2 核心逻辑底部Tab导航组件底部导航是大多数工具类APP的标配。HarmonyOS使用Tabs和TabContent组件实现标签页导航。我们将封装一个可复用的底部导航容器组件。代码块2TabNavigation组件实现TabNavigation.ets/** * TabNavigation组件 * 提供应用底部Tab导航框架 * 包含首页、编辑、我的三个标签页 */Componentexportstruct TabNavigation{// 当前选中的Tab索引从0开始StatecurrentIndex:number0/** * 构建页面主体 * 包含顶部的标题栏区域、中间的Tab内容区域、底部的导航栏 */build(){// 使用Column实现垂直布局Column(){// 顶部标题栏Row(){Text(图片处理工具).fontSize(20).fontWeight(FontWeight.Bold).width(100%).textAlign(TextAlign.Center)}.height(56).width(100%).backgroundColor(#F5F5F5)// Tabs组件实现标签页切换// barPosition设置为BarPosition.End将导航栏置于底部Tabs({barPosition:BarPosition.End}){// 首页Tab内容// 通过TabContent嵌入首页页面TabContent(){// 首页内容占位后续替换为具体页面组件Column(){Text(首页).fontSize(24).fontColor(#666666)}.width(100%).height(100%).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}// tabBar定义导航项的外观传入TabBarItemBuilder.tabBar(this.buildTabItem(0,首页,$r(app.media.ic_home)))// 编辑Tab内容TabContent(){// 编辑页面占位后续替换为图片编辑器Column(){Text(编辑).fontSize(24).fontColor(#666666)}.width(100%).height(100%).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}.tabBar(this.buildTabItem(1,编辑,$r(app.media.ic_edit)))// 我的Tab内容TabContent(){// 我的页面占位后续替换为个人信息或设置页Column(){Text(我的).fontSize(24).fontColor(#666666)}.width(100%).height(100%).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}.tabBar(this.buildTabItem(2,我的,$r(app.media.ic_user)))}// 监听Tab切换事件更新currentIndex.onChange((index:number){this.currentIndexindex})// 设置当前激活的Tab索引.index(this.currentIndex)// 设置Tab导航栏的高度.barHeight(64)// 设置Tab导航栏的背景色.barBackgroundColor(#FFFFFF).width(100%).height(100%)}.width(100%).height(100%)}/** * 构建单个Tab项的布局 * param index Tab项的索引 * param label 显示的文字标签 * param icon 图标的资源引用 * returns 返回Column组件作为Tab项的容器 */BuilderbuildTabItem(index:number,label:string,icon:Resource){Column(){Image(icon).width(24).height(24)// 根据当前选中状态切换图标颜色.fillColor(this.currentIndexindex?Color.Blue:Color.Gray)Text(label).fontSize(12)// 根据当前选中状态切换文字颜色.fontColor(this.currentIndexindex?Color.Blue:Color.Gray).margin({top:4})}.width(100%).height(100%).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}}关键点说明Tabs组件配合TabContent是最常用的标签页实现方式。barPosition控制导航栏位置BarPosition.End表示底部。Builder buildTabItem是一个自定义构建函数用于封装重复的Tab项UI逻辑。Builder装饰的方法可以接收参数提升代码复用性。$r(app.media.ic_home)是资源引用的语法需要先在resources/base/media/目录下放置对应的图标资源文件。onChange事件回调用于监听Tab切换更新currentIndex状态实现选中态的颜色变化。2.3 完整页面整合EntryAbility与Index页面现在我们将底层的权限配置和导航组件组装到入口页面中。代码块3完整Index页面pages/Index.ets/** * Index页面 - 应用主入口页面 * 整合底部Tab导航组件 */// 导入自定义的TabNavigation组件import{TabNavigation}from../components/TabNavigation// 导入Image Kit模块后续处理图片时需要用到// ohos.multimedia.image 是官方提供的图片处理核心APIimportimagefromohos.multimedia.imageEntryComponentstruct Index{// 页面构建入口build(){// Stack容器用于实现全屏布局Stack(){// 引用自定义的TabNavigation组件TabNavigation().width(100%).height(100%)}.width(100%).height(100%)}}EntryAbility.tsAppScope/entry/src/main/ets/entryability/EntryAbility.ts/** * EntryAbility - 应用主Ability * 负责初始化窗口、设置页面加载等 */importAbilityConstantfromohos.app.ability.AbilityConstantimporthilogfromohos.hilogimportUIAbilityfromohos.app.ability.UIAbilityimportWindowfromohos.windowimportWantfromohos.app.ability.WantexportdefaultclassEntryAbilityextendsUIAbility{/** * 当Ability创建时调用 * param want 启动参数 * param launchParam 启动参数 */onCreate(want:Want,launchParam:AbilityConstant.LaunchParam):void{hilog.info(0x0000,testTag,%{public}s,Ability onCreate)}/** * 当Ability与窗口关联时调用 * 设置页面加载为Index页面 * param window 当前窗口对象 */onWindowStageCreate(windowStage:Window.WindowStage):void{// 加载Index页面作为主页面windowStage.loadContent(pages/Index,(err,data){if(err.code){hilog.error(0x0000,testTag,Failed to load the content. Cause: %{public}s,JSON.stringify(err)??)return}hilog.info(0x0000,testTag,Succeeded in loading the content. Data: %{public}s,JSON.stringify(data)??)})}// ... 其他生命周期方法}关键点说明EntryAbility是应用启动时运行的第一个Ability。onWindowStageCreate方法中通过windowStage.loadContent指定应用启动后显示的第一个页面参数为页面的路径字符串例如pages/Index。import image from ohos.multimedia.image导入了Image Kit核心模块。虽然本篇未使用具体图片处理API但提前导入便于后续快速使用。自定义组件TabNavigation通过import语句从相对路径导入后可以作为普通组件直接在其他组件中使用。HarmonyOS的自定义组件具有独立的作用域需要显式导入才能在其他文件中使用。3. 运行验证完成以上代码编写后在DevEco Studio中连接真机或启动模拟器点击运行按钮。预期效果应用启动后显示一个带有灰色标题栏图片处理工具的页面。页面底部有三个Tab项首页、编辑、我的分别带有图标和文字。默认选中首页Tab图标和文字显示为蓝色点击编辑或我的后对应Tab项高亮为蓝色其余保持灰色。三个Tab对应的内容区域分别显示对应的文字占位首页“编辑”“我的”。如果运行失败请检查module.json5中权限名称是否有拼写错误图标资源文件是否放置在正确路径resources/base/media/TabNavigation组件的导入路径是否正确4. 小结与预告本篇完成了图像处理APP的基础骨架搭建创建了HarmonyOS工程配置了读写媒体文件的权限实现了底部Tab导航框架并整合了EntryAbility与Index页面。从此刻开始你拥有了一个可运行、可扩展的APP容器。下一篇文章我们将正式进入图片处理功能开发的第一环图片选择与预览。届时会使用PhotoViewPicker从系统相册选择图片并用Image Kit的createImageSource解码图片在编辑Tab中预览展示。准备好打开相册的大门了吗我们第2篇再见。