HarmonyOS 鸿蒙Next中利用组件滚动拼接实现滚动截屏
HarmonyOS 鸿蒙Next中利用组件滚动拼接实现滚动截屏
- 工具里面需要UIContext,需要在entrybility里面保存
let uiContext: UIContext | undefined = windowStage.getMainWindowSync().getUIContext();
AppStorage.setOrCreate('uiContext', uiContext);
- 设置截图组件的id
list_id = 'List_ID'
- 滚动截图
/**************begin snap****************/
private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
private scroller: Scroller = new Scroller();
private listComponentWidth: number = 0;
private listComponentHeight: number = 0;
private curYOffset: number = 0;
private scrollHeight: number = 0;
private yOffsetBefore: number = 0;
private isClickStop: boolean= false;
@State isEnableScroll: boolean = true;
@StorageLink('screenWidth') screenWidth: number = 0;
@StorageLink('screenHeight') screenHeight: number = 0;
@State snapPopupPosition: Position = { x: 0, y: 0 };
@State mergedImage: PixelMap | undefined = undefined;
private areaArray: image.PositionArea[] = [];
private scrollYOffsets: number[] = [];
//滚动截图的入口方法
async scrollSnapshot() {
// The settings list cannot be manually scrolled during the screenshot process
// to avoid interference with the screenshot
this.isEnableScroll = false;
// Saves the current location of the component for recovery
this.yOffsetBefore = this.curYOffset;
// Set the prompt pop-up to be centered
this.snapPopupPosition = PopupUtils.calcPopupCenter(this.screenWidth, this.screenHeight, 100, 200);
await this.scrollSnapAndMerge();
// [StartExclude context]
// Open the prompt pop-up window
this.isShowPreview = true;
// Initial variable after stitching
await this.afterGeneratorImage();
// [EndExclude context]
this.isEnableScroll = true;
this.isClickStop = false;
}
//滚动拼接
async scrollSnapAndMerge() {
// Record an array of scrolls
this.scrollYOffsets.push(this.curYOffset - this.yOffsetBefore);
// Call the API for taking screenshots to obtain the current screenshots
const pixelMap = await this.getUIContext().getComponentSnapshot().get(this.LIST_ID);
// Gets the number of bytes per line of image pixels.
let area: image.PositionArea =
await ImageUtils.getSnapshotArea(pixelMap, this.scrollYOffsets, this.listComponentWidth, this.listComponentHeight)
this.areaArray.push(area);
// During the loop, it is determined whether the bottom is reached, and the user does not stop taking screenshots
if (!this.scroller.isAtEnd() && !this.isClickStop) {
// Scroll to the next page without scrolling to the end
CommonUtils.scrollAnimation(this.scroller, 1000, this.scrollHeight);
await CommonUtils.sleep(1500);
await this.scrollSnapAndMerge();
} else {
// After scrolling to the bottom, the buffer obtained by each round of scrolling is spliced
// to generate a long screenshot
this.mergedImage =
await ImageUtils.mergeImage(this.areaArray, this.scrollYOffsets[this.scrollYOffsets.length - 1],
this.listComponentWidth, this.listComponentHeight);
}
}
//完成拼接
async afterGeneratorImage() {
// Delay for transition animation
await CommonUtils.sleep(200);
this.snapPopupPosition = PopupUtils.calcPopupBottomLeft(this.screenHeight, 200);
this.componentMaskImage = undefined;
this.scrollYOffsets.length = 0;
this.areaArray.length = 0;
}
/**************end snap****************/
更多关于HarmonyOS 鸿蒙Next中利用组件滚动拼接实现滚动截屏的实战教程也可以访问 https://www.itying.com/category-93-b0.html
2 回复
在HarmonyOS NEXT中,可通过ScrollView组件嵌套内容组件实现滚动截屏。使用ScrollView的scrollBy方法控制滚动位移,结合PixelMap.createFromSurface获取每帧图像。利用Image.Packer将多帧图像拼接为长图。关键代码:
// 创建ScrollView
let scrollView = new ScrollView();
// 设置滚动回调
scrollView.onScroll(() => {
// 截取当前帧
let pixelMap = pixelMapCreator.createPixelMap();
// 拼接图像
imagePacker.addImage(pixelMap);
});
// 触发滚动
scrollView.scrollBy(0, offset);
需在config.json中声明"ohos.permission.CAPTURE_SCREEN"权限。
更多关于HarmonyOS 鸿蒙Next中利用组件滚动拼接实现滚动截屏的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
这是一个很好的HarmonyOS Next滚动截屏实现方案。我来分析下关键点:
-
核心实现思路是通过Scroller组件控制滚动,在每次滚动后调用getComponentSnapshot()获取当前屏幕截图,最后使用mergeImage()拼接成长图。
-
几个关键步骤:
- 初始化时获取UIContext和组件尺寸
- scrollSnapshot()作为入口方法,禁用手动滚动
- scrollSnapAndMerge()递归实现滚动和截图
- 使用PositionArea记录每张截图的位置信息
- 滚动到底部或用户停止时进行图片拼接
- 需要注意的细节:
- 滚动过程中需要禁止用户交互(isEnableScroll)
- 要记录滚动偏移量(scrollYOffsets)
- 适当添加延时保证滚动和截图完成
- 完成后重置状态变量
这个方案实现了完整的滚动截屏流程,代码结构清晰,通过递归调用实现了自动滚动和截图。对于需要长截图的场景很有参考价值。