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

简介: 本文是鸿蒙元服务实战系列的第三篇,围绕“笑笑五子棋”项目深入讲解了 Canvas 的高级用法。主要内容包括:`createPattern` 方法实现图片填充模板,支持多种重复方式如 `repeat`、`clamp` 和 `mirror`;绘制二次和三次贝塞尔曲线的路径方法 `quadraticCurveTo` 和 `bezierCurveTo`;以及通过 `ImageData` 对象操作像素数据,实现图像反色、黑白、亮度调整等特效。此外,还介绍了性能优化的马赛克效果实现技巧和渐变滤镜效果。结合代码示例与实际效果,帮助开发者掌握 Canvas 更多实用功能。

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

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

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

createPattern

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

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

参数名 类型 必填 说明
image ImageBitmap 图源对象,具体参考 ImageBitmap 对象。
repetition string \ null 设置图像重复的方式:'repeat':沿 x 轴和 y 轴重复绘制图像;'repeat-x':沿 x 轴重复绘制图像;'repeat-y':沿 y 轴重复绘制图像;'no-repeat':不重复绘制图像;'clamp':在原始边界外绘制时,超出部分使用边缘的颜色绘制;'mirror':沿 x 轴和 y 轴重复翻转绘制图像。

提前准备好图片

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

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

参数名 类型 必填 说明
cpx number 贝塞尔参数的 x 坐标值。默认单位:vp。
cpy number 贝塞尔参数的 y 坐标值。默认单位:vp。
x number 路径结束时的 x 坐标值。默认单位:vp。
y number 路径结束时的 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

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

参数名 类型 必填 说明
cp1x number 第一个贝塞尔参数的 x 坐标值。默认单位:vp。
cp1y number 第一个贝塞尔参数的 y 坐标值。默认单位:vp。
cp2x number 第二个贝塞尔参数的 x 坐标值。默认单位:vp。
cp2y number 第二个贝塞尔参数的 y 坐标值。默认单位:vp。
x number 路径结束时的 x 坐标值。默认单位:vp。
y number 路径结束时的 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. 数学曲线之一:贝塞尔曲线
  2. 神奇 canvas 带你实现魔法摄像头
  3. ImageData
目录
相关文章
|
28天前
|
存储 调度 开发者
HarmonyOS Next 实战卡片开发 03
本文详细介绍了基于 HarmonyOS Next 的卡片开发实战,涵盖从项目创建到功能实现的全流程。首先通过新建项目和服务卡片搭建基础框架,并设置沉浸式体验优化界面。接着实现了首页轮播图功能,包括申请网络权限、初始化数据和构建轮播组件。随后深入讲解了卡片 id 的处理,涉及获取、返回、持久化存储及移除操作,确保卡片与应用间的高效通信。此外,封装了下载图片工具类,支持卡片发起通知获取网络图片,增强功能扩展性。最后实现了卡片同步轮播功能,使首页与卡片轮播状态保持一致。整个流程注重细节,结合实际案例,为开发者提供了全面的参考。
75 20
HarmonyOS Next 实战卡片开发 03
|
29天前
|
移动开发 JavaScript API
HarmonyOS Next 简单上手元服务开发
本文介绍了 HarmonyOS Next 中元服务的开发流程与关键特性。元服务是一种轻量级应用程序形态,支持免安装、秒开直达,适用于听音乐、打车等场景,大幅提升服务获取效率。文章详细讲解了元服务的开发旅程,包括在 AGC 平台上新建项目、修改名称与图标、新增卡片等内容,并提供了代码示例,如 AtomicServiceTabs 的 tab 切换和标题设置、AtomicServiceNavigation 的路由管理等。此外,还探讨了 AtomicServiceWeb 的使用方法,涵盖鸿蒙页面与 h5 页面的数据传递及方法调用。
108 20
HarmonyOS Next 简单上手元服务开发
|
28天前
HarmonyOS Next 实战卡片开发 02
本文介绍了 HarmonyOS Next 实战中卡片开发的图片显示技术,包括本地图片和网络图片的处理方法。对于本地图片,通过截图、选择图片、复制到临时目录并传递给卡片组件完成显示;而对于网络图片,则需申请网络权限,下载图片至本地后再按本地图片流程处理。文中详细展示了代码实现步骤与关键点,如使用 `PhotoViewPicker` 选择图片、`http` 下载网络资源以及通过 `formImages` 传递图片数据,确保图片在卡片中正确显示。
45 14
HarmonyOS Next 实战卡片开发 02
|
29天前
|
开发框架 API 计算机视觉
鸿蒙元服务实战-笑笑五子棋(5)
本文介绍了鸿蒙元服务实战项目“笑笑五子棋”的最后一部分,主要包括卡片制作与发布上架流程。通过 Form Kit 框架,实现静态与动态卡片的开发,详细讲解了卡片生命周期、功能页面设计及配置文件设置。文章还展示了如何完成卡片内的五子棋逻辑,包括绘制棋盘、处理落子和胜负判断等核心功能。最后,说明了发布上架的步骤,如设置图标、配置证书及打包 Hap 文件。附有参考链接和代码仓库,方便读者深入学习。至此,“笑笑五子棋”从开发到上线全流程完毕。
60 12
鸿蒙元服务实战-笑笑五子棋(5)
|
29天前
|
前端开发
鸿蒙元服务实战-笑笑五子棋(4)
本文介绍了基于鸿蒙元服务开发的“笑笑五子棋”项目第四部分的核心实现。主要涵盖五子棋的基本逻辑,包括沉浸式设计、AtomicServiceTabs组件使用、棋盘绘制、点击下棋逻辑以及输赢判断等功能。
49 8
鸿蒙元服务实战-笑笑五子棋(4)
|
28天前
|
自然语言处理 JavaScript 数据管理
HarmonyOS Next 实战卡片开发 01
本文详细介绍了 HarmonyOS Next 中的卡片开发,涵盖基本概念、类型、创建、配置、能力支持、生命周期及通信等内容。Form Kit 提供将应用重要信息前置到服务卡片的功能,减少跳转层级,适用于嵌入系统应用(如桌面),支持拉起页面与发送消息等交互。卡片分为静态与动态两种类型,分别适用于不同刷新需求场景。
43 0
HarmonyOS Next 实战卡片开发 01
|
26天前
|
前端开发
鸿蒙开发:使用Rect绘制矩形
几何矩形,在实际的开发中,有多种的实现方式,并非一定需要Rect组件,但是,如果有需要用到矩形的场景,建议还是使用Rect组件,因为Rect组件自身携带了很多样式属性,可以满足我们日常的不同的需求。
鸿蒙开发:使用Rect绘制矩形
|
26天前
|
人工智能 物联网 Android开发
【04】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-自定义一个设置输入小部件组件-完成所有设置setting相关的页面-优雅草卓伊凡
【04】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-自定义一个设置输入小部件组件-完成所有设置setting相关的页面-优雅草卓伊凡
159 92
|
26天前
|
人工智能 物联网 Android开发
【03】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-在lib目录新建自定义库UtilsLibrary,ComponentLibrary,CommonConstLibrary完成设置SettingsView.ets初始公共类书写-优雅草卓伊凡
【03】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-在lib目录新建自定义库UtilsLibrary,ComponentLibrary,CommonConstLibrary完成设置SettingsView.ets初始公共类书写-优雅草卓伊凡
68 23
【03】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-在lib目录新建自定义库UtilsLibrary,ComponentLibrary,CommonConstLibrary完成设置SettingsView.ets初始公共类书写-优雅草卓伊凡
|
26天前
|
存储 人工智能 物联网
【02】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-登录页面LoginView.ets完成-并且详细解释关于arkui关于 CommonConst, commonColor, InputDataModel-优雅草卓伊凡
【02】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-登录页面LoginView.ets完成-并且详细解释关于arkui关于 CommonConst, commonColor, InputDataModel-优雅草卓伊凡
56 14
【02】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-登录页面LoginView.ets完成-并且详细解释关于arkui关于 CommonConst, commonColor, InputDataModel-优雅草卓伊凡
下一篇
oss创建bucket