当前位置: 首页 > news >正文

实战:HarmonyOS 中 HEIF 图像开发全流程(转码篇 兼容场景)

紧接着上篇文章。我们继续HarmonyOS 中 HEIF 图像开发全流程。这篇主要记录如何进行图转码。

实战 :HEIF 图像自定义处理(进阶场景)

这里还是说一下环境吧。

环境要求

  • HarmonyOS 版本:需基于 HarmonyOS 5.0 及以上(HEIF 解码性能优化、硬件编码支持均从 5.0 开始)。
  • 开发工具:DevEco Studio 5.0 及以上(确保 ArkUI 组件与 Image Kit API 兼容)。
  • 测试设备:搭载 HarmonyOS 5.x 的真机或模拟器(部分硬件解码能力需真机支持)。
  • 图像资源:准备 1-2 张 HEIF 格式图片(后缀通常为 .heif 或 .heic,可通过手机拍摄或在线工具转换获取),并放入项目的 main_pages/images 目录下(需在 module.json5 中配置资源路径)。

部分旧应用或第三方接口可能仅支持 JPEG 格式,此时需将 HEIF 转码为 JPEG 并保存到本地。本实战将实现 “加载 HEIF 图片→转码为 JPEG→保存到应用沙箱目录” 的全流程。

1. 场景需求

加载 scenery.heic 图片,将其转码为质量 95 的 JPEG 格式,保存到应用的沙箱目录(/data/storage/el2/base/haps/应用包名/files/),并输出保存路径。

2. 操作步骤

步骤 1:申请文件读写权限

转码后需保存文件到本地,需在 module.json5 中申请 ohos.permission.WRITE_USER_STORAGE 权限:

{"module": {"abilities": [{"permissions": [{"name": "ohos.permission.WRITE_USER_STORAGE","reason": "需要保存转码后的JPEG图片","usedScene": { "when": "always" }}]}]}
}

步骤 2:编写转码代码

通过 image.createImagePacker() 创建编码器,配置 JPEG 编码参数(质量、是否保留 EXIF 信息),最后将转码后的文件保存到沙箱目录:

import image from '@ohos.multimedia.image';
import fs from '@ohos.file.fs';
import { Column, Button, Text, FlexAlign, AlertDialog } from '@ohos/ui';
import permission from '@ohos.permission';@Entry
@Component
struct HEIFTranscodePage {private jpegSavePath: string = '';  // 存储 JPEG 保存路径// 申请文件读写权限async requestStoragePermission() {const result = await permission.requestPermissions(['ohos.permission.WRITE_USER_STORAGE']);return result[0].grantStatus === permission.GrantStatus.PERMISSION_GRANTED;}// 核心方法:HEIF 转码为 JPEG 并保存async transcodeHEIFToJPEG() {// 1. 先申请权限const hasPermission = await this.requestStoragePermission();if (!hasPermission) {AlertDialog.show({ message: '请授予文件读写权限,否则无法保存图片' });return;}try {// 2. 创建 HEIF 图像源const imageSource = image.createImageSource($r('app.image.scenery').uri);// 3. 创建图像编码器(用于转码)const imagePacker = image.createImagePacker();// 4. 配置 JPEG 编码选项const packOpts: image.PackingOption = {format: 'image/jpeg',          // 目标格式为 JPEGquality: 95,                   // 质量(0-100,95 为高质量)needsPackProperties: true      // 保留原图片的 EXIF 信息(如拍摄时间、分辨率)};// 5. 定义 JPEG 保存路径(应用沙箱的 files 目录)const appFilesDir = fs.getAppFilesDir();  // 获取应用沙箱目录this.jpegSavePath = `${appFilesDir}/transcoded_scenery.jpg`;// 6. 打开文件流,准备保存const file = await fs.open(this.jpegSavePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);// 7. 执行转码并保存到文件await imagePacker.packToFile(imageSource, file.fd, packOpts);// 8. 关闭文件流、释放资源await fs.close(file.fd);imagePacker.release();imageSource.release();// 9. 提示转码成功并输出路径AlertDialog.show({title: '转码成功',message: `JPEG 保存路径:${this.jpegSavePath}`,confirm: { text: '确定' }});} catch (err) {console.error('HEIF 转码失败:', err);AlertDialog.show({ message: '转码失败,请检查图片格式或权限' });}}build() {Column({ space: 30, alignItems: FlexAlign.Center }) {Text('HEIF 转码为 JPEG').fontSize(24).fontWeight(FontWeight.Bold);// 触发转码的按钮Button('开始 HEIF 转码为 JPEG').width(300).height(50).fontSize(16).onClick(() => {this.transcodeHEIFToJPEG();});// 显示保存路径if (this.jpegSavePath) {Text(`JPEG 已保存至:\n${this.jpegSavePath}`).fontSize(14).width('90%').textAlign(TextAlign.Center);}}.padding(20).width('100%').height('100%');}
}

步骤 3:验证转码结果

  1. 运行应用,点击 “开始 HEIF 转码为 JPEG” 按钮,授予权限后,会弹出 “转码成功” 提示。
  2. 通过 DevEco Studio 的 “Device File Explorer”(设备文件浏览器),导航到提示的 jpegSavePath 目录,下载 transcoded_scenery.jpg 到本地,用图片查看器确认:
    • 格式为 JPEG(后缀 .jpg)。
    • 图像质量无明显损失(因质量设为 95)。
    • EXIF 信息保留(可通过图片属性查看拍摄时间等)。

3. 关键注意点

  • 权限申请:HarmonyOS 6.0 及以上需动态申请 WRITE_USER_STORAGE 权限,静态配置后需通过 permission.requestPermissions() 触发用户授权。
  • 编码质量quality 设为 95 时,可在 “体积” 与 “质量” 间取得平衡;若需更小体积,可降至 80-90。
  • 文件覆盖:若目标路径已存在同名文件,需先删除或重命名,避免转码失败(可通过 fs.access() 判断文件是否存在)。

文章转载自:

http://QzwDgj4v.qnbzs.cn
http://F8EHE7MH.qnbzs.cn
http://hRMEbEmr.qnbzs.cn
http://IzHBIAMS.qnbzs.cn
http://vevGgAsB.qnbzs.cn
http://nwZnxmdg.qnbzs.cn
http://CEtHXwHH.qnbzs.cn
http://IfWW6oYJ.qnbzs.cn
http://zoqn8Xy0.qnbzs.cn
http://Tgo0QLGY.qnbzs.cn
http://b65ox75u.qnbzs.cn
http://AaSCQyco.qnbzs.cn
http://tUPAxiyV.qnbzs.cn
http://VyIUMg5m.qnbzs.cn
http://bj5xbMeb.qnbzs.cn
http://B6Dcgu5N.qnbzs.cn
http://ZJS2gciJ.qnbzs.cn
http://FAdEcBeq.qnbzs.cn
http://nW7eaTki.qnbzs.cn
http://nwbbzPlY.qnbzs.cn
http://ramskdUw.qnbzs.cn
http://jjL3gidY.qnbzs.cn
http://bwIlEZOJ.qnbzs.cn
http://7QOdikyI.qnbzs.cn
http://YAGGhD3J.qnbzs.cn
http://D0zyhCH1.qnbzs.cn
http://7Xfh7Zc4.qnbzs.cn
http://YQ8wq3GW.qnbzs.cn
http://ef4KDRto.qnbzs.cn
http://XRbLOtOE.qnbzs.cn
http://www.dtcms.com/a/376925.html

相关文章:

  • 融智学生活方式DBA 小生境融智:身心健康就是美,抓住刚需就是赢
  • 【高级】系统架构师 | 2025年上半年综合真题DAY3
  • CentOS 7部署Zabbix5.0
  • [rStar] 策略与奖励大语言模型
  • 使用命令centos把普通用户设置为管理员
  • 机器学习实操项目03——Scikit-learn介绍及简单分类案例
  • 了解网站安全监测系统的重要性
  • 图像尺寸和CMOS的关联
  • 视频转webp批量处理工具哪个好?这里有答案
  • cuda-NCCL笔记(3)-- 分布式训练LeNet
  • Android Studio开发环境配置
  • 【springboot+vue3】博客论坛管理系统(源码+文档+调试+基础修改+答疑)
  • 中台的万象
  • 从Grok 4多智能体协同到RAG范式革命:2025年AI工作流的技术重构
  • pythonFlask 使用 SQLAlchemy 的连接池
  • 【系统架构设计(25)】Web应用服务器与现代架构
  • minikube 的 kubernetes 入门教程-Nginx Proxy Manager
  • ‌Git Bisect 二分查找定位错误总结
  • 基于大数据挖掘的药品不良反应知识整合与利用研究
  • Git 命令教程
  • springboot synchronized 本地锁入门与实战
  • 【竞赛系列】机器学习实操项目08——全球城市计算AI挑战赛(数据可视化分析)
  • Nginx 实战系列(八)—— Nginx SSL/TLS 配置指南
  • Python函数详解及*args、**kwargs用法
  • 零基础3个月上岸[特殊字符]自学数据分析路线
  • Java多线程(一)
  • pyspark读取hive表中数据后进行lgb建模
  • LeetCode 热题 42.接雨水(双指针写法)
  • 带你走进vue的响应式底层
  • 【算法--链表】117.填充每个节点的下一个右侧节点指针Ⅱ--通俗讲解