前言——华为创新赛
大家好!我又来啦!今天青蓝程序员工具箱成功适配手机!欢迎大家在评论区提出修改建议和想要增加的功能!
言归正传!我为什么要发布这款应用,还去做PC端和移动端适配!因为创新赛啊!
2025 HarmonyOS 创新赛
就冲这个奖金,他不值得冲一把嘛!
好啦好啦,下面我就来详细介绍一下我的项目,如果大家后面很感兴趣,我后面也可以进行开源!
🎯 项目概述
青蓝程序员工具箱 是我们团队为2025 HarmonyOS创新赛精心打造的参赛作品。这是一款专为程序员设计的全能工具集应用,基于HarmonyOS原生开发,采用最新的ArkTS技术栈,实现了真正的"一次开发,多端部署"。
核心理念 :让开发者在任何设备上都能享受一致且优化的工具使用体验。
整体架构
QlzmToolBox/
├── AppScope/ # 应用全局配置
│ ├── app.json5 # 应用配置文件
│ └── resources/ # 全局资源文件
├── entry/ # 主模块
│ ├── src/main/ets/ # ArkTS源码目录
│ │ ├── component/ # 公共组件
│ │ ├── entryability/ # 应用入口能力
│ │ ├── model/ # 数据模型
│ │ ├── pages/ # 页面文件
│ │ ├── utils/ # 工具类
│ │ └── view/ # 视图组件
│ ├── src/main/resources/ # 资源文件
│ └── build-profile.json5 # 模块构建配置
├── config/ # 签名证书配置
└── hvigor/ # 构建工具配置
核心目录详解
📱 pages/ - 页面层
Index.ets- 应用主入口页面
🎨 view/ - 视图层
HomeView.ets- 首页工具展示SettingView.ets- 设置页面CompressionView.ets- 图片压缩工具JsonFormattingView.ets- JSON格式化工具TimestampConversionView.ets- 时间戳转换工具UTFChineseView.ets- UTF-8编码转换UnicodeChineseView.ets- Unicode编码转换HttpCodeTableView.ets- HTTP状态码表
🧩 component/ - 组件层
titleBar.ets- 通用标题栏组件
🔧 utils/ - 工具层
Theme.ets- 主题切换工具compressImage.ets- 图片压缩工具
多端部署
🖥️ PC端优化 - 大屏幕的无限可能 智能多列布局系统
PC端专属交互优化
- 悬浮效果 :鼠标悬停时卡片智能缩放,提供桌面级交互体验
- 键盘导航 :支持Tab键导航和快捷键操作
- 大屏信息密度 :PC端显示更多工具描述信息和功能标识
- 多窗口支持 :完美适配HarmonyOS PC的多窗口环境
我们为PC端专门设计了响应式网格布局,根据屏幕尺寸智能调整工具卡片的排列:
GridRow({
breakpoints: {
value: ['320vp', '600vp', '840vp',
'1440vp', '1600vp'],
},
gutter: {
x: this.stateIsMobile ? 8 : 12,
y: this.stateIsMobile ? 12 : 16
}
}) {
ForEach(this.stateFilteredTools, (item:
ToolModel, index: number) => {
GridCol({
span: {
xs: 6, // 移动端2列
sm: 6, // 小屏2列
md: 6, // 中屏2列
lg: 4, // 大屏3列
xl: 4, // 超大屏3列
xxl: 3 // 超超大屏4列 - PC端最优布局
}
}) {
this.EnhancedToolCard(item, index)
}
})
}
📱 多端自动适配 - 一套代码,完美体验 智能设备识别系统
private initDeviceInfo(): void {
const displayInfo = display.
getDefaultDisplaySync()
this.stateScreenWidth = px2vp
(displayInfo.width)
this.stateScreenHeight = px2vp
(displayInfo.height)
// 智能设备类型判断
if (this.stateScreenWidth < 600) {
this.stateIsMobile = true // 手机
端优化
} else if (this.stateScreenWidth < 840)
{
this.stateIsTablet = true // 平板
端优化
} else {
this.stateIsDesktop = true // PC端
优化
}
}
响应式UI组件设计
每个UI组件都根据设备类型进行精细化适配:
// 工具卡片自适应尺寸
.width(this.stateIsMobile ? 56 : 64)
.height(this.stateIsMobile ? 56 : 64)
// 字体大小智能调整
.fontSize(this.stateIsMobile ? 13 : 15)
// 间距自动优化
.padding(this.stateIsMobile ? 12 : 16)
// 阴影效果分级
.shadow({
offsetY: this.stateIsMobile ? 2 : 4,
radius: this.stateIsMobile ? 8 : 12
})
🖼️ 核心技术——智能图片压缩
📋 技术概述
图片压缩功能采用了先进的二分法压缩算法和智能质量调节机制,能够在保证图像质量的前提下,精确控制文件大小。
🔧 核心技术架构
1. 压缩引擎核心算法
实现了三层压缩策略:
// 核心压缩函数 - 智能压缩算法
export async function compressedImage(
pixelMap: image.PixelMap,
targetSize: number,
format: ImageFormatENUM
): Promise<ImageInfo> {
const imagePacker = image.createImagePacker()
// 第一阶段:初始压缩
let packingOptions: image.PackingOption = {
format: format === ImageFormatENUM.PNG ? 'image/png' : 'image/jpeg',
quality: 90 // 初始高质量
}
let imageData = await imagePacker.packing(pixelMap, packingOptions)
// 第二阶段:二分法质量调节
if (imageData.byteLength > targetSize * 1024) {
imageData = await packingImage(pixelMap, targetSize, format)
}
// 第三阶段:尺寸缩放(如果质量调节仍不满足)
if (imageData.byteLength > targetSize * 1024) {
const scaleFactor = Math.sqrt((targetSize * 1024) / imageData.byteLength)
const scaledPixelMap = await scalePixelMap(pixelMap, scaleFactor)
imageData = await packingImage(scaledPixelMap, targetSize, format)
}
return await saveImage(imageData, format)
}
// 二分法压缩核心算法
async function packingImage(
pixelMap: image.PixelMap,
targetSize: number,
format: ImageFormatENUM
): Promise<ArrayBuffer> {
const imagePacker = image.createImagePacker()
let minQuality = 10
let maxQuality = 90
let bestResult: ArrayBuffer | null = null
// 二分法迭代优化
while (minQuality <= maxQuality) {
const currentQuality = Math.floor((minQuality + maxQuality) / 2)
const packingOptions: image.PackingOption = {
format: format === ImageFormatENUM.PNG ? 'image/png' : 'image/jpeg',
quality: currentQuality
}
const result = await imagePacker.packing(pixelMap, packingOptions)
if (result.byteLength <= targetSize * 1024) {
bestResult = result
minQuality = currentQuality + 1 // 尝试更高质量
} else {
maxQuality = currentQuality - 1 // 降低质量
}
}
return bestResult || await imagePacker.packing(pixelMap, {
format: format === ImageFormatENUM.PNG ? 'image/png' : 'image/jpeg',
quality: 10
})
}
2. 批量处理与性能优化
export class compressimage {
// 批量压缩处理引擎
static async compressStart(
imageUris: string[],
format: ImageFormatENUM,
targetSize: number
): Promise<string[]> {
const compressedResults: string[] = []
// 并发处理优化
const compressionPromises = imageUris.map(async (uri) => {
try {
const fileSource = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY)
const imageSource = image.createImageSource(fileSource.fd)
const pixelMap = await imageSource.createPixelMap()
const result = await compressedImage(pixelMap, targetSize, format)
return result.imageUri
} catch (error) {
console.error(`压缩失败: ${uri}`, error)
return null
}
})
const results = await Promise.all(compressionPromises)
return results.filter(uri => uri !== null) as string[]
}
// 媒体库保存优化
static async saveImages(imageUris: string[], format: ImageFormatENUM) {
const helper = photoAccessHelper.getPhotoAccessHelper(getContext())
for (const uri of imageUris) {
try {
const asset = await helper.createAsset(
photoAccessHelper.PhotoType.IMAGE,
`compressed_${Date.now()}.${format.toLowerCase()}`
)
const fd = await helper.openAsset(asset, 'w')
const sourceFile = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY)
await fileIo.copyFile(sourceFile.fd, fd)
await helper.closeAsset(asset, fd)
await fileIo.close(sourceFile)
} catch (error) {
console.error('保存失败:', error)
}
}
}
}
🖥️ PC端专属优化
// PC端拖拽上传支持
.allowDrop([
uniformTypeDescriptor.UniformDataType.IMAGE,
uniformTypeDescriptor.UniformDataType.OPENHARMONY_PIXEL_MAP
])
.onDrop(async (dragEvent?: DragEvent) => {
const data = dragEvent?.getData().getRecords() as unifiedDataChannel.Image[]
// 批量处理拖拽的图片
for (let index = 0; index < data.length; index++) {
this.ImageUriArr.push(data[index].imageUri)
}
// 启动压缩引擎
this.afterCompressImage = await compressimage.compressStart(
this.ImageUriArr, this.ImageFormat, this.MaxFileStorage
)
})
📊 性能指标
| 技术指标 | 数值 | 说明 |
|---|---|---|
| 压缩精度 | ±5KB | 目标大小控制精度 |
| 支持格式 | PNG/JPEG | 主流图像格式全覆盖 |
| 批量处理 | 最多9张 | 单次批量压缩上限 |
| 压缩范围 | 10KB-1000KB | 灵活的大小控制范围 |
| 质量范围 | 10%-90% | 二分法动态质量调节 |
| 处理速度 | 并发优化 | Promise.all并发处理 |
🔄 压缩流程图
📷 原始图片输入
↓
🎯 目标大小设置 (10-1000KB)
↓
🔧 格式选择 (PNG/JPEG)
↓
⚡ 三阶段压缩算法
├─ 阶段1: 高质量初压 (90%)
├─ 阶段2: 二分法优化 (10%-90%)
└─ 阶段3: 智能缩放 (保比例)
↓
✅ 精确大小控制 (±5KB)
↓
💾 媒体库自动保存
↓
🎉 压缩完成通知
后续
后续大家要是对应用的其他技术感兴趣在评论区中留言,我会继续分享或者将我的项目进行开源,供大家学习~
接下来我将继续丰富和优化应用,对分享服务的碰一碰和多设备手势识别拖拽分享有点兴趣,可能会在后续的版本上线哦!大家可以持续关注一下!
总结
我叫云杰!我来自青蓝逐码!
如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯,甚至你想要做出一款属于自己的应用!欢迎在评论区留言或者私信,可以加入技术交流群。