HarmonyOS应用开发-手写板(二)

        在前一篇手写板的文章中(HarmonyOS应用开发-手写板-CSDN博客),我们通过使用Path实现了一个基本的手写板,但遗憾的是,无法保存所绘制的图像。在本文中,我们将采用canvas和Path2D来重新构建手写板应用。依然只需几十行代码,就能轻松实现手写功能,并添加清空画布以及保存图片的功能。

一、先上效果图:

二、上代码

import picker from '@ohos.file.picker';
import fs from '@ohos.file.fs';
import buffer from '@ohos.buffer';

@Entry
@Component
struct CanvasPage {
  //手写路径
  @State pathCommands: string = '';
  canvas: CanvasRenderingContext2D = new CanvasRenderingContext2D();
  path2D: Path2D = new Path2D();

  build() {
    Column() {
      Row() {
        //清空画布按钮
        Button("清空")
          .margin(10)
          .onClick(() => {
            //将路径置空
            this.path2D = new Path2D();
            //清空画布
            this.canvas.clearRect(0, 0, this.canvas.width, this.canvas.height);
          })
        Button("保存")
          .onClick(() => {
            this.saveImage();
          })
      }

      Canvas(this.canvas)
        .width('100%')
        .height('100%')
        .onTouch((e) => {
          this.onTouchEvent(e);
        })
    }
  }

  onTouchEvent(event: TouchEvent) {
    //手指按下和移动时的位置转换成像素位置
    let x = (event.touches[0].x);
    let y = (event.touches[0].y);
    switch (event.type) {

    //手指按下
      case TouchType.Down:
      //移动到(x,y)点
        this.path2D.moveTo(x, y);
        break;

    //画线到(x,y)点
      case TouchType.Move:
        this.path2D.lineTo(x, y);
      //画笔颜色
        this.canvas.strokeStyle = "#0000ff";
      //画笔粗细
        this.canvas.lineWidth = 5;
      //画出线段
        this.canvas.stroke(this.path2D);
        break;
      default:
        break;
    }
  }

  saveImage() {
    //文件保存路径
    let uri = '';
    try {
      let PhotoSaveOptions = new picker.PhotoSaveOptions();
      //保存图片默认名称
      PhotoSaveOptions.newFileNames = ['11111.png'];
      let photoPicker = new picker.PhotoViewPicker();
      //调起系统的图片保存功能
      photoPicker.save(PhotoSaveOptions).then((PhotoSaveResult) => {
        uri = PhotoSaveResult[0];
        //获取图片的base64字符串
        let imageStr = this.canvas.toDataURL().split(',')[1];
        //打开文件
        let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
        //base64字符串转成buffer
        const decodeBuffer = buffer.from(imageStr, 'base64').buffer;
        //写入文件
        fs.writeSync(file.fd, decodeBuffer);
        //关闭文件
        fs.closeSync(file);
      }).catch((err: Error) => {
        console.error(err + '');
      })
    } catch (e) {
      console.error(e);
    }
  }
}

在这段代码中,根据功能划分,主要涵盖了三个关键操作:绘制路径、清空画布和保存画布。

一、绘制路径

        在绘制路径方面,代码通过Canvas执行图像绘制,同时借助Path2D定义了具体的绘制路径。手写路径的生成通过记录手指按下和移动的位置实现。具体操作包括:

this.path2D.moveTo(x, y)  // 移动到(x, y)点
this.path2D.lineTo(x, y)  // 画线到(x, y)点

二、清空画布

清空画布的操作分为两步:

1.将路径置空

// 重新生成新的Path2D对象,因为HarmonyOS中的Path2D没有reset方法
this.path2D = new Path2D();  

2.清空canvas

this.canvas.clearRect(0, 0, this.canvas.width, this.canvas.height);

三、保存画布

        保存画布的过程主要由saveImage方法完成,依赖于@ohos.file.picker组件,调用系统的图片保存功能。具体步骤包括:

  1. 通过PhotoViewPickersave方法获取用户选择的保存文件路径。
  2. 利用Canvas的toDataURL()方法将Canvas转换为base64字符串形式的图片。
  3. 通过@ohos.buffer将base64字符串转换为buffer。
  4. 最终,通过@ohos.file.fs将buffer写入文件,文件的路径为之前获取的保存路径。

        这一系列步骤成功实现了将绘制的图像保存为一个完整的图片文件。整体而言,代码清晰地展示了绘制路径、清空画布和保存画布的功能实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/257939.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ArcGIS Pro中去除黑边方法汇总

在有些时候(比如镶嵌栅格后),我们获取到的影像数据可能会有黑边,这里为大家汇总一下在ArcGIS Pro中去除黑边的方法,希望能对你有所帮助。 数据来源 本教程所使用的数据是从水经微图中下载的影像数据,除了…

YOLOv8改进 | 主干篇 | 轻量级网络ShuffleNetV1(附代码+修改教程)

一、本文内容 本文给大家带来的改进内容是ShuffleNetV1,这是一种为移动设备设计的高效CNN架构。它通过使用点群卷积和通道混洗等操作,减少了计算成本,同时保持了准确性,通过这些技术,ShuffleNet在降低计算复杂度的同时…

1.【分布式】分布式事务详解

分布式事务 1.分布式事务是什么?数据库事务 2.分布式事务产生的原因?存储层拆分服务层拆分 3.分布式事务解决方案4.分布式事务有哪些开源组件SeateTCC 分布式服务组件基于消息补偿的最终一致性 5.两阶段提交,三阶段协议详解二阶段提交协议三阶…

长短期记忆(LSTM)神经网络-多输入分类

目录 一、程序及算法内容介绍: 基本内容: 亮点与优势: 二、实际运行效果: 三、部分程序: 四、完整程序下载: 一、程序及算法内容介绍: 基本内容: 本代码基于Matlab平台编译&am…

SpringCloud源码探析(十二)-基于SpringBoot开发自定义中间件

1.概述 中间件是一种介于操作系统和应用软件之间,为应用软件提供服务功能的软件,按功能划分有消息中间件(Kafka、RocketMQ)、通信中间件(RPC通信中间件,dubbo等),应用服务器等。中间…

k8s-ingress特性 9

TLS加密 创建证书 测试访问 auth认证 创建认证文件 rewrite重定向 进入域名时,会自动重定向到hostname.html 示例: 测试 版本的升级迭代,之前利用控制器进行滚动更新,在升级过程中无法做到快速回滚 更加平滑的升级&#xff1…

Axure中继器的使用实现表格的增删改查的自定义文件

目录 一.认识中继器 1.1.什么中继器 1.2. 中继器的组成 1.3.中继器的使用场景 二.中继器进行增删改查 三.十例表格增删改查 还有Axure这个东西许多东西需要我们去发现,我们需要去细心的研究,我们一起加油吧!!!今…

Opencv实验合集——实验四:图片融合

1.概念 图像融合是将两个或多个图像结合在一起,创建一个新的图像的过程。这个过程的目标通常是通过合并图像的信息来获得比单个图像更全面、更有信息量的结果。图像融合可以在许多领域中应用,包括计算机视觉、遥感、医学图像处理等。 融合的方法有很多…

无人机在融合通信系统中的应用

无人驾驶飞机简称“无人机”,是利用无线电遥控设备和自备的程序控制装置操纵的不载人飞行器,现今无人机在航拍、农业、快递运输、测绘、新闻报道多个领域中都有深度的应用。 在通信行业中,无人机广泛应用于交通,救援,消…

第十七章 爬虫scrapy登录与中间件2

文章目录 数据盘区太快会报错,setting中配置延迟 连接提取器

elementui中的el-table,当使用fixed属性时,table主体会遮挡住滚动条的大半部分,导致很难选中。

情况&#xff1a; 解决&#xff1a; el-table加个类&#xff0c;这里取为class"table" 然后是样式部分&#xff1a; <style scoped lang"scss"> ::v-deep.table {// 滚动条高度调整::-webkit-scrollbar {height: 15px;}// pointer-events 的基本信…

监控k8s controller和scheduler,创建serviceMonitor以及Rules

目录 一、修改kube-controller和kube-schduler的yaml文件 二、创建service、endpoint、serviceMonitor 三、Prometheus验证 四、创建PrometheusRule资源 五、Prometheus验证 直接上干货 一、修改kube-controller和kube-schduler的yaml文件 注意&#xff1a;修改时要一个节…

Databend 开源周报第 124 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 新增对 Delta 和…

SpringBlade export-user SQL 注入漏洞复现

0x01 产品简介 SpringBlade 是一个由商业级项目升级优化而来的 SpringCloud 分布式微服务架构、SpringBoot 单体式微服务架构并存的综合型项目。 0x02 漏洞概述 SpringBlade v3.2.0 及之前版本框架后台 export-user 路径存在安全漏洞,攻击者利用该漏洞可通过组件customSqlS…

node.js mongoose中间件(middleware)

目录 简介 定义模型 注册中间件 创建doc实例&#xff0c;并进行增删改查 方法名和注册的中间件名相匹配 执行结果 分析 错误处理中间件 手动抛出错误 注意点 简介 在mongoose中&#xff0c;中间件是一种允许在执行数据库操作前&#xff08;pre&#xff09;或后&…

【AI图集】猫狗的自动化合成图集

猫是一种哺乳动物&#xff0c;通常被人们作为宠物饲养。它们有柔软的毛发&#xff0c;灵活的身体和尖锐的爪子。猫是肉食性动物&#xff0c;主要以肉类为食&#xff0c;但也可以吃一些蔬菜和水果。猫通常在夜间活动&#xff0c;因此它们需要足够的玩具和活动空间来保持健康和快…

【python基础】-- yarn add 添加依赖的各种类型

目录 1、安装 yarn 1.1 使用npm安装 1.2 查看版本 1.3 yarn 淘宝源配置 2、安装命令说明 2.1 yarn add&#xff08;会更新package.json和yarn.lock&#xff09; 2.2 yarn install 2.3 一些操作 2.3.1 发布包 2.3.2 移除一个包 2.3.3 更新一个依赖 2.3.4 运行脚本 …

ASP.NET Core MVC依赖注入理解(极简个人版)

依赖注入 文献来源&#xff1a;《Pro ASP.NET Core MVC》 Adam Freeman 第18章 依赖注入 1 依赖注入原理 所有可能变化的地方都用接口在使用接口的地方用什么实体类通过在ConfigureService中注册解决注册的实体类需要指定在何种生命周期中有效 TransientScopedSingleton 2…

【办公软件】C# NPOI 操作Excel 案例

文章目录 1、加入NPOI 程序集&#xff0c;使用nuget添加程序集2、引用NPOI程序集3、设置表格样式4、excel加载图片5、导出excel 1、加入NPOI 程序集&#xff0c;使用nuget添加程序集 2、引用NPOI程序集 private IWorkbook ExportExcel(PrintQuotationOrderViewModel model){//…

国货之光,复旦发布大模型训练效率工具 CoLLiE,效率显著提升

在这个信息爆炸的时代&#xff0c;大型语言模型&#xff08;LLM&#xff09;成为理解和挖掘文本信息的重要工具。为了更好地适应各种应用场景&#xff0c;对 LLM 进行定制化训练变得至关重要。 在预训练 LLM 的过程中&#xff0c;无论是初学者还是经验丰富的炼丹人士&#xff…