HarmonyOS 鸿蒙Next中使用图片当水印
HarmonyOS 鸿蒙Next中使用图片当水印 如何把文本水印换成图片效果跟下面图片一样,求大佬指点
更多关于HarmonyOS 鸿蒙Next中使用图片当水印的实战教程也可以访问 https://www.itying.com/category-93-b0.html
【背景知识】
应用背景水印是综合办公类应用中的高频使用场景之一,当用户查看的内容涉及内部敏感信息时,应用在背景自动生成水印,保证信息安全性。 应用背景水印示例基于Canvas绘制水印图案,并通过设置浮层叠加在背景上,实现背景水印功能。
【解决方案】
-
在Canvas组件上绘制水印图案。
@Builder waterMark() { Canvas(this.context) .onReady(() => { ... // 设置水印绘制参数 while (posY < this.context.height) { ... // 设置每行位置参数 posY = WATERMARK_HEIGHT * row; for (let i = 0; i <= Math.ceil(this.context.width / WATERMARK_WIDTH); i++) { ... // 绘制该行水印 } row++; } }); }
-
设置浮层属性,将绘制好的水印图案叠加到背景组件上。
Column() .width('100%') .layoutWeight(1) .overlay(this.waterMark());
更多关于HarmonyOS 鸿蒙Next中使用图片当水印的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
1.关于鸿蒙水印的添加楼主可以参考下面的实现: Canvas提供画布组件,用于自定义绘制图形。使用CanvasRenderingContext2D对象在Canvas组件上进行绘制,其中fillText()方法用于绘制文本,drawImage()方法用于图像绘制。
开发流程
- 创建Canvas画布,在画布上绘制水印。
- 使用Stack组件或浮层overlay属性,将画布与UI页面组件融合显示。
2.具体实现参考代码:楼主可以参考这个仓库 https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-add-watermark#section20851175145112
3.部分实现代码:
@Prop watermarkWidth: number = 120;
@Prop watermarkHeight: number = 120;
@Prop watermarkText: string = this.getWatermarkText();
@Prop rotationAngle: number = -30;
@Prop fillColor: string | number | CanvasGradient | CanvasPattern = '#10000000';
@Prop font: string = '16vp';
draw() {
this.context.fillStyle = this.fillColor;
this.context.font = this.font;
const colCount = Math.ceil(this.context.width / this.watermarkWidth);
const rowCount = Math.ceil(this.context.height / this.watermarkHeight);
for (let col = 0; col <= colCount; col++) {
let row = 0;
for (; row <= rowCount; row++) {
const angle = this.rotationAngle * Math.PI / 180;
this.context.rotate(angle);
const positionX = this.rotationAngle > 0 ? this.watermarkHeight * Math.tan(angle) : 0;
const positionY = this.rotationAngle > 0 ? 0 : this.watermarkWidth * Math.tan(-angle);
this.context.fillText(this.watermarkText, positionX, positionY);
this.context.rotate(-angle);
this.context.translate(0, this.watermarkHeight);
}
this.context.translate(0, -this.watermarkHeight * row);
this.context.translate(this.watermarkWidth, 0);
}
}
使用水印方式Canvas绘画试试
看看这个是否是您需要的
https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-add-watermark#section12388834480
@Component
export struct Watermark {
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
// ...
build() {
Canvas(this.context)
.width('100%')
.height('100%')
.hitTestBehavior(HitTestMode.Transparent)
.onReady(() => this.draw())
}
}
@Builder
watermarkBuilder() {
Column() {
Watermark()
}
.hitTestBehavior(HitTestMode.Transparent)
}
build() {
// ...
Column() {
Image($r('app.media.empty'))
.width(110)
.height(88)
// ...
}
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.layoutWeight(1)
.overlay(this.watermarkBuilder())
// ...
}
试试通过离屏画布绘制技术实现。通过OffscreenCanvas创建离屏画布,利用drawImage()方法将水印图片叠加到原始图片上。加载原始图片与水印图片→创建画布→绘制叠加→保存新图片。
参考步骤
1/加载图片为PixelMap:将原始图片及水印图片转换为PixelMap对象
// 通过相册选择或资源加载获取图片
let imageSource = image.createImageSource(uri);
let originalPixelMap = await imageSource.createPixelMap();
let watermarkImageSource = image.createImageSource(watermarkUri);
let watermarkPixelMap = await watermarkImageSource.createPixelMap();
2/创建离屏画布并绘制
// 创建与原始图片同尺寸的离屏画布
let offCanvas = new OffscreenCanvasRenderingContext2D(
originalPixelMap.width,
originalPixelMap.height
);
// 绘制原始图片
offCanvas.drawImage(originalPixelMap, 0, 0);
// 绘制水印图片
let watermarkX = originalPixelMap.width - watermarkPixelMap.width - 20; // 右边距20
let watermarkY = originalPixelMap.height - watermarkPixelMap.height - 20; // 下边距20
offCanvas.globalAlpha = 0.5; // 设置透明度
offCanvas.drawImage(watermarkPixelMap, watermarkX, watermarkY);
// 获取合成后的PixelMap
let resultPixelMap = offCanvas.getPixelMap();
3/保存处理后的图片
// 使用ImagePacker保存为文件
let imagePacker = image.createImagePacker();
let imageBuffer = await imagePacker.packToData(resultPixelMap, {
format: 'image/jpeg',
quality: 90
});
// 写入文件(需申请媒体库权限)
let filePath = ...; // 目标路径
await fileIo.write(filePath, imageBuffer);
要实现您描述的效果,通常需要利用底层图形绘制能力。鸿蒙文档中提到的 Canvas
或 OffscreenCanvas
相关API是更合适的基础:
-
使用
Canvas
/OffscreenCanvasRenderingContext2D
:- 您可以先使用
Image
相关API(如ImageDecoder
)将图片解码为PixelMap
。 - 创建一个
Canvas
或OffscreenCanvas
,其大小与图片一致。 - 将
PixelMap
绘制到Canvas
上作为背景。 - 使用
Canvas
的rotate()
方法旋转绘图上下文,然后使用fillText()
或strokeText()
方法多次绘制文本,通过调整旋转角度和绘制位置来实现“很多条斜着”的水印效果。 - 最后,使用
Canvas
的相关方法(如toPixelMap
)将合成后的图像获取出来。
- 您可以先使用
-
关键API参考(来自鸿蒙文档):
CanvasRenderingContext2D.rotate(angle)
: 用于旋转当前的绘图上下文。CanvasRenderingContext2D.fillText(text, x, y)
: 用于在画布上绘制填充文本。CanvasRenderingContext2D.strokeText(text, x, y)
: 用于在画布上绘制文本边框(描边)。OffscreenCanvasRenderingContext2D
: 离屏画布的上下文,提供与CanvasRenderingContext2D
相同的API,可在Worker线程中处理图像,避免阻塞UI。
我的想法是使用本地图片来当作水印,来实现这样一个效果,
你这个安装不了,没在https://ohpm.openharmony.cn注册,
?什么意思,
有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html
这个没用我要的效果是应用到全局要配合Navigation使用,
在HarmonyOS Next中,可通过Image组件结合绝对定位实现图片水印。使用WaterSpan或自定义布局,设置透明度与重复平铺。推荐使用PixelMap处理图像数据,避免直接操作位图。水印叠加需注意图层顺序与混合模式,确保不影响主内容显示。