功能场景描述及使用场景应用开发中,用户头像时需要特定的宽高和大小限制,这个时候我们需要对用户上传的头像进行严格精准的压缩,维持在一个标准内,下面demo为例,实现将一个1.9M大小的图片,压缩成宽500,高500,且大小保持在100kb以内。
使用的核心API图像变换(ArkTS)图片编码(ArkTS)初始化图片资源到沙箱async aboutToAppear(): Promise<void> { const resourceManager = getContext(this).resourceManager const imageArray = await resourceManager.getMediaContent($r('app.media.100')); console.log("yuv_path is:" + path); let file = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); fs.write(file.fd, imageArray.buffer).then((writeLen) => { console.info("write data to file succeed and size is:" + writeLen); fs.closeSync(file); }).catch((err: BusinessError) => { console.info("write data to file failed with error message: " + err.message + ", error code: " + err.code); }); }创建pixelMap,并调用压缩方法/ // path为已获得的沙箱路径 const imageSource: image.ImageSource = image.createImageSource(path); //创建pixelMap this.pixelMap = await imageSource.createPixelMap(decodingOptions); console.log("6666661" + this.pixelMap.getPixelBytesNumber()); //指定压缩宽、高、大小 this.packingDetail(500, 500, 100)根据压缩后目标图片宽高计算缩放比 并进行缩放,调用packing方法实现第一次压缩 if (this.pixelMap) { Logger.info("zhaohao before scaling pixelmap." + this.pixelMap.getPixelBytesNumber()); let imageInfo = await this.pixelMap.getImageInfo(); let a = this.pixelMap //计算压缩比 let scaleX: number = targetWidth / imageInfo.size.width; let scaleY: number = targetHeight / imageInfo.size.height; this.pixelMap.scale(scaleX, scaleY, (err: BusinessError) => { if (err) { console.error("zhaohao Failed to scale pixelmap."); return; } else { console.log("zhaohao in scaling pixelmap." + a.getPixelBytesNumber()); } }); } let imagePackerApi = image.createImagePacker(); let packOpts: image.PackingOption = { format: "image/jpeg", quality: 100 }; imagePackerApi.packing(this.pixelMap, packOpts).then((data: ArrayBuffer) => { Logger.info("zhaohao in 100 quality data" + data.byteLength) this.compressPictures(data, targetPixelSize, 99); });调用递归算法,当压缩后的data ,小于等于压缩目标图片大小时将data写入本地沙箱并结束递归compressPictures(data?: ArrayBuffer, size?: number, quality?: number): void { if (data && size && quality) { const currentSize = data.byteLength / 1024 if (currentSize <= size || quality === 0) { console.log("finally quallity is:" + ++quality) let file = fs.openSync(path9, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); fs.write(file.fd, data).then(async (writeLen) => { console.info("write data to file succeed2 and size is:" + writeLen); fs.closeSync(file); }).catch((err: BusinessError) => { console.info("write data to file failed1 with error message: " + err.message + ", error code: " + err.code); }); return; } } if (quality) { let packOpts: image.PackingOption = { format: "image/jpeg", quality: quality } let imagePackerApi = image.createImagePacker(); imagePackerApi.packing(this.pixelMap, packOpts) .then((ret: ArrayBuffer) => { //递归算法,直到压缩到指定大小的data if (quality) { Logger.info("PACKING66666"+quality) return this.compressPictures(ret, size, quality - 1) } }).catch((err: BusinessError) => { console.log(`lbh`) return false }) } }实现效果原图压缩后目标图片注明适配的版本信息API版本:11软件版本:ALN-AL00 4.1.0.66(SP58DEVC00E66R4P1log)
使用的核心API
图像变换(ArkTS)
图片编码(ArkTS)
初始化图片资源到沙箱
创建pixelMap,并调用压缩方法
根据压缩后目标图片宽高计算缩放比 并进行缩放,调用packing方法实现第一次压缩
调用递归算法,当压缩后的data ,小于等于压缩目标图片大小时将data写入本地沙箱并结束递归
实现效果
原图
压缩后目标图片
注明适配的版本信息
API版本:
11
软件版本:
ALN-AL00 4.1.0.66(SP58DEVC00E66R4P1log)