import 'dart:async'; import 'dart:typed_data'; import 'package:fis_measure/interfaces/process/items/terms.dart'; import 'package:fis_measure/interfaces/process/items/types.dart'; import 'package:fis_measure/interfaces/process/workspace/application.dart'; import 'package:fis_measure/interfaces/process/workspace/measure_3d_view_controller.dart'; import 'package:fis_measure/process/workspace/measure_3d_view_controller.dart'; import 'package:fis_measure/view/player/controller.dart'; import 'package:fis_measure/view/vid_painter/carotid_vid_painter.dart'; import 'package:flutter/material.dart' hide Image, decodeImageFromList; import 'package:get/get.dart'; import 'package:vid/us/vid_us_image.dart'; import 'package:vid/us/vid_us_unit.dart'; import 'dart:ui'; import '../../interfaces/process/items/item_metas.dart'; class CarotidPlayer extends StatefulWidget { const CarotidPlayer( this.measure3DViewController, { Key? key, }) : super(key: key); final Measure3DViewController measure3DViewController; @override State createState() => _CarotidPlayerState(); } class _CarotidPlayerState extends State { Image? image; int frameIndex = 0; final application = Get.find(); List curColorFilterMatrix = [ 1, 0, 0, 0, 0, // red 0, 1, 0, 0, 0, // green 0, 0, 1, 0, 0, // blue 0, 0, 0, 1, 0, // alpha ]; @override void initState() { final stdSize = widget.measure3DViewController.stdSize; application.loadFrame(VidUsImage(1, stdSize.width.toInt(), stdSize.height.toInt(), Uint8List.fromList([0]))); application.carotid2DSize = Size( widget.measure3DViewController.image4Measure!.width.toDouble(), widget.measure3DViewController.image4Measure!.height.toDouble()); if (application.carotid2DSize.width > stdSize.width || application.carotid2DSize.height > stdSize.height) { application.isAdaptiveCarotid2D = true; } else { application.isAdaptiveCarotid2D = false; } widget.measure3DViewController.onUpdateCarotid2DImage .addListener(_loadCarotidImageBytes); widget.measure3DViewController.updatePlayerMode.addListener(_onModeChanged); loadFrame(widget.measure3DViewController.image4Measure!); super.initState(); } @override void dispose() { application.isAdaptiveCarotid2D = false; widget.measure3DViewController.onUpdateCarotid2DImage .removeListener(_loadCarotidImageBytes); widget.measure3DViewController.updatePlayerMode .removeListener(_onModeChanged); image?.dispose(); super.dispose(); } /// 模式改变触发更新 void _onModeChanged(Object s, MeasureMode mode) { switch (mode) { case MeasureMode.vidMode: break; case MeasureMode.carotid2DMode: loadFrame(widget.measure3DViewController.image4Measure!); break; case MeasureMode.carotid3DMode: break; } } @override void didUpdateWidget(covariant CarotidPlayer oldWidget) { if (oldWidget.measure3DViewController != widget.measure3DViewController) { throw UnsupportedError("[VidTestPlayer] unsupport replace controller."); } super.didUpdateWidget(oldWidget); } void loadFrame(VidUsImage e) async { frameIndex = e.index; final oldImage = image; image = await _loadImage(e.imageData); oldImage?.dispose(); setState(() {}); } void _loadCarotidImageBytes(Object sender, String base64Url) async { print("更新颈动脉2D"); final oldImage = image; image = await getImage(base64Url); oldImage?.dispose(); setState(() {}); } ///从base64Url获取图片 Future getImage(String path) async { var completer = Completer(); var img = NetworkImage(path); img .resolve(const ImageConfiguration()) .addListener(ImageStreamListener((info, _) { completer.complete(info); })); ImageInfo imageInfo = await completer.future; return imageInfo.image; } Future _loadImage(Uint8List bytes) async { final Completer completer = Completer(); decodeVidFromList(bytes, (Image image) => completer.complete(image)); return completer.future; } void decodeVidFromList(Uint8List bytes, ImageDecoderCallback callback) async { ImmutableBuffer.fromUint8List(bytes).then((ImmutableBuffer buffer) async { final ImageDescriptor descriptor = await ImageDescriptor.encoded(buffer); descriptor.instantiateCodec().then((Codec codec) { final Future frameInfo = codec.getNextFrame(); codec.dispose(); return frameInfo; }).then((FrameInfo frameInfo) { buffer.dispose(); descriptor.dispose(); return callback(frameInfo.image); }); }); } @override Widget build(BuildContext context) { return buildBox(context, buildFrameView(context)); } Widget buildBox(BuildContext context, Widget child) { return Container( alignment: Alignment.center, child: child, ); } Widget buildFrameView(BuildContext context) { if (image != null) { final size = MediaQuery.of(context).size; return RepaintBoundary( child: CustomPaint( painter: CarotidVidPainter( image: image!, stdSize: widget.measure3DViewController.stdSize), isComplex: false, //是否为复杂图像(true会缓存) size: size, ), ); } else { return Container(); } } }