写点什么

鸿蒙元服务实战 - 笑笑五子棋(3)

作者:万少
  • 2025-01-05
    江苏
  • 本文字数:2978 字

    阅读完需:约 10 分钟

鸿蒙元服务实战-笑笑五子棋(3)

鸿蒙元服务实战-笑笑五子棋(3)

接上篇。上一篇主要讲解了元服务的创建和 canvas 的一些基本使用,直线、矩形、弧形、文本、图像等。canvas 本身还有很多其他


的功能。这里继续围绕 canvas 进行讲解。

createPattern

createPattern(image: ImageBitmap, repetition: string | null): CanvasPattern | null


通过指定图像和重复方式创建图片填充的模板。



提前准备好图片


基本使用

  1. 基于图片创建填充模版

  2. 设置到 canvas 的 fillStyle 中

  3. 进行描绘


@Entry@Componentstruct Index {  private settings: RenderingContextSettings = new RenderingContextSettings(true)  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)  private img: ImageBitmap = new ImageBitmap("/images/2.png")
build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Canvas(this.context) .width('100%') .height('100%') .backgroundColor('#ffff00') .onReady(() => { // 1 基于图片创建填充模版2. let pattern = this.context.createPattern(this.img, 'no-repeat') // 不平铺 if (pattern) { // 2 设置到canvas的fillStyle中 this.context.fillStyle = pattern } // 3 进行描绘 this.context.fillRect(0, 0, 400, 400) }) } .width('100%') .height('100%') }}
复制代码


效果


repetition:repeat

设置平铺


let pattern = this.context.createPattern(this.img, "repeat");
复制代码


效果


clamp

在原始边界外绘制时,超出部分使用边缘的颜色绘制;


let pattern = this.context.createPattern(this.img, "clamp");
复制代码


mirror

沿 x 轴和 y 轴重复翻转绘制图像。


let pattern = this.context.createPattern(this.img, "mirror");
复制代码


quadraticCurveTo

quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void


创建二次贝赛尔曲线的路径。



示例代码


this.context.beginPath();this.context.moveTo(20, 20);this.context.quadraticCurveTo(100, 100, 200, 20);this.context.stroke();
复制代码


效果



辅助理解





bezierCurveTo

bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void


创建三次贝赛尔曲线的路径。



示例代码


  this.context.beginPath()  this.context.moveTo(10, 10)  this.context.bezierCurveTo(20, 100, 200, 100, 200, 20)  this.context.stroke()
复制代码


效果



辅助理解



ImageData

ImageData对象可以存储 canvas 渲染的像素数据。也就是说 ImageData 可以让我们使用 canvas 对画布中的每一个像素进行操作。提


供了强大的控制能力。

实例属性

  • ImageData.data 只读

  • Uint8ClampedArray 描述了一个一维数组,包含以 RGBA 顺序的数据,数据使用 0255(包含)的整数表示。

  • ImageData.height 只读

  • 无符号长整型(unsigned long),使用像素描述 ImageData 的实际高度。

  • ImageData.width 只读

  • 无符号长整型(unsigned long),使用像素描述 ImageData 的实际宽度。


这里通过 canvas 的getImageData方法快速获取 ImageData 数据。然后通过putImageData把处理好的内容重新描绘到画图上。


@Entry@Componentstruct Index {  private settings: RenderingContextSettings = new RenderingContextSettings(true)  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)  private img: ImageBitmap = new ImageBitmap("/images/2.png")
build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Canvas(this.context) .width('100%') .height('100%') .backgroundColor('#ffff00') .onReady(() => { this.context.drawImage(this.img, 0, 0, 130, 130) // 获取了 ImageData 示例 let imagedata = this.context.getImageData(50, 50, 130, 130) // 又重新描绘到canvas上 this.context.putImageData(imagedata, 150, 150) }) } .width('100%') .height('100%') }}
复制代码


效果


ImageData 反色

this.context.drawImage(this.img, 0, 0, 130, 130);// 获取了 ImageData 示例let imagedata = this.context.getImageData(50, 50, 130, 130);// console.log("xxx,", JSON.stringify(imagedata.data))Object.keys(imagedata.data).forEach((k) => {  // 反色  imagedata.data[k] = 255 - imagedata.data[k];});// 又重新描绘到canvas上this.context.putImageData(imagedata, 150, 150);
复制代码


ImageData 其他效果

反转效果:


  • 原理:通过将每个像素的 RGB 值取反来实现反转效果。

  • 实现方式:使用getImageData获取图像数据,然后遍历每个像素,将每个像素的 RGB 值取反,再使用putImageData将修改后的数据绘制回 Canvas。


黑白效果:


  • 原理:将每个像素的 RGB 值转换为灰度值,使图像变为黑白。

  • 实现方式:使用getImageData获取图像数据,然后遍历每个像素,将每个像素的 RGB 值转换为灰度值(R、G、B 三个分量取平均值),再使用putImageData将修改后的数据绘制回 Canvas。


亮度效果:


  • 原理:调整每个像素的亮度值,使图像变亮或变暗。

  • 实现方式:使用getImageData获取图像数据,然后遍历每个像素,调整每个像素的亮度值,再使用putImageData将修改后的数据绘制回 Canvas。


复古效果:


  • 原理:通过调整每个像素的色调、饱和度和亮度,使图像呈现复古效果。

  • 实现方式:使用getImageData获取图像数据,然后遍历每个像素,调整每个像素的色调、饱和度和亮度,再使用putImageData将修改后的数据绘制回 Canvas。


红色、绿色、蓝色效果:


  • 原理:增加或减少每个像素的红色、绿色、蓝色分量的值,使图像呈现相应颜色的效果。

  • 实现方式:使用getImageData获取图像数据,然后遍历每个像素,增加或减少每个像素的红色、绿色、蓝色分量的值,再使用putImageData将修改后的数据绘制回 Canvas。


透明效果:


  • 原理:调整每个像素的透明度值,使图像呈现透明效果。

  • 实现方式:使用getImageData获取图像数据,然后遍历每个像素,调整每个像素的透明度值,再使用putImageData将修改后的数据绘制回 Canvas。


马赛克效果:


  • 原理:将图像分割为小块,每个小块的像素值设置为该小块内像素的平均值,从而实现马赛克效果。

  • 实现方式:使用getImageData获取图像数据,然后将图像分割为小块,计算每个小块内像素的平均值,再将该小块内所有像素的值设置为该平均值,最后使用putImageData将修改后的数据绘制回 Canvas。


马赛克效果


  • 由于实际操作过程中,上述马赛克效果处理性能比较底下,这里用来一个取巧的效果来实现。就是先用 canvas 将画面画小,然后再将画面缩放来实现一个模糊效果,间接实现马赛克效果


渐变滤镜效果:


  • 原理:通过在图像上应用渐变效果,使图像呈现渐变色的效果。

  • 实现方式:使用createLinearGradientcreateRadialGradient创建渐变对象,然后使用渐变对象作为填充样式,绘制图像到 Canvas 上。

参考链接

  1. 数学曲线之一:贝塞尔曲线

  2. 神奇 canvas 带你实现魔法摄像头

  3. ImageData


发布于: 刚刚阅读数: 5
用户头像

万少

关注

还未添加个人签名 2021-12-02 加入

还未添加个人简介

评论

发布
暂无评论
鸿蒙元服务实战-笑笑五子棋(3)_鸿蒙_万少_InfoQ写作社区