可可图片编辑 HarmonyOS(4)图片裁剪-canvas

前言

可可图片编辑 实现了图片的裁剪功能,效果如图所示。这里的核心技术是使用了canvas。

image-20250826230645973

Canvas 入门

Canvas提供画布组件,用于自定义绘制图形,开发者使用CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象在Canvas组件上进行绘制,绘制对象可以是基础形状、文本、图片等,canvas也可以实现对图片到裁剪,并且还可以把canvas上描绘的图形下载保存成图片。本章节主要讲解下canvas的基本使用。

基本使用

canvas 的基本使用分为 4 步:

  1. 设置是否抗锯齿抗锯齿(Anti - aliasing)是一种在数字图形处理中使用的技术,主要用于减少图像中因为像素有限而产生的锯齿状边缘的现象
  2. 创建画布上下文
  3. 渲染画布组件
  4. 在画布上描绘图案
@Entry
@Component
struct Index {// 1 用来配置CanvasRenderingContext2D对象的参数,包括是否开启抗锯齿,true表明开启抗锯齿。private settings: RenderingContextSettings = new RenderingContextSettings(true)// 2 用来创建CanvasRenderingContext2D对象,通过在canvas中调用CanvasRenderingContext2D对象来绘制。private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)build() {// 3 在canvas中调用CanvasRenderingContext2D对象。Column(){Canvas(this.context).width('100%').height('100%').backgroundColor('#F5DC62').onReady(() => {// 4 可以在这里绘制内容。this.context.strokeRect(50, 50, 200, 150);})}.width('100%').height('100%').justifyContent(FlexAlign.Center)}
}
  1. 效果

image-20250104222001043

canvas 常见用法

canvas 的核心思想是将想要的图形如,直线、圆圈、矩形等图形描绘到画布上。如果想要呈现出比较酷炫的效果,做法是:

  1. 描绘图形
  2. 擦除画布
  3. 计算数值-重新描绘图形
  4. 擦除画布
  5. 。。。

通过以上过程实现动画效果

image-20250104223622772

canvas 的坐标系

在 canvas 中画图形都是基于坐标系来进行的。 左上角为起点。

image-20250104224722034

描绘图形

canvas 中内置的常见的描绘图形的方法有以下:

  1. 直线
  2. 矩形
  3. 弧形
  4. 文本
  5. 图像

直线

描绘直线可以使用:

  1. 定起点 moveTo
  2. 定终点 lineTo
  3. 开始描绘 stroke
this.context.moveTo(10, 10);
this.context.lineTo(100, 100);
this.context.stroke();

image-20250104224216771

矩形

可以使用直线lineTo自己画成一个矩形。也可以直接使用 strokeRect直接生成矩形

lineTo 画矩形

this.context.moveTo(10, 10);
this.context.lineTo(300, 10);
this.context.lineTo(300, 300);
this.context.lineTo(10, 300);
//   自动闭环
this.context.closePath();
//   开始描述 将路径的当前点移回到路径的起点,当前点到起点间画一条直线
this.context.stroke();

image-20250104225516822

strokeRect 画矩形

// this.context.strokeRect(x, y, 宽度, 高度);
this.context.strokeRect(50, 50, 200, 150);

image-20250104225643875

弧形

弧形可以使用 arcarcTo 来描绘

arc

arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean)

参数名类型必填说明
xnumber弧线圆心的 x 坐标值。默认单位:vp。
ynumber弧线圆心的 y 坐标值。默认单位:vp。
radiusnumber弧线的圆半径。默认单位:vp。
startAnglenumber弧线的起始弧度。单位:弧度
endAnglenumber弧线的终止弧度。单位:弧度
counterclockwiseboolean是否逆时针绘制圆弧。true:逆时针方向绘制椭圆。false:顺时针方向绘制椭圆。默认值:false。

这里需要注意的是 arc 使用的单位是弧度不是角度

一圈 = 360角度 =  2 * Math.PI
半圈 = 180角度 =  Math.PI ≈ 3.14

观察以下效果

image-20250104230514600

100,75 是圆心坐标

50 是半径

0 是开始的弧度

6.28 ≈ 2 * Math.PI = 一圈


arc 是从正右方向开始旋转的。

this.context.beginPath();
this.context.arc(100, 75, 50, 0, 3.14 / 2);
this.context.stroke();

image-20250104230945457

arcTo

arcTo(x1: number, y1: number, x2: number, y2: number, radius: number)

参数名类型必填说明
x1number第一个控制点的 x 坐标值。默认单位:vp。
y1number第一个控制点的 y 坐标值。默认单位:vp。
x2number第二个控制点的 x 坐标值。默认单位:vp。
y2number第二个控制点的 y 坐标值。默认单位:vp。
radiusnumber圆弧的圆半径值。默认单位:vp。

image-20250104235451185

this.context.beginPath();
this.context.strokeStyle = "#000000";
this.context.lineWidth = 3;
this.context.moveTo(360, 20);
this.context.arcTo(360, 170, 110, 170, 150);
this.context.stroke();

辅助理解

想象一下,我们有一个起点(即当前路径的最后一个点),然后有三个更多的点:两个控制点 (x1, y1) 和 (x2, y2),以及由 radius

定义的一个圆心。arcTo 会创建一条从起点到第二个控制点 (x2, y2) 的圆弧,这条圆弧是位于以 radius 为半径的圆周上的一部

分。该圆弧会在起点和第一个控制点 (x1, y1) 之间形成一个切线,并且也会在第二个控制点 (x2, y2) 和圆弧的终点之间形成一个切线。

image-20250104234845265

文本

  1. strokeText表示描边的图形
  2. fillText 表示填充的图形,还有其他fillfillRect等也表示填充。

strokeText

  this.context.font = '55px sans-serif'this.context.strokeText("Hello World!", 20, 60)

image-20250104235533508

fillText

this.context.font = '55px sans-serif'
this.context.fillText("Hello World!", 20, 60)

image-20250104235642059

图像

drawImage可以把图像描绘到画布上,很多的在线图形合成效果都可以利用该功能实现

drawImage(image: ImageBitmap | PixelMap, dx: number, dy: number): void

drawImage(image: ImageBitmap | PixelMap, dx: number, dy: number, dw: number, dh: number): void

drawImage(image: ImageBitmap | PixelMap, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void

参数名类型必填说明
imageImageBitmap或PixelMap图片资源,请参考 ImageBitmap 或 PixelMap。
sxnumber裁切源图像时距离源图像左上角的 x 坐标值。image 类型为 ImageBitmap 时,默认单位:vp。image 类型为 PixelMap 时,单位:px。
synumber裁切源图像时距离源图像左上角的 y 坐标值。image 类型为 ImageBitmap 时,默认单位:vp。image 类型为 PixelMap 时,单位:px。
swnumber裁切源图像时需要裁切的宽度。image 类型为 ImageBitmap 时,默认单位:vp。image 类型为 PixelMap 时,单位:px。
shnumber裁切源图像时需要裁切的高度。image 类型为 ImageBitmap 时,默认单位:vp。image 类型为 PixelMap 时,单位:px。
dxnumber绘制区域左上角在 x 轴的位置。默认单位:vp。
dynumber绘制区域左上角在 y 轴的位置。默认单位:vp。
dwnumber绘制区域的宽度。当绘制区域的宽度和裁剪图像的宽度不一致时,将图像宽度拉伸或压缩为绘制区域的宽度。默认单位:vp。
dhnumber绘制区域的高度。当绘制区域的高度和裁剪图像的高度不一致时,将图像高度拉伸或压缩为绘制区域的高度。默认单位:vp。
@Entry
@Component
struct Index {private settings: RenderingContextSettings = new RenderingContextSettings(true)private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)private img: ImageBitmap = new ImageBitmap("/images/example.jpg")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)this.context.drawImage(this.img, 0, 150, 300, 100)this.context.drawImage(this.img, 0, 0, 500, 500, 0, 300, 400, 200)})}.width('100%').height('100%')}
}

image-20250105000141244

canvas 浅尝动态效果 1

const width = px2vp(display.getDefaultDisplaySync().availableWidth) * 0.9;
const height = width;
let x = 0;
let y = 0;
setInterval(() => {this.context.strokeRect(x, y, 100, 100);x++;y++;
}, 20);

PixPin_2025-01-05_00-07-08

canvas 浅尝动态效果 2

const width = px2vp(display.getDefaultDisplaySync().availableWidth) * 0.9;
const height = width;
let x = 0;
let y = 0;
setInterval(() => {// 清理画布this.context.strokeRect(x, y, 100, 100);x++;y++;
}, 20);

PixPin_2025-01-05_00-08-20

canvas 属性 一览

名称说明
fillStyle设置绘制的填充色,支持多种类型及对应创建方式,有默认值。
lineWidth设置绘制线条的宽度,有默认值及取值限制。
strokeStyle设置线条的颜色,支持多种类型及对应创建方式,有默认值。
lineCap指定线端点的样式,有可选值及默认值。
lineJoin指定线段间相交的交点样式,有可选值及默认值。
miterLimit设置斜接面限制值,有默认值及取值限制。
font设置文本绘制中的字体样式,包含多种可选参数及默认值。
textAlign设置文本绘制中的文本对齐方式,有可选值及默认值。
textBaseline设置文本绘制中的水平对齐方式,有可选值及默认值。
globalAlpha设置透明度,有默认值。
lineDashOffset设置画布的虚线偏移量,有默认值。
globalCompositeOperation设置合成操作的方式,有可选值及默认值。
shadowBlur设置绘制阴影时的模糊级别,有默认值及取值限制。
shadowColor设置绘制阴影时的阴影颜色,有默认值。
shadowOffsetX设置绘制阴影时和原有对象的水平偏移值,有默认值。
shadowOffsetY设置绘制阴影时和原有对象的垂直偏移值,有默认值。
imageSmoothingEnabled设置绘制图片时是否进行图像平滑度调整,有默认值。
height表示组件高度,有默认单位。
width表示组件宽度,有默认单位。
imageSmoothingQuality设置图像平滑度,有默认值。
direction设置绘制文字时使用的文字方向,有默认值。
filter设置图像的滤镜,支持多种滤镜效果,有默认值。
canvas获取和 CanvasRenderingContext2D 关联的 Canvas 组件的 FrameNode 实例,
可监听可见状态,默认值为 null。

canvas 方法 一览

名称说明
fillRect推测用于进行图形填充相关操作(通常是填充矩形区域)
strokeRect推测用于绘制矩形边框相关操作(通常是绘制矩形的轮廓)
clearRect推测用于清除指定矩形区域的内容
fillText推测用于对文本进行填充操作(比如设置文本填充颜色等相关样式填充)
strokeText推测用于绘制文本的轮廓相关操作
measureText推测用于测量文本相关的尺寸等属性
stroke一般用于绘制图形的轮廓、线条等(按常规语义理解)
beginPath通常用于开始定义一个新的路径,后续可基于此路径进行图形绘制等操作
moveTo常用来将画笔移动到指定坐标位置,作为绘制路径的起始点等操作
lineTo一般用于从当前画笔位置绘制直线到指定坐标位置,构建路径内容
closePath通常用于闭合当前正在绘制的路径,使路径形成封闭图形
createPattern可能用于创建某种图案(比如重复平铺的图案等)用于绘制等
bezierCurveTo大概率用于绘制贝塞尔曲线,通过控制点来定义曲线形状
quadraticCurveTo推测用于绘制二次贝塞尔曲线,指定控制点来确定曲线走向
arc一般用于绘制圆弧,通过圆心、半径、起始角度、结束角度等参数来定义
arcTo常用来绘制与两条切线相切的圆弧,按给定条件确定圆弧形状
ellipse用于绘制椭圆图形,需指定相关参数如圆心坐标、长半轴、短半轴等
rect可用于绘制矩形,指定矩形的左上角坐标、宽度、高度等参数
fill用于对已绘制的图形或者指定区域进行填充操作
clip可能用于设置裁剪区域,后续绘制内容只在裁剪区域内显示
reset12+从名称看可能是在特定版本(12+)中用于重置某些状态或设置的操作
saveLayer12+在特定版本(12+)里可能用于保存图层相关状态等操作
restoreLayer12+在特定版本(12+)里对应于之前保存图层状态进行恢复的操作
resetTransform推测用于重置图形变换相关的设置(比如旋转、缩放等变换)
rotate用于将图形进行旋转操作,需指定旋转角度等参数
scale用于对图形进行缩放操作,指定横向和纵向的缩放比例
transform一般用于对图形进行多种变换(如平移、旋转、缩放等组合变换)的设置
setTransform可能用于设置图形的变换矩阵,来确定图形的变换情况
getTransform推测用于获取当前图形的变换相关信息(比如变换矩阵等)
translate用于将图形进行平移操作,指定在横、纵坐标方向平移的距离
drawImage通常用于在画布上绘制图像,指定图像源及绘制位置等参数
createImageData可能用于创建图像数据对象(比如像素数据等相关内容)
getPixelMap推测用于获取像素映射相关的数据(比如图像像素的分布等情况)
setPixelMap大概是用于设置像素映射相关数据,改变图像像素表现等
getImageData一般用于获取图像的像素数据等具体信息内容
putImageData通常是将获取到的图像数据(如像素数据)重新应用到画布等位置
setLineDash可能用于设置线条的虚线样式,指定虚线的长度、间隔等参数
getLineDash推测用于获取当前线条所设置的虚线样式相关参数
transferFromImageBitmap从名称看可能是与从图像位图进行数据转移相关操作
toDataURL通常用于将画布等内容转换为可以表示图像数据的 URL 格式
restore一般用于恢复之前保存的某些状态(如画布状态等)
save常用来保存当前画布等相关的状态,以便后续恢复使用
createLinearGradient用于创建线性渐变对象,可用于图形的渐变填充等操作
createRadialGradient用于创建径向渐变对象,定义从中心向外扩散的渐变效果
createConicGradient用于创建圆锥渐变对象,实现类似圆锥形状的渐变效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/95204.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95204.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/95204.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么用PS制作1寸证件照(已解决)

方法/步骤一、按住键盘上的“Ctrl”“O”打开你要制作的照片二、点击裁剪工具 (调整为宽:2.5cm,高:3.5cm,分辨率:300像素),设置之后直接框选出需要剪切保留的位置(使人物居正中), 然后按上面的“√”,以便确认剪裁三、…

Qt libcurl的下载、配置及简单测试 (windows环境)

Qt libcurl的下载、配置及简单测试引言一、libcurl下载二、在Qt Creator中配置三、简单测试引言 curl(Client URL)是一个开源的命令行工具和库,用于传输数据支持多种协议(如HTTP、HTTPS、FTP、SFTP等)。其核心库libcur…

【Python语法基础学习笔记】竞赛常用标准库

前言此系列笔记是拨珠自己的学习笔记,自用为主,学习建议移步其他大佬的专门教程。math库Python 的 math 库是标准库之一,提供了大量数学运算相关的函数,适用于基础数学计算、科学计算等场景。下面详细介绍其使用方法及常用功能&am…

我的项目我做主:Focalboard+cpolar让团队协作摆脱平台依赖

文章目录前言1. 使用Docker本地部署Focalboard1.1 在Windows中安装 Docker1.2 使用Docker部署Focalboard2. 安装Cpolar内网穿透工具3. 实现公网访问Focalboard4. 固定Focalboard公网地址前言 “项目管理软件又涨价了!“小团队负责人小林发愁——刚习惯操作逻辑&…

【3D 入门-4】trimesh 极速上手之 3D Mesh 数据结构解析(Vertices / Faces)

【3D入门-指标篇上】3D 网格重建评估指标详解与通俗比喻【3D入门-指标篇下】 3D重建评估指标对比-附实现代码【3D 入门-3】常见 3D 格式对比,.glb / .obj / .stl / .ply Mesh 数据结构解析 1. Vertices(顶点) original_vertices mesh_ful…

无需服务器,免费、快捷的一键部署前端 vue React代码--PinMe

作为前端的开发,有时候想部署一个项目真的是很“受气”,要不就是找运维,或者后端,看别人的时间,或者走流程。 现在,有这么一个神器PinMe, 以前部署项目:自己买服务器?域名、 SSL、N…

【LeetCode_26】删除有序数组中的重复项

刷爆LeetCode系列LeetCode26题:github地址前言题目描述题目与思路分析代码实现算法代码优化LeetCode26题: github地址 有梦想的电信狗 前言 本文介绍用C实现leetCode第26题题目链接:https://leetcode-cn.com/problems/remove-duplicates-…

CMake构建学习笔记23-SQLite库的构建

1. 构建思路 在前文中构建了大量的库包程序(参看CMake构建学习笔记-目录)之后,可以总结一下在Windows下使用脚本构建程序的办法: 使用CMake构建。这是目前最通用最流行的构建方式,大部分C/C程序都在逐渐向这个方向转…

Watt Toolkit下载安装并加速GitHub

一、下载 官方地址:(Steam++官网) - Watt Toolkit Gitee下载地址:https://gitee.com/rmbgame/SteamTools/releases/tag/3.0.0-rc.16

DevOps运维与开发一体化及Kubernetes运维核心详解

前言: 在云原生时代,技术的融合与流程的重构已成为驱动业务创新的核心引擎。Kubernetes作为容器编排的事实标准,其稳定的运维能力是业务应用的基石;而DevOps所倡导的开发与运维一体化文化,则是实现快速交付和价值流动的…

HQX SELinux 权限问题分析与解决

Google自Android 5.0起强制实施的SELinux安全子系统,通过最小权限原则显著提升了系统安全性,但这也导致开发过程中频繁出现权限拒绝问题。值得注意的是,即便设备已获取root权限,SELinux的强制访问控制机制仍会限制部分敏感操作。 …

SpringBoot集成Kafka实战应用

目录 使用Kafka-Client实现消息收发 引入依赖 发送端: 消费端: SpringBoot集成 引入maven依赖 消费端 在上一篇我们深度解析了Kafka的运行操作原理以及集群消息消费机制等,请点击下方链接获取 Kafka消息队列深度解析与实战指南 本篇我…

单元测试总结2

1、重载和重写的区别01、定义不同:重载是在同一个类中定义多个方法名相同但参数列表不同的方法;重写是子类对父类中同名同参数列表的方法进行重新实现02、范围不同:重载发生在同一个类中,重写发生在子类和父类中03、参数要求不同&…

Wi-Fi技术——MAC特性

有线和无线网络在数据链路层的特性存在差异,具体为: CSMA/CD 用于有线网络,通过检测和处理冲突来维持网络的稳定性。CSMA/CA 用于无线网络,强调冲突的预防,以应对无线信道共享的挑战 1 有线网 CSMA/CD 有线网 CSMA/…

OpenHarmony 分布式感知中枢深度拆解:MSDP 框架从 0 到 1 的实战指南

MSDP设备状态感知框架技术开发文档 1. 系统概述 1.1 框架定位 MSDP (Multi-Sensor Data Processing) 设备状态感知框架是OpenHarmony系统中负责设备状态识别和分发的核心服务,基于多传感器融合技术,为系统应用提供设备状态感知能力。 1.2 核心功能 静止状态识别:基于加速…

图像 OSD层数据 显示--OSD LOGO单色黑色显示,按区域大小申请MMZ内存的优缺点分析

在监控摄像机、嵌入式显示设备等场景中,OSD(On-Screen Display,屏幕显示)LOGO 常需单色黑色显示,且按区域大小申请 MMZ(Multi-Media Zone,多媒体专用内存)内存,该方案的优缺点需结合硬件资源、显示效率、功能适配性等维度综合分析,具体如下: 一、核心优势:针对性优…

徐真妍最新杂志封面大片曝光,探索镜头下的多面魅力

近日,青年演员徐真妍拍摄的一组大片正式曝光。这组以 “森林系” 为主题的大片,登上时尚杂志《慵懒LAZY DAYS》8-9月刊封面。融合了优雅与现代先锋感,展现了徐真妍甜美温婉的表现力。镜头前的她,在多种风格间自如切换,…

广度优先搜索(BFS, Breadth-First Search)

好的,我给你讲 广度优先搜索(BFS, Breadth-First Search),并配一个直观例子。1️⃣ 什么是广度优先广度优先搜索的特点:按层访问:先访问根节点,然后访问它的直接子节点,再访问子节点…

GD32入门到实战22--红外NEC通信协议

ir_drv.c红外传输协议地位在前&#xff0c;所以我们可以这样保存数据到数组假使接收到1就>>1再|0x80&#xff0c;如果接收到0就>>1新建红外驱动层代码ir_drv.c#include <stdio.h> #include "gd32f30x.h" #include <stdbool.h> static voi…

zkML-JOLT——更快的ZK隐私机器学习:Sumcheck +Lookup

1. 引言 ICME团队开源的zkML项目&#xff1a; https://github.com/ICME-Lab/jolt-atlas&#xff08;Rust&#xff09; zkML-JOLT&#xff08;JOLT ‘Atlas’&#xff09;构建在a16z Crypto团队的JOLT研究和实现基础上&#xff0c;其性能比其他zkML项目快了3到7倍。 a16z Cr…