华为HarmonyOS创新赛——青蓝程序员工具箱

150 阅读6分钟

前言——华为创新赛

大家好!我又来啦!今天青蓝程序员工具箱成功适配手机!欢迎大家在评论区提出修改建议和想要增加的功能!

image.png

言归正传!我为什么要发布这款应用,还去做PC端和移动端适配!因为创新赛啊!

2025 HarmonyOS 创新赛

image.png

就冲这个奖金,他不值得冲一把嘛!

image.png

好啦好啦,下面我就来详细介绍一下我的项目,如果大家后面很感兴趣,我后面也可以进行开源

🎯 项目概述

青蓝程序员工具箱 是我们团队为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端优化 - 大屏幕的无限可能 智能多列布局系统

image.png PC端专属交互优化

  • 悬浮效果 :鼠标悬停时卡片智能缩放,提供桌面级交互体验
  • 键盘导航 :支持Tab键导航和快捷键操作
  • 大屏信息密度 :PC端显示更多工具描述信息和功能标识
  • 多窗口支持 :完美适配HarmonyOS PC的多窗口环境

我们为PC端专门设计了响应式网格布局,根据屏幕尺寸智能调整工具卡片的排列:

GridRow({
  breakpoints: {
    value: ['320vp''600vp''840vp', 
    '1440vp''1600vp'],
  },
  gutter: { 
    xthis.stateIsMobile ? 8 : 12, 
    ythis.stateIsMobile ? 12 : 16 
  }
}) {
  ForEach(this.stateFilteredTools(item: 
  ToolModel, index: number) => {
    GridCol({
      span: {
        xs6,  // 移动端2列
        sm6,  // 小屏2列  
        md6,  // 中屏2列
        lg4,  // 大屏3列
        xl4,  // 超大屏3列
        xxl3  // 超超大屏4列 - PC端最优布局
      }
    }) {
      this.EnhancedToolCard(item, index)
    }
  })
}

📱 多端自动适配 - 一套代码,完美体验 智能设备识别系统

image.png

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({
  offsetYthis.stateIsMobile ? 2 : 4,
  radiusthis.stateIsMobile ? 8 : 12
})

🖼️ 核心技术——智能图片压缩

image.png

📋 技术概述

图片压缩功能采用了先进的二分法压缩算法智能质量调节机制,能够在保证图像质量的前提下,精确控制文件大小。

🔧 核心技术架构

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. 批量处理与性能优化

PixPin_2025-08-04_21-32-33.gif

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端专属优化

PixPin_2025-08-04_21-31-02.gif

// 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)
    ↓
💾 媒体库自动保存
    ↓
🎉 压缩完成通知

后续

后续大家要是对应用的其他技术感兴趣在评论区中留言,我会继续分享或者将我的项目进行开源,供大家学习~

接下来我将继续丰富和优化应用,对分享服务的碰一碰和多设备手势识别拖拽分享有点兴趣,可能会在后续的版本上线哦!大家可以持续关注一下!

总结

我叫云杰!我来自青蓝逐码!

关于青蓝逐码组织

如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯甚至你想要做出一款属于自己的应用!欢迎在评论区留言或者私信,可以加入技术交流群。

image.png