HarmonyOS 鸿蒙Next拍照时添加水印信息

发布于 1周前 作者 songsunli 来自 鸿蒙OS

HarmonyOS 鸿蒙Next拍照时添加水印信息 拍照时如何添加水印信息

2 回复

转pixMap的处理:

let sourceOptions: image.SourceOptions = {
  sourceDensity: 0,
  sourcePixelFormat: image.PixelMapFormat.NV21, // NV21
  sourceSize: this.imageSize
}
let imageSource: image.ImageSource = image.createImageSource(imgComponent.byteBuffer, sourceOptions);
let opts: image.InitializationOptions = {
  editable: true,
  pixelFormat: image.PixelMapFormat.NV21,
  size: this.imageSize
}
let pixelMap = await imageSource.createPixelMap(opts);
await pixelMap.rotate(90.0);

保存:

let file: fileIo.File = fileIo.openSync(photoUri, fileIo.OpenMode.WRITE_ONLY);
let imagePacker: image.ImagePacker = image.createImagePacker();
let packOpts: image.PackingOption = { format: 'image/jpeg', quality: 100 };
await imagePacker.packToFile(this.finalPixelMap, file.fd, packOpts);
fileIo.closeSync(file);

保存图片添加水印: 方案:使用OffScreenCanvas离屏画布拿到图片源数据,在离屏画布上使用OffscreenCanvasRenderingContext2D.drawImage方法讲图片数据进行绘制,使用OffscreenCanvasRenderingContext2D.fillText方法绘制文字水印,通过 OffscreenCanvasRenderingContext2D.getPixelMap方法获取添加水印后的图片pixelMap数据,再通过安全控件方式拿到图库的uri路径,在这个uri下通过image.createImagePacker方法创建图片文件,通过fs.write方法写入这个图库的文件中,具体实现代码如下所示:

第一步:使用resourceManager.getMediaContent方法获取当前的图片资源

getContext(this).resourceManager.getMediaContent($r(this.imagePath)).then((data) => {
  // ...
}).catch((err: BusinessError) => {
  console.log("getPixelMap error" + err.message)
})

第二步:使用image.createImageSource方法创建图片资源,在使用OffscreenCanvasRenderingContext2D.drawImage方法绘制图片在离屏画布上

let arrayBuffer = data.buffer.slice(data.byteOffset, data.byteLength + data.byteOffset)
let imageSource: image.ImageSource = image.createImageSource(arrayBuffer);
imageSource.getImageInfo((err, value) => {
  if (err) {
    return;
  }
  let opts: image.DecodingOptions = {
    editable: true,
    desiredSize: {
      height: value.size.height,
      width: value.size.width
    }
  };
  imageSource.createPixelMap(opts, async (err, pixelMap) => {
    let offScreenCanvas = new OffscreenCanvas(value.size.width, value.size.height)
    let OffScreenContext = offScreenCanvas.getContext("2d")
    this.imageScale = offScreenCanvas.width / display.getDefaultDisplaySync().width
    OffScreenContext.drawImage(pixelMap, 0, 0, offScreenCanvas.width, offScreenCanvas.height)
    // ...
  })
})

第三步:使用OffscreenCanvasRenderingContext2D.fillText绘制水印

getContext(this).resourceManager.getMediaContent($r(this.imagePath)).then((data) => {
  let arrayBuffer = data.buffer.slice(data.byteOffset, data.byteLength + data.byteOffset)
  let imageSource: image.ImageSource = image.createImageSource(arrayBuffer);
  imageSource.getImageInfo((err, value) => {
    if (err) {
      return;
    }
    let opts: image.DecodingOptions = {
      editable: true,
      desiredSize: {
        height: value.size.height,
        width: value.size.width
      }
    };
    imageSource.createPixelMap(opts, async (err, pixelMap) => {
      // ...
      OffScreenContext.textAlign = "right"
      OffScreenContext.textBaseline = "bottom"
      OffScreenContext.fillStyle = '#30000000'
      OffScreenContext.font = 32 * this.imageScale + "vp"
      OffScreenContext.fillText("初九会画画", offScreenCanvas.width - 20 * this.imageScale, offScreenCanvas.height - 20 * this.imageScale)
      // ...
    })
  })
}).catch((err: BusinessError) => {
  console.log("getPixelMap error" + err.message)
})

第四步:使用OffscreenCanvasRenderingContext2D.getPixelMap取出绘制后的图片数据

// 获取新的PixelMap
this.pixelMap = OffScreenContext.getPixelMap(0, 0, offScreenCanvas.width, offScreenCanvas.height)

第五步:使用SaveButton保存到图库中

SaveButton({ icon: SaveIconStyle.FULL_FILLED }).onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => {
  if (result == SaveButtonOnClickResult.SUCCESS) {
    try {
      let context = getContext(this);
      let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
      let uri = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg'); // 创建媒体文件
      this.imagePath = "app.media.img1"
      this.addWatermark()
      if (this.pixelMap) {
        saveToFile(this.pixelMap, uri)
      }
    } catch (err) {
      console.error('createAsset failed, message = ', err);
    }
  } else {
    console.error('SaveButtonOnClickResult createAsset failed');
  }
})

拍照添加水印: 方案:使用cameraPicker拉起系统相机拍照,拿到返回的picker.PickerResult.resultUri后使用fs.openSync读出图片文件转化为pixelMap,使用image组件渲染在页面上,在保存图片的时候通过drawing.TextBlob.makeFromString方法绘制水印后保存

第一步:使用cameraPicker拉起系统相机

import picker from '@ohos.multimedia.cameraPicker';
import camera from '@ohos.multimedia.camera';
async openCamera() {
  try {
    let pickerProfile: picker.PickerProfile = {
      cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
    };
    let pickerResult: picker.PickerResult = await picker.pick(getContext(this), [picker.PickerMediaType.PHOTO, picker.PickerMediaType.VIDEO], pickerProfile);
    console.log("the pick pickerResult is:" + JSON.stringify(pickerResult));
    // ...
  } catch (error) {
    let err = error as BusinessError;
    console.error(`the pick call failed. error code: ${err.message}`);
  }
}

第二步:将相机拍摄的照片渲染在页面中,使用fs.readSync读出文件字节流,再使用image.createImageSource创建图片资源管理器获取到图片的pixelMap

@State pixelMap: image.PixelMap | null = null
async openCamera() {
  try {
    // ...
    if (pickerResult.resultUri) {
      this.showImage = true
    }
    let file = fs.openSync(pickerResult.resultUri)
    let buffer = new ArrayBuffer(fs.statSync(file.fd).size)
    fs.readSync(file.fd, buffer)
    let imageSource: image.ImageSource = image.createImageSource(buffer)
    imageSource.getImageInfo((err, value) => {
      if (err) {
        return;
      }
      let opts: image.DecodingOptions = {
        editable: true,
        desiredSize: {
          height: value.size.height,
          width: value.size.width
        }
      };
      imageSource.createPixelMap(opts, async (err, pixelMap) => {
        this.pixelMap = pixelMap
      })
    })
  } catch (error) {
    let err = error as BusinessError;
    console.error(`the pick call failed. error code: ${err.message}`);
  }
}
build() {
  // ...
  if(this.showImage) {
    Image(this.pixelMap).width("100%")
    // ...
  }
}

第三步:使用drawing.TextBlob.makeFromString绘制水印后 使用SaveButton保存在系统相册中

SaveButton()
.onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => {
  if (result == SaveButtonOnClickResult.SUCCESS) {
    try {
      let context = getContext(this);
      let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
      let uri = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'png'); // 创建媒体文件
      saveToFile(this.addWaterMask(this.pixelMap!), uri);
    } catch (err) {
      console.error('createAsset failed, message = ', err);
    }
  } else {
    console.error('SaveButtonOnClickResult createAsset failed');
  }
})

更多关于HarmonyOS 鸿蒙Next拍照时添加水印信息的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS(鸿蒙)系统中,拍照时添加水印信息通常涉及相机应用的设置或第三方应用的功能。以下是针对该问题的直接回答:

  1. 检查相机设置:首先,打开相机应用,查看是否有内置的“水印”或“添加信息”等选项。某些版本的鸿蒙相机应用可能已内置此功能。

  2. 使用第三方应用:如果相机应用中没有水印功能,你可以考虑下载并安装支持水印添加的第三方相机应用。这些应用通常提供丰富的水印模板,允许你自定义水印内容。

  3. 后期编辑:拍摄照片后,你可以使用图库应用或第三方图片编辑软件来添加水印。这些工具通常提供文本叠加功能,让你能够在照片上添加想要的文字或图标水印。

请注意,以上方法可能因鸿蒙系统版本、设备型号或第三方应用的不同而有所差异。如果尝试上述方法后仍无法添加水印,可能是当前系统或应用版本不支持该功能。

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

回到顶部