自定义生成图像Bitmap并实时绘制到页面布局
数据由AI生成。
功能概述
本示例演示如何在鸿蒙OS API12+中使用ArkUI实现以下功能:
自定义生成图像Bitmap
实时绘制到页面布局中
图像默认铺满所在布局
实现触摸移动图像中的点或线的操作
完整代码实现
// 导入必要的模块
import { Bitmap, PixelMap, image } from '@kit.ImageKit';
import { drawing } from '@kit.ArkGraphics2D';
import { display } from '@kit.ArkUI';
@Component
struct DrawingCanvas {
// 定义画布尺寸
private canvasWidth: number = 0;
private canvasHeight: number = 0;
// 定义绘制对象
private pixelMap: PixelMap | null = null;
private drawingContext: drawing.DrawingContext | null = null;
// 定义可移动的点
private points: Array<{ x: number, y: number }> = [
{ x: 100, y: 100 },
{ x: 200, y: 200 }
];
// 定义选中的点索引
private selectedPointIndex: number = -1;
// 定义触摸事件处理
private touchHandler: (event: TouchEvent) => void = (event) => {
if (event.type === TouchType.Down || event.type === TouchType.Move) {
const touchX = event.touches[0].x;
const touchY = event.touches[0].y;
// 检查是否点击了点
if (event.type === TouchType.Down) {
this.selectedPointIndex = -1;
for (let i = 0; i < this.points.length; i++) {
const distance = Math.sqrt(
Math.pow(touchX - this.points[i].x, 2) +
Math.pow(touchY - this.points[i].y, 2)
);
if (distance < 30) { // 30像素的点击范围
this.selectedPointIndex = i;
break;
}
}
}
// 移动选中的点
if (this.selectedPointIndex >= 0) {
this.points[this.selectedPointIndex].x = touchX;
this.points[this.selectedPointIndex].y = touchY;
this.redrawCanvas();
}
}
};
// 初始化画布
aboutToAppear() {
// 获取屏幕尺寸
const displayInfo = display.getDefaultDisplaySync();
this.canvasWidth = displayInfo.width;
this.canvasHeight = displayInfo.height;
// 创建PixelMap
this.createPixelMap();
}
// 创建PixelMap
private createPixelMap() {
const imageInfo: image.ImageInfo = {
size: {
height: this.canvasHeight,
width: this.canvasWidth
},
pixelFormat: image.PixelFormat.RGBA_8888,
alphaType: image.AlphaType.IMAGE_ALPHA_TYPE_OPAQUE
};
const initialPixels = new ArrayBuffer(this.canvasWidth * this.canvasHeight * 4);
image.createPixelMap(imageInfo, initialPixels).then((pixelMap: PixelMap) => {
this.pixelMap = pixelMap;
this.redrawCanvas();
});
}
// 重绘画布
private redrawCanvas() {
if (!this.pixelMap) return;
// 创建DrawingContext
drawing.createDrawingContext(this.pixelMap).then((context: drawing.DrawingContext) => {
this.drawingContext = context;
// 清空画布
this.drawingContext.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
// 绘制背景
this.drawingContext.fillStyle = '#FFFFFF';
this.drawingContext.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
// 绘制连接线
this.drawingContext.strokeStyle = '#0000FF';
this.drawingContext.lineWidth = 2;
this.drawingContext.beginPath();
this.drawingContext.moveTo(this.points[0].x, this.points[0].y);
this.drawingContext.lineTo(this.points[1].x, this.points[1].y);
this.drawingContext.stroke();
// 绘制点
this.drawingContext.fillStyle = '#FF0000';
this.points.forEach(point => {
this.drawingContext.beginPath();
this.drawingContext.arc(point.x, point.y, 10, 0, Math.PI * 2);
this.drawingContext.fill();
});
// 更新UI
this.pixelMap = this.drawingContext.getPixelMap();
});
}
build() {
Column() {
// 绘制区域
Stack() {
// 背景层
Column()
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
// 图像层
if (this.pixelMap) {
Image(this.pixelMap)
.width('100%')
.height('100%')
.objectFit(ImageFit.Fill)
.onTouch(this.touchHandler)
}
}
.width('100%')
.height('100%')
}
.width('100%')
.height('100%')
}
}
@Entry
@Component
struct Index {
build() {
Column() {
DrawingCanvas()
}
.width('100%')
.height('100%')
}
}
代码说明
1. 图像创建与绘制
PixelMap创建:
使用
image.createPixelMap()
创建指定尺寸的PixelMap设置像素格式为RGBA_8888以获得彩色图像支持
绘图上下文:
通过
drawing.createDrawingContext()
获取绘图上下文使用标准的Canvas 2D API进行绘制操作
2. 触摸交互实现
触摸事件处理:
监听
onTouch
事件处理触摸操作检测触摸点是否在可移动点附近(30像素范围内)
更新选中点的位置并重绘
点移动逻辑:
在
TouchType.Down
时检测是否选中点在
TouchType.Move
时更新选中点位置
3. 图像显示
布局设置:
使用
Stack
布局叠加背景和图像Image
组件使用objectFit(ImageFit.Fill)
确保图像铺满容器
实时更新:
每次修改后调用
redrawCanvas()
重绘通过更新
pixelMap
触发UI刷新
扩展建议
性能优化:
对于复杂绘图,考虑使用
OffscreenCanvas
进行离屏渲染实现双缓冲技术减少闪烁
功能增强:
添加多点触摸支持
实现线条的添加和删除功能
添加撤销/重做功能
视觉效果:
为可移动点添加悬停效果
实现平滑的动画过渡
这个示例提供了完整的实现框架,您可以根据实际需求进行修改和扩展。