积分141 / 贡献0

提问0答案被采纳0文章9

[经验分享] flutter中创建并使用外接纹理的方法 原创

深开鸿_石悌君 显示全部楼层 发表于 5 天前

开发pdf_render插件时对照安卓代码发现其直接在外接纹理上渲染图片。

创建纹理的流程:

private fun allocTex(): Int {
    val surfaceTexture = flutterPluginBinding.textureRegistry.createSurfaceTexture()
    val id = surfaceTexture.id().toInt()
    textures.put(id, surfaceTexture)
    return id
  }

使用纹理的流程

private fun updateTex(args: HashMap<String, Any>): Int {
    ...
    val tex = textures[texId] //allocTex创建的纹理
    ...

    tex.surfaceTexture()?.setDefaultBufferSize(width, height)
    Surface(tex.surfaceTexture()).use {
      val canvas = it.lockCanvas(Rect(0, 0, width, height));

      canvas.drawBitmap(bmp, 0f, 0f, null) //bmp是需要渲染的图片
      bmp.recycle()

      it.unlockCanvasAndPost(canvas)
    }

    return 0
  }

这种场景在OpenHarmony上可以使用PlatformView实现,步骤如下:

自定义PlatformView并定义图片成员变量

export class PdfViewPlatformView extends PlatformView {
  private _pixelMap: image.PixelMap | undefined = undefined;

  getView(): WrappedBuilder<[Params]> {
    return new WrappedBuilder(PdfBuilder)
  }

  dispose(): void {
  }

  getPixelMap(): image.PixelMap | undefined {
    return this._pixelMap;
  }

  setPixelMap(_pixelMap: image.PixelMap | undefined): void {
    this._pixelMap = _pixelMap;
  }
}

自定义Component

@Entry
@Component
struct PDFPreview {
  @Prop params: Params;
  _pixelMap: image.PixelMap | undefined = undefined;

  build() {
    Column(){
      Image(this._pixelMap)
    }
  }
}

@Builder
export function PdfBuilder(params: Params){
  PDFPreview({params: params,_pixelMap: (params.platformView as PdfViewPlatformView).getPixelMap()});
}

实现插件

关键点:

1、onAttachedToEngine时保存platformViewController

2、渲染时调用platformViewController相关接口直接操作

export default class PdfRenderPlugin implements FlutterPlugin, MethodCallHandler {
  ...
  private platformViewController: PlatformViewsController | null = null;

  onAttachedToEngine(binding: FlutterPluginBinding): void {
    this.binding = binding;
    this.methodChannel = new MethodChannel(binding.getBinaryMessenger(), "pdf_render");
    this.methodChannel.setMethodCallHandler(this);

    this.platformViewController = this.binding.getFlutterEngine().getPlatformViewsController();
  }

  allocTex():number {
    const textureRegistry = this.binding.getTextureRegistry();
    const textureId = textureRegistry.getTextureId();
    const surfaceTexture = textureRegistry.registerTexture(textureId);

    this.textures.set(textureId, surfaceTexture);

    const platformView: PdfViewPlatformView = new PdfViewPlatformView();
    this.platformViews.set(textureId, platformView);

    return textureId
  }

  updateTex(call: MethodCall):number {
    ...
    const surfaceTexture = this.textures.get(textureId);

    try {
      //获取创建的纹理并设置图片
      const platformView = this.platformViews.get(textureId);
      platformView!.setPixelMap(pixelMap);
      //调用platformViewController的render函数直接在文理商渲染图片
      this.platformViewController?.render(surfaceTexture?.getSurfaceId(), platformView!, width, height, left, top);
    } catch (e) {
      Log.e(TAG,  "except:" + e.message);
    }
  }
}

参考资料

flutter_pdf_render鸿蒙化代码

如何使用PlatformView

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部