HarmonyOS 鸿蒙Next 加过水印后的图片内存较大问题
HarmonyOS 鸿蒙Next 加过水印后的图片内存较大问题
通过 canvas和OffScreenContext为图片添加水印,添加文字水印后的图片内存较大,如何在不修改原画质的技术上,降低添加水印后的图片大小。 这是我当前的代码: 添加水印:
/**
* 获取图片信息,包含宽、高、类型
* [@param](/user/param) params
* [@returns](/user/returns)
*/
async function getImageInfo(params: GetImageInfoParams): Promise<ImageInfo> {
const buffer = await this.getBuffer(params.src)
console.log("vvvv: getImageInfo - buffer - ", buffer?.byteLength)
let type: FileType = FileType.UNKNOWN
if (buffer) {
type = this.getFileTypeByBuffer(buffer)
}
const imageSource: image.ImageSource = image.createImageSource(buffer);
const decodingOptions: image.DecodingOptions = {
editable: true,
desiredPixelFormat: 3,
}
const pixelMap: PixelMap = await imageSource.createPixelMap(decodingOptions)
const info = await pixelMap.getImageInfo()
const width = info.size.width
const height = info.size.height
return {
width,
height,
type
}
}
async function getPixelMap(url: string, imageInfo: ImageInfo): Promise<PixelMap> {
const buffer = await this.getBuffer(url)
console.log("vvvv: getPixelMap - buffer-", buffer?.byteLength)
const imageSource: image.ImageSource = image.createImageSource(buffer);
let opts: image.DecodingOptions = {
editable: true,
desiredSize: {
height: imageInfo.height,
width: imageInfo.width
}
};
const pixelMap = await imageSource.createPixelMap(opts)
return pixelMap
}
/**
* 将buffer内容写入沙箱中
* [@param](/user/param) buffer buffer内容
* [@param](/user/param) name 文件名
* [@param](/user/param) isTemporary 是否临时保存
* [@returns](/user/returns)
*/
async function writeBufferToFile(buffer: ArrayBuffer, name: string, isTemporary: boolean = true) {
const filesDir: string = isTemporary ? getContext(ImageCreator.mContext).tempDir : getContext(ImageCreator.mContext)
.filesDir
const foldPath = `${filesDir}/${ImageCreator.storePath}`
if (!fs.accessSync(foldPath)) {
fs.mkdirSync(foldPath)
}
let filePath = `${foldPath}/${name}`
let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
fs.writeSync(file.fd, buffer);
fs.fsyncSync(file.fd);
fs.closeSync(file);
return filePath
}
/**
* 为图片添加水印
* [@param](/user/param) sourcePath 图片地址
*/
async function imageWatermarkText(sourcePath) {
const imageInfo: ImageInfo = await getImageInfo({ src: sourcePath })
const imgWidth = imageInfo.width
const imgHeight = imageInfo.height
const type = imageInfo.type
let textBaseline: CanvasTextBaseline = "middle";
let textAlign: CanvasTextAlign = "center";
let fillTextX: number = 0;
let fillTextY: number = 0;
const pixelMap = await getPixelMap(sourcePath, imageInfo)
let offScreenCanvas = new OffscreenCanvas(imgWidth, imgHeight);
let OffScreenContext = offScreenCanvas.getContext("2d");
let imageScale = offScreenCanvas.width / display.getDefaultDisplaySync().width;
OffScreenContext.drawImage(pixelMap, 0, 0, offScreenCanvas.width, offScreenCanvas.height);
OffScreenContext.textAlign = "center";
OffScreenContext.textBaseline = "middle";
OffScreenContext.font = 28 * imageScale + "vp";
OffScreenContext.fillStyle = "#ff0000";
OffScreenContext.globalAlpha = 1;
OffScreenContext.fillText("这是水印", 0, 0);
// 获取加水印后图片ArrayBuffer,并存到内存种
const newPixelMap = OffScreenContext.getPixelMap(0, 0, offScreenCanvas.width, offScreenCanvas.height)
const imagePacker = image.createImagePacker();
const imageBuffer = await imagePacker.packing(newPixelMap, {
format: `image/${type}`,
quality: 100
});
console.log("vvvv: imageBuffer-", imageBuffer.byteLength)
// 存到内存中,并返回内存地址
const fileName = `watermark_${Date.now()}.${type}`
const filePath = await writeBufferToFile(imageBuffer, fileName)
const LightResourcePath = ResourceProviderProxy.saveToCommonLightResourceFile(filePath, FILE_TYPE.IMAGE)
const result: JSONObject = {
tempFilePath: LightResourcePath
}
}
原始图片的ArrayBuffer获取:
async function getBuffer(localFilePath: string): Promise<ArrayBuffer> {
let srcFile = fs.openSync(localFilePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
const bufferSize = await this.getFileBufferSize(localFilePath)
let arrayBuffer = new ArrayBuffer(bufferSize)
const readLen = await fs.read(srcFile.fd, arrayBuffer)
arrayBuffer = arrayBuffer.slice(0, readLen);
this.saveBufferToAlbum(arrayBuffer)
fs.closeSync(srcFile)
return arrayBuffer
}
更多关于HarmonyOS 鸿蒙Next 加过水印后的图片内存较大问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS 鸿蒙Next 加过水印后的图片内存较大问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
针对HarmonyOS鸿蒙Next系统中加过水印后的图片内存较大的问题,这通常是由于水印处理过程中增加了图像数据的复杂度,导致图片文件大小增加。具体原因分析如下:
-
水印信息嵌入:水印的加入会改变原图像的像素信息,尤其当水印为彩色或包含半透明效果时,每个像素点的RGB或RGBA值都可能发生变化,导致整体数据量增加。
-
图像质量:为了保持水印的清晰度,可能会提升图像的分辨率或质量,这同样会增加图像的文件大小。
-
压缩算法:在加入水印后,如果选择的图像压缩算法不够高效,或者为了保持水印的可见性而减少压缩比,也会导致图片内存占用增大。
-
元数据:加入水印可能同时增加了图像的元数据,如版权信息、水印创建时间等,这些也会略微增加文件大小。
解决此问题的一种方法是优化水印处理算法,减少不必要的图像数据变化,同时选择合适的压缩算法和参数,以在保持水印可见性的同时减少文件大小。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html