// ignore_for_file: non_constant_identifier_names, constant_identifier_names import 'dart:typed_data'; import 'package:fis_common/event/event_type.dart'; import 'package:fis_measure/interfaces/process/standard_line/pixel_space.dart'; import 'package:fis_measure/interfaces/process/standard_line/standard_line.dart'; import 'package:fis_vid_ext/vid_extended_data.dart'; import 'package:fis_vid_ext/vid_tag.dart'; import 'package:fis_vid_ext/vid_value.dart'; /// 参考线 class StandardLine extends IStandardLine { /// Default Standard Line Physical Length (unit cm) static const double DefaultPhysicsLength = 4.0; /// 0028,0030 PixelSpacing from dicom static final VidTag DicomTagPixelSpacing = VidTag("0028", "0030"); /// 0018, 602E Physical Delta Y static final VidTag DicomTagPhysicalDeltaY = VidTag("0018", "602E"); /// 0018,602C Physical Delta X static final VidTag DicomTagPhysicalDeltaX = VidTag("0018", "602C"); /// 0018, 6024 Physical Units X static final VidTag DicomTagPhysicalUnitsX = VidTag("0018", "6024"); /// 0018, 6026 Physical Units Y static final VidTag DicomTagPhysicalUnitsY = VidTag("0018", "6026"); PixelSpacing _currentPixelSpacing = PixelSpacing(); double _physicsLength = DefaultPhysicsLength; double _pixelLength = 0.0; double _perPixelPhysicalLength = 0.0; StandardLine() { pixelSpacingChanged = FEventHandler(); } /// 参考线物理长度(cm) @override double get physicsLength => _physicsLength; @override set physicsLength(double val) { if (val != _physicsLength) { _physicsLength = val; _onLineLengthChanged(); } } /// 参考线像素长度 @override double get pixelLength => _pixelLength; @override set pixelLength(double val) { if (val != _pixelLength) { _pixelLength = val; _onLineLengthChanged(); } } /// 单位像素物理长度(cm) @override double get perPixelPhysicalLength => _perPixelPhysicalLength; /// 当前像素距离尺 @override PixelSpacing get currentPixelSpacing => _currentPixelSpacing; @override set currentPixelSpacing(PixelSpacing val) { if (val != _currentPixelSpacing) { _currentPixelSpacing = val; _onPixelSpacingChanged(); } } /// 像素距离尺变化事件 @override late final FEventHandler pixelSpacingChanged; /// 通过vid扩展信息加载像素距离信息 void loadFromVidExtData(Uint8List bytes) { final extInfo = VidExtendedData.fromBytes(bytes); if (extInfo == null) { currentPixelSpacing = PixelSpacing(); return; } PixelSpacing pixelSpacing = PixelSpacing(); var pixelSpacingValue = _getVidValueByTag(DicomTagPixelSpacing, extInfo); if (pixelSpacingValue != null) { var pixelSpacingArray = pixelSpacingValue.getValue().toString().split('\\'); if (pixelSpacingArray.length > 1) { double? pixelSpacingX = double.tryParse(pixelSpacingArray[0]); if (pixelSpacingX != null) { pixelSpacing.physicalDeltaX = pixelSpacingX; } double? pixelSpacingY = double.tryParse(pixelSpacingArray[1]); if (pixelSpacingY != null) { pixelSpacing.physicalDeltaY = pixelSpacingY; } } } else { pixelSpacing.physicalDeltaX = _getPhysicalDeltaX(extInfo); pixelSpacing.physicalDeltaY = _getPhysicalDeltaY(extInfo); } if (pixelSpacing.physicalDeltaX > 0 && pixelSpacing.physicalDeltaX < 1.0 && pixelSpacing.physicalDeltaY > 0 && pixelSpacing.physicalDeltaY < 1.0) { currentPixelSpacing = pixelSpacing; } else { currentPixelSpacing = PixelSpacing(); } if (currentPixelSpacing.isEmpty == false) { _initPixelLength(); } } /// 加载初始参考线像素长度 void _initPixelLength() { final pixelsPerCM = 1 / _perPixelPhysicalLength; _pixelLength = pixelsPerCM * physicsLength; } void _onLineLengthChanged() { final physicalDeltaX = physicsLength * 10 / pixelLength; final physicalDeltaY = physicalDeltaX; currentPixelSpacing = PixelSpacing.fill(physicalDeltaX, physicalDeltaY); } void _onPixelSpacingChanged() { _perPixelPhysicalLength = _getPixelLengthWithUnit(currentPixelSpacing.physicalDeltaX); pixelSpacingChanged.emit(this, currentPixelSpacing); } double _getPixelLengthWithUnit(double length) { // if (_mearsureUnit == MearsureUnit.cm) // { length = length / 10; // } return length; } IVidValue? _getVidValueByTag(VidTag vidTag, VidExtendedData extendedData) { var matchKeys = extendedData.data.keys .where((v) => v.group == vidTag.group && v.element == vidTag.element); if (matchKeys.isNotEmpty) { final vidTagKey = matchKeys.first; var vidValue = extendedData.data[vidTagKey]; return vidValue; } return null; } double _getPhysicalDeltaX(VidExtendedData extendedData) { final physicalDeltaXvalue = _getVidValueByTag(DicomTagPhysicalDeltaX, extendedData); if (physicalDeltaXvalue != null) { final physicalUnitsXvalue = _getVidValueByTag(DicomTagPhysicalUnitsX, extendedData); if (physicalUnitsXvalue != null) { var unitsvalue = int.parse(physicalUnitsXvalue.getValue().toString()); if (unitsvalue == 3) { var physicalDeltaX = double.parse(physicalDeltaXvalue.getValue().toString()) * 10; return physicalDeltaX; } } } return 1.0; } double _getPhysicalDeltaY(VidExtendedData extendedData) { final physicalDeltaYvalue = _getVidValueByTag(DicomTagPhysicalDeltaY, extendedData); if (physicalDeltaYvalue != null) { final physicalUnitsYvalue = _getVidValueByTag(DicomTagPhysicalUnitsY, extendedData); if (physicalUnitsYvalue != null) { var unitsvalue = int.parse(physicalUnitsYvalue.getValue().toString()); if (unitsvalue == 3) { var physicalDeltaX = double.parse(physicalDeltaYvalue.getValue().toString()) * 10; return physicalDeltaX; } } } return 1.0; } }