HarmonyOS开发实战:小分享-ImageEditPage图片编辑器——黑色主题与文字叠加


前言
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
图片编辑器 让用户选择图片后添加文字、滤镜等效果。小分享 App 的 ImageEditPage 采用黑色主题背景,使用 position 属性实现文字叠加在图片上。本篇讲解 黑色主题设计、position 绝对定位、滤镜条横向滚动、@State 选中态管理 等核心实现。详细 API 可参考 HarmonyOS position 官方文档。
一、ImageEditPage 完整代码
1.1 页面完整实现
import router from '@ohos.router';
import { FilterItem } from '../common/interfaces';
@Entry
@Component
struct ImageEditPage {
@State selectedFilter: number = 0;
private filters: Array<FilterItem> = [
{ name: '原图', color: '#F0F0F0' },
{ name: '清新', color: '#E8F5E9' },
{ name: '暖色', color: '#FFF3E0' },
{ name: '胶片', color: '#F3E5F5' },
{ name: '黑白', color: '#E0E0E0' },
{ name: '复古', color: '#EFEBE9' }
];
build() {
Column() {
// Header
this.HeaderBar()
// 图片预览区 + 文字叠加
this.ImagePreview()
// 底部工具栏
this.BottomToolbar()
}
.width('100%').height('100%').backgroundColor('#1A1A1A')
}
}
二、黑色主题设计
2.1 黑色背景
.width('100%').height('100%').backgroundColor('#1A1A1A')
黑色主题的页面结构:
Column (主容器,黑色背景 #1A1A1A)
├─ Row (Header,白色背景)
├─ Column (图片预览区,黑色背景)
│ ├─ Column (图片占位,灰色 #F0F0F0)
│ └─ Column (文字叠加层,position 定位)
└─ Column (工具栏,白色背景)
2.2 Header 导航栏
Row() {
Text('‹').fontSize(24).fontColor('#1A1A1A')
.onClick(() => { router.back() })
Text('图片编辑').fontSize(18).fontWeight(FontWeight.Bold)
.fontColor('#1A1A1A').layoutWeight(1).textAlign(TextAlign.Center)
Text('完成').fontSize(16).fontColor('#F5A623')
.onClick(() => { router.pushUrl({ url: 'pages/SharePreviewPage' }) })
}
.width('100%').padding({ left: 16, right: 16, top: 12, bottom: 12 })
.backgroundColor(Color.White)
三、position 文字叠加
3.1 position 定位
Column({ space: 8 }) {
Text('山川湖海,').fontSize(24).fontWeight(FontWeight.Bold).fontColor(Color.White)
Text('天地与爱。').fontSize(24).fontWeight(FontWeight.Bold).fontColor(Color.White)
}
.position({ x: 24, y: 200 })
3.2 position 参数
| 参数 | 值 | 说明 |
|---|---|---|
x |
24 | 距左侧 24vp |
y |
200 | 距顶部 200vp |
3.3 position 各模式
| 模式 | 语法 | 说明 |
|---|---|---|
| 绝对定位 | position({x, y}) |
相对于父容器定位 |
| 相对定位 | offset({x, y}) |
相对于自身原始位置 |
| 百分比 | position('50%', '50%') |
相对于父容器百分比 |
提示:
position定位的元素会脱离文档流,不会影响其他元素的布局。
四、滤镜条横向滚动
4.1 横向 Scroll
Scroll() {
Row({ space: 12 }) {
ForEach(this.filters, (item: FilterItem, index: number) => {
Column({ space: 6 }) {
Column().width(56).height(56)
.backgroundColor(item.color).borderRadius(8)
.border({ width: this.selectedFilter === index ? 2 : 0, color: '#F5A623' })
.onClick(() => { this.selectedFilter = index })
Text(item.name).fontSize(11)
.fontColor(this.selectedFilter === index ? '#F5A623' : '#666666')
}
.alignItems(HorizontalAlign.Center)
}, (item: FilterItem, index: number) => item.name)
}
.padding({ left: 16, right: 16 })
}
.scrollable(ScrollDirection.Horizontal).scrollBar(BarState.Off)
4.2 滤镜列表
| 滤镜 | 索引 | 色值 | 说明 |
|---|---|---|---|
| 原图 | 0 | #F0F0F0 |
无效果 |
| 清新 | 1 | #E8F5E9 |
绿色调 |
| 暖色 | 2 | #FFF3E0 |
暖色调 |
| 胶片 | 3 | #F3E5F5 |
紫色调 |
| 黑白 | 4 | #E0E0E0 |
灰度 |
| 复古 | 5 | #EFEBE9 |
棕色系 |
五、@State 选中态管理
5.1 选中态逻辑
@State selectedFilter: number = 0
5.2 选中态视觉反馈
// 边框 - 选中时显示 2px 橙色边框
.border({
width: this.selectedFilter === index ? 2 : 0,
color: '#F5A623'
})
// 文字颜色 - 选中时变为主色
.fontColor(this.selectedFilter === index ? '#F5A623' : '#666666')
六、工具栏按钮
6.1 @Builder 封装
@Builder ToolBtn(icon: string, label: string) {
Column({ space: 4 }) {
Text(icon).fontSize(20)
Text(label).fontSize(11).fontColor('#666666')
}
.alignItems(HorizontalAlign.Center)
}
6.2 工具栏布局
Row({ space: 0 }) {
this.ToolBtn('', '滤镜')
this.ToolBtn('', '调整')
this.ToolBtn('', '贴纸')
this.ToolBtn('T', '文字')
this.ToolBtn('', '裁剪')
}
.width('100%').height(60).backgroundColor(Color.White)
.justifyContent(FlexAlign.SpaceAround)
七、路由跳转
7.1 完成按钮
Text('完成').fontSize(16).fontColor('#F5A623')
.onClick(() => { router.pushUrl({ url: 'pages/SharePreviewPage' }) })
7.2 返回按钮
Text('‹').fontSize(24).fontColor('#1A1A1A')
.onClick(() => { router.back() })
八、常见问题
8.1 问题 1:position 定位不生效
原因:父容器没有设置 width 和 height。
解决:确保父容器有明确的宽高值。
8.2 问题 2:横向 Scroll 不滚动
原因:Row 没有足够的宽度(Row 的宽度应该由内容撑开)。
解决:不要给 Row 设置 width('100%'),让内容决定宽度。
九、核心知识点
9.1 技术要点
- 黑色背景用
backgroundColor('#1A1A1A') - 文字叠加用
position({x, y})绝对定位 - 滤镜条横向滚动用
Scroll(scrollable: Horizontal) - 选中态用
@State+border条件渲染
9.2 实战建议
- 黑色背景提升编辑视觉沉浸感
- position 定位文字在图片上
- 滤镜选中态用 border 条件渲染
总结
本文详细讲解了 ImageEditPage 图片编辑器的完整实现,从 黑色主题设计、position 文字叠加、滤镜条横向滚动 到 @State 选中态管理,涵盖了图片编辑器的全部核心功能。下一篇我们将深入 LinkEditPage 链接分享的实现。
附录:图片编辑器的完整实现细节
1. 完整的页面结构
Column (主容器,黑色背景 #1A1A1A)
├─ Row (Header 导航栏,白色背景)
│ ├─ Text('‹') 返回按钮
│ ├─ Text('图片编辑') 标题
│ └─ Text('完成') 跳转按钮
├─ Column (图片预览区,黑色背景) - layoutWeight(1)
│ ├─ Column (图片占位,灰色 #F0F0F0)
│ │ └─ Text('') 80px Emoji
│ └─ Column (文字叠加层)
│ └─ position({x:24, y:200}) 定位
└─ Column (底部工具栏,白色背景)
├─ Row (工具行) - 滤镜/调整/贴纸/文字/裁剪
└─ Scroll (滤镜条,横向滚动)
└─ Row - 6 个滤镜缩略图
2. 工具栏按钮详解
@Builder ToolBtn(icon: string, label: string) {
Column({ space: 4 }) {
Text(icon).fontSize(20)
Text(label).fontSize(11).fontColor('#666666')
}
.alignItems(HorizontalAlign.Center)
}
3. 滤镜选中态的实现方式
| 状态 | 边框宽度 | 边框颜色 | 文字颜色 |
|---|---|---|---|
| 选中 | 2px | #F5A623 |
#F5A623 |
| 未选中 | 0px | 透明 | #666666 |
4. 与文字编辑器的对比
| 对比维度 | ImageEditPage | TextEditPage |
|---|---|---|
| 背景色 | 黑色 #1A1A1A |
白色 #FFFFFF |
| 文字叠加 | position 定位 | 直接排列 |
| 滤镜 | 6 种滤镜预设 | 无 |
| 工具栏 | 双行(工具+滤镜) | 双行(工具+格式) |
| 跳转目标 | SharePreviewPage | PreviewPage |
5. 扩展方向
- 真实图片选择:集成 PhotoViewPicker
- 真实滤镜处理:集成 EffectKit
- 图片裁剪功能:集成 ImageEditor
- 贴纸功能:预置贴纸库
- 文字样式:字号、颜色、字体选择
以上扩展功能将在后续文章详细介绍。
6. 滤镜数据模型
export interface FilterItem {
name: string; // 滤镜名称
color: string; // 滤镜预览色值
}
private filters: Array<FilterItem> = [
{ name: '原图', color: '#F0F0F0' },
{ name: '清新', color: '#E8F5E9' },
{ name: '暖色', color: '#FFF3E0' },
{ name: '胶片', color: '#F3E5F5' },
{ name: '黑白', color: '#E0E0E0' },
{ name: '复古', color: '#EFEBE9' }
];
7. 键盘快捷键支持
// 返回键处理
.onClick(() => { router.back() })
// 完成键处理
.onClick(() => { router.pushUrl({ url: 'pages/SharePreviewPage' }) })
8. 性能优化建议
| 优化项 | 建议 | 原因 |
|---|---|---|
| 滤镜预览 | 使用缩略图而非全尺寸 | 减少内存占用 |
| 图片加载 | 异步加载 | 避免阻塞 UI |
| 工具栏 | 使用 @Builder 复用 | 减少重复代码 |
| 状态管理 | 最小化 @State 使用 | 减少不必要的 UI 刷新 |
9. 完整代码索引
| 文件路径 | 说明 |
|---|---|
pages/ImageEditPage.ets |
图片编辑器页面 |
common/interfaces.ets |
FilterItem 接口定义 |
components/BottomTabBar.ets |
底部导航栏组件 |
10. 本文涉及的所有 API
| API | 用途 | 文档链接 |
|---|---|---|
@State |
状态管理 | State Guide |
@Builder |
UI 复用 | Builder Guide |
position() |
绝对定位 | Position |
Scroll |
横向滚动 | Scroll Component |
border() |
边框样式 | Border |
router.pushUrl() |
路由跳转 | Router |
router.back() |
返回 | Router |
以上 API 的详细用法可参考 HarmonyOS 官方文档。
11. 实现要点总结
图片编辑器的核心实现要点:
- 黑色主题:使用
#1A1A1A深色背景营造沉浸式编辑体验 - 文字叠加:通过
position({x, y})将文字层定位在图片之上 - 滤镜横向滚动:
Scroll+ScrollDirection.Horizontal实现横向滑动 - 选中态反馈:
border条件渲染 +fontColor条件渲染 - @Builder 复用:工具栏按钮通过
@Builder封装
下一步优化方向:
- 集成
PhotoViewPicker实现真实图片选择 - 集成
EffectKit实现真实滤镜效果 - 集成
ImageEditor实现裁剪和旋转功能
12. 本文总结
本文详细讲解了 ImageEditPage 图片编辑器的完整实现。核心知识点包括:黑色主题设计(#1A1A1A 背景营造沉浸式编辑体验)、position 文字定位(在图片上叠加文字层)、滤镜横向滚动(Scroll + ScrollDirection.Horizontal 实现横向滑动)、@State 选中态管理(border 条件渲染 + fontColor 条件渲染)。这些技术构成了图片编辑器的完整实现基础,后续可扩展真实图片选择和滤镜处理。在下一篇文章中,我们将继续探讨 LinkEditPage 链接分享编辑器的实现。
- LinkEditPage 链接分享——PreviewCard + Toggle 开关
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
更多推荐



所有评论(0)