使用ArkTS在HarmonyNext系统上,实现图片增加文字水印 原创

zhouchy
发布于 2025-3-8 21:35
636浏览
0收藏


 文章目录

概要

使用ArkTS在HarmonyNext系统上,实现图片增加文字水印

整体架构流程

1、使用Stack组件作为根容器,并设置id为“root”

Stack() {
   Image(this.bgImg)
     .width('100%')
     .draggable(false)
     .objectFit(ImageFit.Contain)
     .onAreaChange((oldArea: Area, newArea: Area) => {
       if ((oldArea.width != newArea.width || oldArea.height != newArea.height) && newArea.width > 0 && newArea.height > 0) {
        this.canvasWidth = newArea.width as number
        this.canvasHeight = newArea.height as number
        this.offContext2D = new OffscreenCanvasRenderingContext2D(this.canvasWidth, this.canvasHeight, this.settings)
        this.offContext2D.fillStyle = '#1F000000'
        this.offContext2D.font = '18vp sans-serif'
       }
     })

   Canvas(this.context2D)
     .width(this.canvasWidth)
     .height(this.canvasHeight)
 }
 .width('100%')
 .height('100%')
 .align(Alignment.Center)
 .id("root")
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

2、通过系统相册选择图片,并使用Image组件显示,作为背景图

openGallery() {
    try {
      let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
      PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
      PhotoSelectOptions.maxSelectNumber = 1;
      let photoPicker = new photoAccessHelper.PhotoViewPicker();
      photoPicker.select(PhotoSelectOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
        if (photoSelectResult.photoUris.length > 0) {
          this.bgImg = photoSelectResult.photoUris[0]
          this.maskText = ''
        }
        console.info('PhotoViewPicker.select successfully, PhotoSelectResult uri: ' + JSON.stringify(photoSelectResult));
      }).catch((err: BusinessError) => {
        console.error(`PhotoViewPicker.select failed with err: ${err.code}, ${err.message}`);
      });
    } catch (error) {
      let err: BusinessError = error as BusinessError;
      console.error(`PhotoViewPicker failed with err: ${err.code}, ${err.message}`);
    }
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

3、在Image组件上叠加Canvas组件,并通过Canvas绘制文字

watchMaskText() {
    this.offContext2D.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
    this.context2D.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
    this.offContext2D.saveLayer()
    this.offContext2D.rotate(-45 * Math.PI / 180)
    let cols = Math.sqrt(this.canvasWidth * this.canvasWidth + this.canvasHeight * this.canvasHeight) / 100
    for (let i = 0; i < cols; i++) {
      let x = (-cols / 2 + i) * 200
      for(let j = 0; j < 100; j++) {
        this.offContext2D.fillText(this.maskText, x, (i * j) * 50)
      }
    }
    this.offContext2D.rotate(45 * Math.PI / 180)
    this.offContext2D.restoreLayer()
    let image = this.offContext2D.transferToImageBitmap()
    if (image) {
      this.context2D.transferFromImageBitmap(image)
      image.close()
    }
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

4、对根容器截图,保存到媒体库

save() {
    componentSnapshot.get("root", async (error: Error, pixmap: image.PixelMap) => {
      if (error) {
        console.log("error: " + JSON.stringify(error))
        return;
      }
      try {
        let packOpts: image.PackingOption = { format: "image/jpeg", quality: 100 }
        let arrayBuffers: ArrayBuffer = await this.imageImagePacker.packing(pixmap, packOpts)
        let result = await savePhoto(getContext(this), arrayBuffers)
        promptAction.showToast({message: result ? '图片已保存到系统相册' : '图片保存失败'})
      } catch (error) {
        console.error("error is "+ JSON.stringify(error));
      }
    }, {scale : 2, waitUntilRenderFinished : true})
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

技术名词解释

  • Stack:层叠布局
  • Image:图片显示组件
  • Canvas:画布组件

技术细节

保存图片到媒体库,有两种方式:

参考文档​​保存媒体库资源-Media Library Kit(媒体文件管理服务)-媒体 - 华为HarmonyOS开发者​

方式1:申请受限权限,获取文件读写的权限(调用需要ohos.permission.READ_IMAGEVIDEO和ohos.permission.WRITE_IMAGEVIDEO的权限),这样就可以将媒体资源保存到媒体库。 参考文档 ​​申请使用受限权限-申请应用权限-应用权限管控-程序访问控制-安全-系统 - 华为HarmonyOS开发者​

方式2:通过安全控件,每次保存图片时需要用户手动授权 参考文档​​安全控件概述-使用安全控件-程序访问控制-安全-系统 - 华为HarmonyOS开发者​

小结

Demo可参考​​WaterMask: 水印工具​


©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报
回复
    相关推荐