0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

万少 来源:jf_22972444 作者:jf_22972444 2025-03-31 09:27 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

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

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

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

createPattern

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

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

参数名类型必填说明
imageImageBitmap图源对象,具体参考 ImageBitmap 对象。
repetitionstringnull

提前准备好图片

image-20250105085559069

基本使用

  1. 基于图片创建填充模版
  2. 设置到 canvas 的 fillStyle 中
  3. 进行描绘
@Entry
@Component
struct 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%')
  }
}

效果

image-20250105085914214

repetition:repeat

设置平铺

let pattern = this.context.createPattern(this.img, "repeat");

效果

image-20250105090015220

clamp

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

let pattern = this.context.createPattern(this.img, "clamp");

image-20250105090145764

mirror

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

let pattern = this.context.createPattern(this.img, "mirror");

image-20250105090203370

quadraticCurveTo

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

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

参数名类型必填说明
cpxnumber贝塞尔参数的 x 坐标值。默认单位:vp。
cpynumber贝塞尔参数的 y 坐标值。默认单位:vp。
xnumber路径结束时的 x 坐标值。默认单位:vp。
ynumber路径结束时的 y 坐标值。默认单位:vp。

示例代码

this.context.beginPath();
this.context.moveTo(20, 20);
this.context.quadraticCurveTo(100, 100, 200, 20);
this.context.stroke();

效果

image-20250105091240519

辅助理解

img


image-20250105091007706

bezierCurveTo

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

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

参数名类型必填说明
cp1xnumber第一个贝塞尔参数的 x 坐标值。默认单位:vp。
cp1ynumber第一个贝塞尔参数的 y 坐标值。默认单位:vp。
cp2xnumber第二个贝塞尔参数的 x 坐标值。默认单位:vp。
cp2ynumber第二个贝塞尔参数的 y 坐标值。默认单位:vp。
xnumber路径结束时的 x 坐标值。默认单位:vp。
ynumber路径结束时的 y 坐标值。默认单位:vp。

示例代码

this.context.beginPath()
  this.context.moveTo(10, 10)
  this.context.bezierCurveTo(20, 100, 200, 100, 200, 20)
  this.context.stroke()

效果

image-20250105091324817

辅助理解

img

image-20250105091128806

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
@Component
struct 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%')
  }
}

效果

image-20250105092307492

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

image-20250105092847039

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. [数学曲线之一:贝塞尔曲线](https://zhuanlan.zhihu.com/p/711975272)
  2. [神奇 canvas 带你实现魔法摄像头](https://juejin.cn/post/7264125562393788473#heading-8)
  3. [ImageData](https://developer.mozilla.org/zh-CN/docs/Web/API/ImageData)

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Canvas
    +关注

    关注

    0

    文章

    21

    浏览量

    11381
  • 鸿蒙
    +关注

    关注

    60

    文章

    2862

    浏览量

    45367
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    labview五子棋程序

    本帖最后由 桂花酒 于 2012-6-10 13:43 编辑 labview五子棋程序,想用的可以看看!本来是发的求助帖,找五子棋程序,不过刚才下了一个,鉴于论坛上现在已经搜不着了(我原来下过,不过删了)一起学习!
    发表于 06-10 13:16

    五子棋的棋盘怎么么做

    做课程设计,五子棋的棋盘怎么做
    发表于 07-02 23:18

    五子棋主程序前面板怎么设计

    五子棋主程序前面板怎么设计?后面版有程序了
    发表于 07-03 16:39

    基于labview的五子棋设计

    本帖最后由 aidisheng2011 于 2014-3-21 19:50 编辑 我上网下载了一个labview的五子棋学习学习,但是发现很难理解,在这里向各位大神求教。1
    发表于 03-21 13:51

    用Verilog写的一个五子棋

    在期末EDA课答辩之际写了一个五子棋的代码,主要用到了VGA和PS2接口的外设,因为在自己敲的时候来网上找过,没找到有关的资料,所以自己写好之后就想发上来和大家讨论下。基本实现了双人对战五子棋的功能。感觉有很多纰漏,想请大家指点下。
    发表于 06-15 14:40

    五子棋

    求一个五子棋的程序
    发表于 06-26 16:09

    五子棋

    自己做的五子棋,说不上有什么难的
    发表于 08-12 21:44

    labview 虚拟五子棋

    `一个简易的五子棋程序,喜欢的可以借鉴下`
    发表于 06-16 21:57

    怎样去设计一种人机对弈五子棋程序

    五子棋游戏应达到几方面的要求?怎样去设计一种人机对弈五子棋程序?
    发表于 09-29 07:26

    五子棋程序源代码-Matlab实现

    五子棋程序源代码-M
    发表于 07-04 16:15 50次下载

    C语言五子棋

    C语言五子棋,有趣的东西,值得玩玩,不用看着黑框发呆
    发表于 01-12 16:49 2次下载

    Delphi教程_使用DrawGrid控件制作五子棋

    Delphi教程使用DrawGrid控件制作五子棋,很好的Delphi的学习资料。
    发表于 03-16 14:55 19次下载

    C语言教程之五子棋游戏的问题

    C语言教程之五子棋游戏的问题,很好的C语言资料,快来学习吧。
    发表于 04-25 17:07 0次下载

    基于LabVIEW的五子棋博弈算法

    针对目前五子棋人机对弈多数基于电脑、手机,缺少真实环境的问题,提出一种基于LabVIEW的博弈算法,并运用于真实的五子棋人机对弈。首先通过图像采集系统获取当前状态下棋盘及人机双方棋子的位置信息;然后
    发表于 12-17 11:32 29次下载

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

    鸿蒙服务实战-笑笑五子棋(1) 前言 作为鸿蒙应用的深度开发者都应该知道,经历了 波澜壮阔 1
    的头像 发表于 03-31 09:23 567次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>元</b><b class='flag-5'>服务实战</b>-<b class='flag-5'>笑笑</b><b class='flag-5'>五子棋</b>(1)