HarmonyOS 鸿蒙Next关于自定义字体水印的实现

发布于 1周前 作者 songsunli 最后一次编辑是 5天前 来自 鸿蒙OS

HarmonyOS 鸿蒙Next关于自定义字体水印的实现

实现自定义字体的图片水印

前言

近期看了一些水印案例以及了解到关于绘制水印这一块的内容,但是官方的api绘制字体时,并不支持使用自定义字体,但是对于一些相机类或图片处理类的APP,就有点不是那么友好了,所以这也是这篇文章的由来,不说废话,继续往下看,

思路

需要各位先去大概了解一下几个api, 注册字体 组件截图  setpixelmap drawimage,大概了解这几个api之后,先说一下思路,原理就是使用组件截图的方式离屏绘制一个与图片大小一致的组件,比较容易变通的小伙伴看到这里可能已经懂了,没错,接下来就是将这个与图片大小一直的截图,"贴"上去,同时保存.好了,接下来看代码

代码实现

首先 默认你已经获取到了图片的大小等信息,使用@builder实现一个自定义结构,同时水印位置也是在这里控制

  @Builder
myTextBuilder(w: number, h: number) {
// 通过这里控制水印位置,也可以通过定位等方式控制水印位置
Stack({alignContent: Alignment.BottomEnd}) {
Text(‘测试水印’)
.fontSize(20)
.fontWeight(700)
.fontColor(’#f00’)
// 注册的自定义字体
.fontFamily(“myFont”)
.rotate({
angle: -10
})
.fontStyle(FontStyle.Italic)
}
.width(w)
.height(h)
.padding(10)
.backgroundColor(Color.Transparent)
}复制

接下来就是实现这个功能的核心代码了------这一部分有两种方式,一个是离屏绘制,不使用canvas组件,一种是使用canvas组件,两种思路一直,只不过代码略有差别
先看使用离屏绘制的, 重要说明:此代码基于官方示例改造如有转载请标明出处------原文链接

调用方法

 Button($r(‘app.string.button_text_add_watermark’))
.height(40)
.width(‘100%’)
.onClick(async () => {
const imagePixelMap = await this.getImagePixelMap($r(‘app.media.img1’));
// 获取图片的宽高信息
const height = px2vp(imagePixelMap.height);
const width = px2vp(imagePixelMap.width);
// 获取组件截图
const myImg1 = await componentSnapshot.createFromBuilder(() => {
this.myTextBuilder(width,height)
})
// 调用绘制方法
this.addedWatermarkPixelMap = await addWatermark(imagePixelMap, myImg1);
})复制

绘制方法

export async function addWatermark(
imagePixelMap: ImagePixelMap,
imagePixelMap2: image.PixelMap,
drawWatermark?: (OffscreenContext: OffscreenCanvasRenderingContext2D) => void
): Promise<image.PixelMap> {
const height = px2vp(imagePixelMap.height);
const width = px2vp(imagePixelMap.width);
const offScreenCanvas = new OffscreenCanvas(width, height);
const offScreenContext = offScreenCanvas.getContext(‘2d’);
// 先将背景图绘制在画布上
offScreenContext.setPixelMap(imagePixelMap.pixelMap)
if (drawWatermark) {
drawWatermark(offScreenContext);
} else {
// 绘制我们自己的组件截图
offScreenContext.drawImage(imagePixelMap2, 0, 0);
}
return offScreenContext.getPixelMap(0, 0, width, height);
}复制

好了,离屏绘制的核心方法就这么多了

接下来就是使用画布的方式了,思路是不变的,只不过代码略有差别,这里直接贴上一个我写的示例,大家看看就好😀

import { DrawWatermark } from ‘…/utils/DrawCanvasUtil’
import { promptAction } from ‘@kit.ArkUI’
import image from ‘@ohos.multimedia.image’

@Entry @Component struct CanvasMarkPage { @State markImg: image.PixelMap = {} as image.PixelMap private settings: RenderingContextSettings = new RenderingContextSettings(true) private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)

build() { Column({ space: 20 }) { // 画布组件 Canvas(this.context)// 假定已经拿到图片宽高 .width(px2vp(800)) .aspectRatio(1) .onReady(async () => { // 获取原图片的PixelMap对象 const imagePixelMap = await DrawWatermark.getImagePixelMap($r(‘app.media.img’)) this.context.setPixelMap(imagePixelMap.pixelMap) }) Button(‘点击开始绘制’) .onClick(() => { this.startDraw() .then((result) => { this.markImg = result }) .catch((e: Error) => { promptAction.showToast({ message: ‘绘制失败’ + e.message }) }) }) Image(this.markImg) .width(px2vp(800)) .aspectRatio(1) } .width(‘100%’) .height(‘100%’) .alignItems(HorizontalAlign.Center) }

async startDraw() { const startTime = Date.now() /* * 获取图片的宽高信息,假定我们已经拿到图片的宽高并进行转换 */ const width = px2vp(800); const height = px2vp(800); // 后台绘制自定义字体的组件并截图 const textImg = await this.getUIContext().getComponentSnapshot().createFromBuilder(() => { this.myTextBuilder({ width, height }) }) this.context.drawImage(textImg, 0, 0); // 绘制完成的对象 const myMarkImg = this.context.getPixelMap(0, 0, width, height) const endTime = Date.now() // 输出执行耗时 promptAction.showToast({ message: ‘绘制耗时’ + (endTime - startTime) + ‘ms’ }) return myMarkImg }

/**

  • 绘制文字组件
  • 宽高与图片保持一致,此处控制水印位置相关信息
  • @param sizeInfo */ @Builder myTextBuilder(sizeInfo: SizeOptions) { Column() { Text(‘绘制文字’) .fontSize(20) .fontColor(’#f00’) .fontWeight(700) .fontFamily(‘myFont’) } .size(sizeInfo) .padding(10) .backgroundColor(Color.Transparent) .justifyContent(FlexAlign.End) .alignItems(HorizontalAlign.End) } }

好了,代码就这么多了,如果有问题的小伙伴,欢迎评论区留言,
ps: 代码部分核心方法基于官网示例改造,此文章旨在提供实现思路,如有转载请务必表明出处,  官方原文链接  官方仓库地址


更多关于HarmonyOS 鸿蒙Next关于自定义字体水印的实现的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS 鸿蒙Next关于自定义字体水印的实现的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,实现自定义字体水印的功能,可以通过以下步骤进行:

  1. 准备自定义字体文件:确保你有一个支持的字体文件(如.ttf格式),并将其放置在项目的资源目录中。

  2. 加载字体文件:在代码中,通过鸿蒙提供的字体加载接口,将自定义字体文件加载到内存中。

  3. 创建水印Canvas:利用鸿蒙的Canvas绘图能力,创建一个Canvas对象用于绘制水印。

  4. 绘制水印内容:在Canvas上,使用加载的自定义字体,设置字体大小、颜色等属性,然后绘制水印文本。

  5. 将水印应用到图像或视图:根据具体需求,将绘制好的水印Canvas内容叠加到目标图像或视图上。如果是图像,可以通过图像合成技术实现;如果是视图,可以通过自定义绘制逻辑实现。

  6. 优化与调整:根据显示效果,调整水印的透明度、位置、大小等参数,以达到最佳视觉效果。

注意,实现过程中需确保字体文件的版权合法性,避免使用未经授权的字体。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部