import { image } from "@kit.ImageKit";
import { resourceManager } from '@kit.LocalizationKit';
import { ContextUtil } from "../context/ContextUtil";
import { util } from "@kit.ArkTS";
export class ImageUtil {
/**
* 创建ImageSource实例
* @param {string | number | ArrayBuffer | resourceManager.RawFileDescriptor} src 图片数据源
* {string} 当前应用沙箱的图片路径。
* {number} 文件描述符fd。
* {ArrayBuffer} 图像缓冲区数组。
* {resourceManager.RawFileDescriptor} rawfile图片文件所在hap的descriptor信息。
* @param {image.SourceOptions} options 图片属性(像素密度、像素格式、图片尺寸等)。
* @returns {image.ImageSource} 返回ImageSource实例。
*/
private static createImageSource(src: string | number | ArrayBuffer | resourceManager.RawFileDescriptor, options?: image.SourceOptions): image.ImageSource {
if (typeof src === 'string') {
if (options) return image.createImageSource(src, options);
return image.createImageSource(src);
} else if (typeof src === 'number') {
if (options) return image.createImageSource(src, options);
return image.createImageSource(src);
} else if (src instanceof ArrayBuffer) {
if (options) return image.createImageSource(src, options);
return image.createImageSource(src);
} else {
if (options) return image.createImageSource(src, options);
return image.createImageSource(src);
}
}
/**
* 用户获取resource目录下的media中的图片PixelMap
* @param {Resource} resource Resource资源信息
* @param {image.DecodingOptions} options 图像解码参数
* @returns {Promise<image.PixelMap>} 返回图像的PixelMap对象
*/
static async getPixelMapFromResource(resource: Resource, options?: image.DecodingOptions): Promise<image.PixelMap> {
const resManager: resourceManager.ResourceManager = ContextUtil.getUIAbilityCtx().resourceManager;
const uint8Array: Uint8Array = resManager.getMediaContentSync(resource.id);
return await ImageUtil.createImageSource(uint8Array.buffer).createPixelMap(options);
}
/**
* 图片打包
* @param {image.PixelMap} source 图像的PixelMap对象
* @param {image.PackingOption} options 图像打包参数
* @returns {Promise<ArrayBuffer>} ArrayBuffer 返回图像数据
*/
static packingFromPixelMap(source: image.PixelMap, options: image.PackingOption): Promise<ArrayBuffer> {
const imagePacker: image.ImagePacker = image.createImagePacker();
return imagePacker.packToData(source, options).finally(() => {
imagePacker.release();
});
}
/**
* PixelMap转base64
* @param {image.PixelMap} pixelMap 图像的PixelMap对象
* @param {string} format 目标格式(默认png,当前只支持jpg、webp和png)
* @returns {Promise<string>} 返回图像的base64字符串
*/
static async pixelMapToBase64(pixelMap: image.PixelMap, format: string = 'image/png'): Promise<string> {
const options: image.PackingOption = { format: format, quality: 100 };
const arrayBuffer: ArrayBuffer = await ImageUtil.packingFromPixelMap(pixelMap, options);
const base64Helper: util.Base64Helper = new util.Base64Helper();
const BASE64_DATA_HEAD: string = `data:${format};base64,`;
let base64Str: string = base64Helper.encodeToStringSync(new Uint8Array(arrayBuffer));
if (!base64Str.startsWith(BASE64_DATA_HEAD)) {
base64Str = BASE64_DATA_HEAD + base64Str;
}
return base64Str;
}
/**
* base64转PixelMap
* @param {string} base64 图片base64字符串
* @returns {Promise<image.PixelMap>} 返回图像的PixelMap对象
*/
static async base64ToPixelMap(base64: string): Promise<image.PixelMap> {
const reg: RegExp = new RegExp('data:image/\\w+;base64,');
const base64Str: string = base64.replace(reg, '');
const base64Helper: util.Base64Helper = new util.Base64Helper();
const uint8Array: Uint8Array = base64Helper.decodeSync(base64Str);
let imageSource: image.ImageSource = image.createImageSource(uint8Array.buffer);
let options: image.DecodingOptions = { editable: false };
return imageSource.createPixelMap(options);
}
/**
* 生成压缩图片
* @param {Resource | image.PixelMap} src 未压缩的Resource图片或PixelMap对象
* @param {number} maxSize 图像大小限制,默认不超过2MB
* @returns {Promise<image.PixelMap>} 返回压缩后的PixelMap对象
*/
static async createCompressedPixelMap(src: Resource | image.PixelMap, maxSize: number = 2 * 1024 * 1024): Promise<image.PixelMap> {
if (typeof (src as Resource).id == 'number') {
src = await ImageUtil.getPixelMapFromResource((src as Resource));
}
const pixelMap = src as image.PixelMap;
let pixelBytes = pixelMap.getPixelBytesNumber(); // 总字节数
while (pixelBytes > maxSize) {
await pixelMap.scale(0.7, 0.7, image.AntiAliasingLevel.LOW);
pixelBytes = pixelMap.getPixelBytesNumber();
}
return pixelMap;
}
}