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

概要

使用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")

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}`);
    }
  }

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()
    }
  }

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})
  }

技术名词解释

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

技术细节

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

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

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

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

小结

Demo可参考WaterMask: 水印工具

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值