【背景知识】
PixelMap是图像解码后的一种无压缩位图格式,主要用于图像显示或进一步处理。这种格式可以有效地存储图像的原始数据,使其可以方便地进行图像变换,如裁剪、缩放、偏移、旋转、翻转、设置透明度等。
【解决方案】
使用HarmonyOS的PixelMap进行图像变换主要涉及以下几个步骤:
- 图片解码:首先,需要加载并解码图片文件,这将返回一个PixelMap对象,该对象用于后续的图像操作。
- 获取图片信息:在进行变换之前,需要获取图片的一些基本信息,如宽度和高度。可以通过调用
getImageInfo()
方法来获取这些信息。
// 获取图片大小
pixelMap.getImageInfo().then(info => {
console.info('info.width = ' + info.size.width);
console.info('info.height = ' + info.size.height);
}).catch(err => {
console.error("Failed to obtain the image pixel map information. And the error is: " + err);
});
- 执行图像变换:包括裁剪、缩放、旋转、翻转、透明度修改等操作。这些操作通常通过PixelMap提供的方法来实现。
@Entry
@Component
struct Index {
@State imagePixelMap: PixelMap | undefined = undefined
@State edit: boolean = false
aboutToAppear(): void {
}
@Builder
buttonModel($$: GeneratedTypeLiteralInterface_1) {
Button($$.textContent)
.fontSize(14)
.height(30)
.width(60)
.borderRadius(10)
.backgroundColor('#E8A027')
.onClick(() => {
$$.action
this.edit = true
})
}
async get_pixelmap() {
const context = getContext(this)
const resourceMgr = context.resourceManager
const fileData = await resourceMgr.getMediaContent($r('app.media.testImg'))
const buffer = fileData.buffer
const imageSource = image.createImageSource(buffer)
const pixelMap = await imageSource.createPixelMap()
return pixelMap
}
// 对pixelMap进行裁剪
async crop_image() {
let pixelMap = await this.get_pixelmap()
pixelMap.crop({ x: 0, y: 0, size: { height: 300, width: 300 } })
this.imagePixelMap = pixelMap
}
// 对pixelMap进行缩放
async scale_image() {
let pixelMap = await this.get_pixelmap()
pixelMap.scale(0.5, 0.5)
this.imagePixelMap = pixelMap
}
// 对pixelMap进行偏移
async translate_image() {
let pixelMap = await this.get_pixelmap()
pixelMap.translate(100, 100);
this.imagePixelMap = pixelMap
}
// 对pixelMap进行旋转
async rotate_image() {
let pixelMap = await this.get_pixelmap()
pixelMap.rotate(90);
this.imagePixelMap = pixelMap
}
// 对pixelMap进行翻转
// 垂直翻转
async flip_image() {
let pixelMap = await this.get_pixelmap()
pixelMap.flip(false, true);
this.imagePixelMap = pixelMap
}
// 对pixelMap进行透明度调整
async opacity_image() {
let pixelMap = await this.get_pixelmap()
pixelMap.opacity(0.5);
this.imagePixelMap = pixelMap
}
}
【常见FAQ】
Q:获取网络图片的PixelMap,如何进行center crop?
A:获取到PixelMap后,可调用crop方法,根据输入的尺寸对图片进行裁剪。
async function Crop() {
let region: image.Region = { x: 0, y: 0, size: { height: 100, width: 100 } };
if (pixelMap != undefined) {
pixelMap.crop(region, (err: BusinessError) => {
if (err) {
console.error(`Failed to crop pixelmap. code is ${err.code}, message is ${err.message}`);
return;
} else {
console.info("Succeeded in cropping pixelmap.");
}
})
}
}
Q:HarmonyOS系统上,有时候竖屏图片加载时会显示成横屏。
A:有些设备会给图片加一个旋转属性,HarmonyOS相册组件是Image的api无法读取此属性,想要规避这个问题可以通过getImageProperty
获取旋转信息,判断图片是否要旋转,如果需要旋转可以通过.rotate(90)进行调整。
Q:图片缩放算法函数scaleSync(x: number, y: number),x和y大概0.2左右(图片长宽尺寸缩小0.046),最终图片byte值为原始图的0.0558倍,这个结果不符合预期,预期也是0.046倍。
A:scaleSync影响的是pixelmap的比例大小,缩放后编码的数据会变小,但是不一定成比列。