第14章_HarmonyOs开发图解 图像
2026/7/28 19:18:30 网站建设 项目流程

第14章 HarmonyOs开发图解 图像

HarmonyOS 学习系统 | 阶段三:高级深耕期


学习目标

序号能力
1掌握图像解码(ImageSource)与编码(ImagePacker)的完整流程
2能够使用 PixelMap 进行像素级操作
3掌握图像缩放、裁剪、EXIF 信息读取等常用功能

核心图解

内容讲解

14.1 图像处理概述

HarmonyOS 的图像处理模块围绕三个核心类展开:ImageSource(图像源/解码器)、PixelMap(位图/像素容器)、ImagePacker(图像编码器)。这三个类组成了"读取 -> 处理 -> 保存"的完整图像处理管线。

生活化类比:PixelMap 就像"乐高底板"

图像解码就像拆快递包装:JPEG/PNG 图片就像被打包好的快递,里面是像素数据但被压缩了。解码(Decode)就是拆开包装,把像素数据整齐地摆放在一块"乐高底板"上——这块底板就是PixelMap,每个格子就是一个像素点的颜色值。编码(Encode)则反过来,把底板上的像素重新打包压缩成图片格式。

14.2 图像解码

ImageSource 负责从各种来源(文件流、资源文件、字节数组)读取图片并解码为 PixelMap。

// 从资源文件解码图片InputStreamis=getResourceManager().getResource(MediaTable.INPUT);ImageSourceimageSource=ImageSource.create(is,newSourceOptions());PixelMappixelMap=imageSource.createPixelmap(newDecodingOptions());imageDecode.setPixelMap(pixelMap);// 带缩放的解码(避免 OOM)DecodingOptionsopts=newDecodingOptions();opts.desiredSize=newSize(400,300);// 缩放到 400x300PixelMapscaledMap=imageSource.createPixelmap(opts);

14.3 图像编码与保存

ImagePacker 负责将 PixelMap 编码为指定格式的图片文件并保存。

// 编码图片保存为 JPEGImagePackerimagePacker=ImagePacker.create();imagePacker.initializePacking(newFile("path/to/output.jpg"),newImagePacker.PackingOptions("image/jpeg",90)// JPEG格式,质量90);imagePacker.addImage(pixelMap);imagePacker.finalizePacking();// 释放资源pixelMap.release();imageSource.release();

14.4 像素级操作

PixelMap 支持对单个像素的读写操作,可以用于图像特效处理。

// 读取指定位置像素intcolor=pixelMap.readPixel(newPosition(100,200));// 写入指定位置像素pixelMap.writePixel(newPosition(100,200),0xFFFF0000);// 红色// 从颜色数组创建 PixelMapint[]colors=newint[width*height];// ... 填充颜色数据PixelMapcreatedMap=PixelMap.create(colors,width,height,PixelFormat.ARGB_8888);

14.5 EXIF 信息读取

通过 ExifUtils 可以读取照片中嵌入的 GPS 坐标、拍摄时间等元数据。

// 获取照片 GPS 坐标double[]latLong=ExifUtils.getLatLong(imageSource);if(latLong!=null){HiLog.info(TAG,"纬度: "+latLong[0]+", 经度: "+latLong[1]);}

代码速查卡

API功能示例
ImageSource.create(stream, opts)从输入流创建图像源ImageSource.create(is, new SourceOptions())
createPixelmap(opts)解码为 PixelMapimageSource.createPixelmap(opts)
PixelMap.create(colors, w, h, fmt)从颜色数组创建位图PixelMap.create(colors, w, h, ARGB_8888)
readPixel(position)读取指定位置像素pixelMap.readPixel(new Position(100,200))
writePixel(position, color)写入指定位置像素pixelMap.writePixel(pos, 0xFFFF0000)
ImagePacker.create()创建图像编码器ImagePacker.create()
ExifUtils.getLatLong()获取照片 GPS 坐标ExifUtils.getLatLong(imageSource)
pixelMap.release()释放 Native 资源pixelMap.release()

与 Android/iOS 对比

特性HarmonyOSAndroidiOS
位图类PixelMapBitmapCGImage / UIImage
解码ImageSourceBitmapFactoryImageIO
编码ImagePackerBitmap.compress()UIImageJPEGRepresentation()
像素操作readPixel / writePixelgetPixel() / setPixel()CGContext 绘制
EXIF 读取ExifUtilsExifInterfaceCGImageDestination
缩放解码DecodingOptions.desiredSizeBitmapFactory.Options.inSampleSizeImageIO 缩略图

⚠️ 踩坑回忆录

OOM!为什么图片一加载就崩溃?

一张 4000x3000 的图片解码后 PixelMap 占用约 48MB 内存(4000 x 3000 x 4 字节/像素)。我曾在列表页同时加载了 20 张大图,直接 OOM 崩溃。解决办法:缩放解码!在DecodingOptions中设置desiredSize,按显示尺寸缩放后再加载。列表页缩略图 200x200 就够了,详情页才加载原图。

还有一个坑:PixelMapImageSource用完必须调release(),它们持有 Native 资源(C/C++ 层内存),Java 的 GC 管不了。我曾在循环里创建了几十个 PixelMap 不释放,最后系统直接杀掉了我的进程。


必做实操任务

序号任务难度
1实现图片解码并在 Image 组件上显示
2实现图片缩放裁剪(设置 DecodingOptions 的 desiredSize 和 desiredRegion)
3读取照片的 EXIF 信息(经纬度、海拔)并在界面上展示
4实现图片格式转换(PNG -> JPEG)
5实现一个简单的图片浏览器,支持缩放和滑动浏览

学习检查清单

  • 能说出 ImageSource、PixelMap、ImagePacker 三者的关系
  • 能实现图片解码并在 UI 上显示
  • 能使用 DecodingOptions 实现缩放解码避免 OOM
  • 能使用 ImagePacker 将 PixelMap 保存为 JPEG/PNG
  • 能使用 readPixel/writePixel 进行像素级操作
  • 能读取照片的 EXIF GPS 信息
  • 知道为什么 PixelMap 和 ImageSource 必须手动 release
  • 理解图片分辨率与内存占用的关系

进阶方向

  • 学习图像变换(旋转、翻转、裁剪)API 的使用
  • 探索 PixelMap 的图像特效处理(灰度、模糊、亮度调节)
  • 结合第 21 章 OCR 能力,实现拍照识别文字的完整流程
    和 ImageSource 必须手动 release
  • 理解图片分辨率与内存占用的关系

进阶方向

  • 学习图像变换(旋转、翻转、裁剪)API 的使用
  • 探索 PixelMap 的图像特效处理(灰度、模糊、亮度调节)
  • 结合第 21 章 OCR 能力,实现拍照识别文字的完整流程

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询