实现思路:从相册中算选择图片,将图片展示到UI界面,利用核心方法drawImage将要添加的水印画到图片上,然后将图片保存。
1、从相册中选取图片,添加水印,并返回添加水印后的图片保存路径
async pickerAcvtor(waterStr: string[]) {
// 实例化选择参数对象
const options = new picker.PhotoSelectOptions()
options.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE
options.maxSelectNumber = 1
// 实例化选择器对象
const pickerView = new picker.PhotoViewPicker()
let res = await pickerView.select(options)
// 判断用户取消了选择图片,则组织下面代码的继续运行
if (res.photoUris.length === 0) {
promptAction.showToast({ message: "用户取消图片选择" })
return
}
// 准备好图片的完整路径
let ext = 'jpg'
let fileName = Date.now().toString()
let cacheDir = getContext().cacheDir
let fullPath = cacheDir + '/' + fileName + '.' + ext
// 利用fileIo拷贝图片
let file = fileIo.openSync(res.photoUris[0], fileIo.OpenMode.READ_ONLY)
fileIo.copyFileSync(file.fd, fullPath)
this.imgPath = fullPath
addWaterMarkManager.addWaterImage(this.imgPath, waterStr, this.fillColor)
.then((pixelMap?: image.PixelMap) => {
if (pixelMap) {
this.pixelMap = pixelMap;
}
})
return this.imgPath
}
2、addWaterImage方法类型的封装
class AddWaterMarkManager {
private pixelMap?: image.PixelMap = undefined;
private TAG: string = 'imageEdit';
// 设置水印文字显示比例
private scale = 12.0 / 375;
/**
* 获取加水印图片pixelMap
*
* @param imageSource ImageSource 图片描述
* @param waterStr 水印数组
* @param imageWidth 显示控件宽度默认50
* @returns
*/
public async addWaterImage(imgPath: string, waterStr: string[], fillColor: string): Promise<image.PixelMap> {
//waterstr最后的数据渲染到页面最上边
let newStr = this.waterStrSort(waterStr)
let imgResource = image.createImageSource(imgPath)
// 获取图片信息
const imageInfo = imgResource.getImageInfoSync();
const pixelMap = await imgResource.createPixelMap({
editable: true
});
let returnPixelMap = this.getPixelMap(imageInfo, pixelMap, newStr, fillColor)
return returnPixelMap
// return imgPath
}
/**
* 获取加水印图片pixelMap
*
* @param imageSource ImageSource 图片描述
* @param waterStr 水印数组
* @param imageWidth 显示控件宽度默认50
* @returns
*/
public async addWaterpixelMap(pixelMap: PixelMap, waterStr: string[], fillColor: string): Promise<image.PixelMap> {
//waterstr最后的数据渲染到页面最上边
let newStr = this.waterStrSort(waterStr)
// 获取图片信息
const imageInfo = pixelMap.getImageInfoSync();
let returnPixelMap = this.getPixelMap(imageInfo, pixelMap, newStr, fillColor)
return returnPixelMap
}
private waterStrSort(strlist: string[]) {
let newList: string[] = []
for (let index = 0; index < strlist.length; index++) {
newList.push(strlist[strlist.length - index-1])
}
return newList
}
private getPixelMap(imageInfo: image.ImageInfo, pixelMap: image.PixelMap, newStr: string[], fillColor: string) {
// 这个回调的pixelMap就是当前图片的pixelMap
let offScreenCanvas = new OffscreenCanvas(imageInfo.size.width, imageInfo.size.height)
let OffScreenContext = offScreenCanvas.getContext("2d")
OffScreenContext.drawImage(pixelMap, 0, 0, offScreenCanvas.width, offScreenCanvas.height)
pixelMap.release();
// 判断水印内容是否为空
if (newStr != undefined && newStr.length > 0) {
let resultString = newStr.join("\n");
// 设置字体大小
OffScreenContext.fillStyle = fillColor
OffScreenContext.font = this.scale * imageInfo.size.width + "vp";
OffScreenContext.textAlign = 'right';
OffScreenContext.textBaseline = 'bottom';
OffScreenContext.fillText(resultString, offScreenCanvas.width - 150, offScreenCanvas.height - 100)
}
// 获取新的PixelMap
return OffScreenContext.getPixelMap(0, 0, offScreenCanvas.width, offScreenCanvas.height)
}
/**
* 获取加水印图片pixelMap
*
* @param fd 文件id
* @param waterStr 水印数组
* @param imageWidth 显示控件宽度默认50
* @returns
*/
private async getFdWaterPixelMap(fd: number, waterStr: string[], fillColor: string) {
const imageSourceApi = image.createImageSource(fd);
if (!imageSourceApi) {
console.log(this.TAG, 'imageSourceAPI created failed!');
}
// 获取图片信息
const imageInfo = imageSourceApi.getImageInfoSync();
const pixelMap = await imageSourceApi.createPixelMap({
editable: true
});
let returnPixelMap = this.getPixelMap(imageInfo, pixelMap, waterStr, fillColor)
return returnPixelMap
}
}
const addWaterMarkManager = new AddWaterMarkManager()
export { addWaterMarkManager }
3、UI界面渲染
build() {
Scroll() {
Column({ space: 20 }) {
this.titleBuilder()
Image(this.pixelMap)
.objectFit(ImageFit.Contain)
.width('100%')
.layoutWeight(1)
.borderRadius($r('app.float.tab_bar_item_font_size'))
Blank().layoutWeight(1)
}
.width('100%')
.align(Alignment.Bottom)
.backgroundColor(Color.Black)
.padding({
top: this.topBar,
right: 10,
left: 10,
bottom: 20
})
}
.height('150%')
.width('100%')
}
@Builder
titleBuilder() {
Row() {
Image($r('app.media.ic_left_row'))
.width($r('app.float.common_font20vp'))
.aspectRatio(1)
.fillColor(Color.White)
.onClick(() => {
router.back();
});
Text('选取图片').fontColor(Color.White)
.fontSize($r('app.float.common_font14'))
.onClick(async () => {
let waterImgPath = await this.pickerAcvtor(this.strings)
AlertDialog.show({ message: `返回图片路径:${waterImgPath}` });
});
Text('完成').fontColor(Color.White)
.fontSize($r('app.float.common_font14'))
.onClick(() => {
AlertDialog.show({ message: `返回图片路径:${this.imgPath}` });
});
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
.padding({ right: $r('app.float.tab_bar_item_icon_size'), left: $r('app.float.tab_bar_item_icon_size') })
}
标签:string,width,解决方案,waterStr,水印,HarmonyOS,pixelMap,let,图片
From: https://blog.csdn.net/xp1870069025/article/details/141297956