HarmonyOS 鸿蒙Next中可可图片编辑图片裁剪-canvas
HarmonyOS 鸿蒙Next中可可图片编辑图片裁剪-canvas
可可图片编辑 HarmonyOS(4)图片裁剪-canvas
前言
可可图片编辑 实现了图片的裁剪功能,效果如图所示。这里的核心技术是使用了canvas。
Canvas 入门
Canvas提供画布组件,用于自定义绘制图形,开发者使用CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象在Canvas组件上进行绘制,绘制对象可以是基础形状、文本、图片等,canvas也可以实现对图片到裁剪,并且还可以把canvas上描绘的图形下载保存成图片。本章节主要讲解下canvas的基本使用。
基本使用
canvas 的基本使用分为 4 步:
- 设置是否抗锯齿抗锯齿(Anti - aliasing)是一种在数字图形处理中使用的技术,主要用于减少图像中因为像素有限而产生的锯齿状边缘的现象
- 创建画布上下文
- 渲染画布组件
- 在画布上描绘图案
@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)
}
}
- 效果
canvas 常见用法
canvas 的核心思想是将想要的图形如,直线、圆圈、矩形等图形描绘到画布上。如果想要呈现出比较酷炫的效果,做法是:
- 描绘图形
- 擦除画布
- 计算数值-重新描绘图形
- 擦除画布
- 。。。
通过以上过程实现动画效果
canvas 的坐标系
在 canvas 中画图形都是基于坐标系来进行的。 左上角为起点。
描绘图形
canvas 中内置的常见的描绘图形的方法有以下:
- 直线
- 矩形
- 弧形
- 文本
- 图像
- …
直线
描绘直线可以使用:
- 定起点
moveTo
- 定终点
lineTo
- 开始描绘
stroke
this.context.moveTo(10, 10);
this.context.lineTo(100, 100);
this.context.stroke();
矩形
可以使用直线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();
strokeRect 画矩形
// this.context.strokeRect(x, y, 宽度, 高度);
this.context.strokeRect(50, 50, 200, 150);
弧形
弧形可以使用 arc
和 arcTo
来描绘
arc
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean)
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
x | number | 是 | 弧线圆心的 x 坐标值。默认单位:vp。 |
y | number | 是 | 弧线圆心的 y 坐标值。默认单位:vp。 |
radius | number | 是 | 弧线的圆半径。默认单位:vp。 |
startAngle | number | 是 | 弧线的起始弧度。单位:弧度 |
endAngle | number | 是 | 弧线的终止弧度。单位:弧度 |
counterclockwise | boolean | 否 | 是否逆时针绘制圆弧。true:逆时针方向绘制椭圆。false:顺时针方向绘制椭圆。默认值:false。 |
这里需要注意的是 arc 使用的单位是弧度不是角度
一圈 = 360角度 = 2 * Math.PI
半圈 = 180角度 = Math.PI ≈ 3.14
观察以下效果
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();
arcTo
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number)
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
x1 | number | 是 | 第一个控制点的 x 坐标值。默认单位:vp。 |
y1 | number | 是 | 第一个控制点的 y 坐标值。默认单位:vp。 |
x2 | number | 是 | 第二个控制点的 x 坐标值。默认单位:vp。 |
y2 | number | 是 | 第二个控制点的 y 坐标值。默认单位:vp。 |
radius | number | 是 | 圆弧的圆半径值。默认单位:vp。 |
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) 和圆弧的终点之间形成一个切线。
文本
- strokeText表示描边的图形
- fillText 表示填充的图形,还有其他fill,fillRect等也表示填充。
strokeText
this.context.font = '55px sans-serif'
this.context.strokeText("Hello World!", 20, 60)
fillText
this.context.font = '55px sans-serif'
this.context.fillText("Hello World!", 20, 60)
图像
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
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
image | ImageBitmap或PixelMap | 是 | 图片资源,请参考 ImageBitmap 或 PixelMap。 |
sx | number | 是 | 裁切源图像时距离源图像左上角的 x 坐标值。image 类型为 ImageBitmap 时,默认单位:vp。image 类型为 PixelMap 时,单位:px。 |
sy | number | 是 | 裁切源图像时距离源图像左上角的 y 坐标值。image 类型为 ImageBitmap 时,默认单位:vp。image 类型为 PixelMap 时,单位:px。 |
sw | number | 是 | 裁切源图像时需要裁切的宽度。image 类型为 ImageBitmap 时,默认单位:vp。image 类型为 PixelMap 时,单位:px。 |
sh | number | 是 | 裁切源图像时需要裁切的高度。image 类型为 ImageBitmap 时,默认单位:vp。image 类型为 PixelMap 时,单位:px。 |
dx | number | 是 | 绘制区域左上角在 x 轴的位置。默认单位:vp。 |
dy | number | 是 | 绘制区域左上角在 y 轴的位置。默认单位:vp。 |
dw | number | 是 | 绘制区域的宽度。当绘制区域的宽度和裁剪图像的宽度不一致时,将图像宽度拉伸或压缩为绘制区域的宽度。默认单位:vp。 |
dh | number | 是 | 绘制区域的高度。当绘制区域的高度和裁剪图像的高度不一致时,将图像高度拉伸或压缩为绘制区域的高度。默认单位: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%')
}
}
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);
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++;
},
更多关于HarmonyOS 鸿蒙Next中可可图片编辑图片裁剪-canvas的实战教程也可以访问 https://www.itying.com/category-93-b0.html
666 学习了
更多关于HarmonyOS 鸿蒙Next中可可图片编辑图片裁剪-canvas的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
感谢支持,
在HarmonyOS鸿蒙Next中,图片裁剪可通过Canvas组件实现。Canvas提供drawImage方法用于绘制图像,结合Rect区域设置可完成裁剪。开发者需使用Image组件加载图片后,通过CanvasContext调整源图像与目标区域的尺寸和位置参数,实现指定区域的裁剪功能。该过程基于ArkTS声明式开发,无需依赖Java或C语言。
在HarmonyOS Next中使用Canvas实现图片裁剪功能是一个高效且灵活的选择。Canvas组件提供了强大的绘图能力,通过CanvasRenderingContext2D可以精确控制图片的绘制区域,实现裁剪效果。
关键步骤包括:
- 创建Canvas上下文并设置抗锯齿
- 使用drawImage方法绘制图片,通过参数控制裁剪区域(sx, sy, sw, sh)和绘制位置(dx, dy, dw, dh)
- 结合用户交互(如触摸事件)动态调整裁剪区域
- 通过toDataURL或getPixelMap导出裁剪后的图片
需要注意的是,Canvas在HarmonyOS Next中的坐标系以左上角为原点,单位默认使用vp,但在处理PixelMap时需注意px单位的转换。对于性能优化,建议在动画场景中使用requestAnimationFrame替代setInterval。
这种方案适合需要自定义裁剪逻辑的场景,相比系统自带的图片裁剪接口提供了更大的灵活性。