HarmonyOS鸿蒙Next中组件截屏传递问题

发布于 1周前 作者 phonegap100 来自 鸿蒙OS

HarmonyOS鸿蒙Next中组件截屏传递问题 我通过 componentSnapshot.get 方法,获取到了组件的截屏,是个 image.PixelMap,我在同一个页面上展示,没有问题,但是我希望在一个弹框中展示,就展示不出来了,请问该怎么做?我试过两个方法,一个是直接传 pixelMap,一个是传 ArrayBuffer,都不行。测试代码如下:

@CustomDialog
struct CustomDialogComponent {
  controller?: CustomDialogController // 将这里用 @Prop 或者 @Link,不传 buffer,也不行
  @State pixelMap: image.PixelMap | undefined = undefined
  @Prop text: string | undefined
  @Link @Watch('onUpdate') buffer: ArrayBuffer | undefined
  @Prop options: image.InitializationOptions | undefined

  onUpdate() {
    if (this.buffer) {
      // 打断点看,这里都走进来了,但是没走 callback 了,所以 pixelMap 得不到 
      image.createPixelMap(this.buffer, this.options, (error: BusinessError, pixelMap: image.PixelMap) => {
        if (!error) {
          this.pixelMap = pixelMap
        }
      })
    }
  }

  aboutToAppear() {
    this.onUpdate()
  }

  build() {
    Column() {
      Text(this.text).width('100%').height(50).textAlign(TextAlign.Center).fontColor(Color.Green)
      Image(this.pixelMap).width(200).height(500).objectFit(ImageFit.Contain)
      Button('关闭')
        .width(100)
        .height(45)
        .backgroundColor('#ffcc0000')
        .onClick(() => {
          this.controller?.close()
        })
        .margin({ top: 10 })
    }
  }
}

@Entry
@Component
struct SnapShotExample {
  @State items: string[] =
    ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20',
      '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32']
  @State pixMap: image.PixelMap | undefined = undefined
  @State mText: string = '我是内容'
  @State buffer: ArrayBuffer | undefined = undefined
  @State options: image.InitializationOptions | undefined =
    undefined
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogComponent({ buffer: this.buffer, options: this.options, text: this.mText })
  })

  build() {
    Column() {
      Text('我是标题')
        .width('100%')
        .height(100)
        .textAlign(TextAlign.Center)
        .fontColor(Color.Black)
        .backgroundColor(Color.Gray)
      Scroll() {
        Column() {
          ForEach(this.items, (item: string) => {
            Text('我是内容' + item).width('100%').height(50).fontColor(Color.Red)
          })
        }.width('100%')
      }.width('100%').layoutWeight(1).id('mainScroll')

      Blank()
        .width('100%')
        .height(1)
        .backgroundColor(Color.Black)
      // 这个作为对比测试,是可以的
      Image(this.pixMap).width('100%').layoutWeight(0.5).objectFit(ImageFit.Contain)
      Button('点击截图').width(100).height(45).onClick(() => {
        componentSnapshot.get('mainScroll', { scale: 0.8, waitUntilRenderFinished: true })
          .then((pixMap: image.PixelMap) => {
            // 如果直接用 pixMap 方式,只要这一句,对比测试也是可以的 
            // this.pixMap = pixMap 
            let imageInfo = pixMap.getImageInfoSync()
            imageInfo.pixelFormat
            let de = imageInfo.density
            let stride = imageInfo.stride
            let w = imageInfo.size.width
            let h = imageInfo.size.height
            // 用 buffer 的方式 l
            let buffer = new ArrayBuffer(w * h * 4)
            pixMap.readPixelsToBuffer(buffer).then(() => {
              let options: image.InitializationOptions =
                { editable: true, size: { width: w, height: h }, srcPixelFormat: imageInfo.pixelFormat }
              this.options = options
              this.buffer = buffer
              // 这里用 buffer 方式对比测试,是可以的 
              image.createPixelMap(buffer, options, (error: BusinessError, pixelMap: image.PixelMap) => {
                if (!error) {
                  this.pixMap = pixelMap
                }
              })
              this.dialogController.open()
            }, (e: BusinessError) => {
              console.info('readPixelsToBuffer:' + JSON.stringify(e))
            })
            console.info('截图成功:' + JSON.stringify({
              w: w,
              h: h,
              de: de,
              stride: stride
            }))
            this.mText = '截图成功'
            this.dialogController.open()
          }).catch((err: Error) => {
          console.info('截图失败:' + JSON.stringify(err))
        })
      })
    }.width('100%').height('100%')
  }
}

更多关于HarmonyOS鸿蒙Next中组件截屏传递问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

尝试把buffer删了,然后弹窗中的pixelMap用link修饰,打开弹窗的时候把pixelMap传进去

import { image } from '@kit.ImageKit'
import { componentSnapshot } from '@kit.ArkUI'

@CustomDialog
struct CustomDialogComponent{
  controller?:CustomDialogController
  @Link pixelMap: image.PixelMap|undefined /*= undefined*/
  @Prop text: string|undefined

  build() {
    Column() {
      Text(this.text).width('100%').height(50).textAlign(TextAlign.Center).fontColor(Color.Green)
      Image(this.pixelMap).width(200).height(500).objectFit(ImageFit.Contain)
      Button('关闭').width(100).height(45).backgroundColor('#ffcc0000').onClick(() =>{
        this.controller?.close()
      }).margin({top:10})
    }
  }
}

@Entry
@Component
struct SnapShotExample{
  @State items:string[] = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32']
  @State pixMap:image.PixelMap|undefined = undefined
  @State mText:string = '我是内容'
  dialogController:CustomDialogController = new CustomDialogController({builder:CustomDialogComponent({pixelMap:this.pixMap, text:this.mText})})

  build() {
    Column() {
      Text('我是标题')
        .width('100%').height(100).textAlign(TextAlign.Center).fontColor(Color.Black).backgroundColor(Color.Gray)
      Scroll() {
        Column() {
          ForEach(this.items, (item: string) => {
            Text('我是内容' + item).width('100%').height(50).fontColor(Color.Red)
          })
        }.width('100%')
      }.width('100%').layoutWeight(1).id('mainScroll')
      Blank().width('100%').height(1).backgroundColor(Color.Black)
      Image(this.pixMap).width('100%').layoutWeight(0.5).objectFit(ImageFit.Contain)
      Button('点击截图').width(100).height(45).onClick(() =>{
        componentSnapshot.get('mainScroll', {scale:0.8, waitUntilRenderFinished:true}).then((pixMap:image.PixelMap)=>{
          this.pixMap = pixMap
          this.dialogController.open()
          this.mText = '截图成功'
        }).catch((err:Error)=>{
          console.info('截图失败:'+JSON.stringify(err))
        })
      })
    }.width('100%').height('100%')
  }
}

更多关于HarmonyOS鸿蒙Next中组件截屏传递问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,组件截屏传递问题主要涉及如何获取组件的截屏数据并将其传递给其他模块或应用。鸿蒙提供了PixelMap类来处理图像数据,可以通过ComponentcreateSnapshot方法来获取组件的截屏数据。具体步骤如下:

  1. 获取组件截屏:使用ComponentcreateSnapshot方法,传入PixelMap对象来获取组件的截屏数据。
let pixelMap: image.PixelMap = component.createSnapshot();
  1. 处理截屏数据:获取到PixelMap对象后,可以对其进行进一步处理,如保存到文件或通过网络传输。

  2. 传递截屏数据:截屏数据可以通过IntentAbilityContext传递给其他应用或模块。例如,使用Intent传递PixelMap对象:

let intent = new Intent();
intent.setParam("pixelMap", pixelMap);
context.startAbility(intent);

需要注意的是,PixelMap对象在不同模块间传递时,可能需要通过序列化和反序列化来处理,确保数据的完整性和一致性。此外,截屏操作可能会涉及权限问题,确保在获取截屏数据前已获取相应权限。

以上是鸿蒙Next中组件截屏传递的基本流程,具体实现可根据实际需求调整。

在HarmonyOS(鸿蒙)Next中,组件截屏并传递可以通过使用PixelMapComponentcreateSnapshot方法来实现。首先,获取目标组件的引用,调用createSnapshot生成PixelMap对象,然后通过PixelMap进行图像处理或保存。若需传递截屏数据,可以将PixelMap转换为字节数组或Base64编码,通过Intent、文件共享等方式传递。注意,截屏操作可能涉及UI线程,建议在异步任务中处理以避免卡顿。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!