VidFile.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. using SkiaSharp;
  2. using Dicom.Imaging;
  3. using Vinno.vCloud.Common.Vid2;
  4. using Vinno.vCloud.Common.Vid2.Visuals;
  5. using System.Runtime.InteropServices;
  6. using Dicom;
  7. namespace VidProcessService.Utilities
  8. {
  9. public class VidFile : IDisposable
  10. {
  11. private const int DefaultFrameRate = 0;
  12. private readonly VinnoImageData _vinnoImageData;
  13. public DicomFrameInfo DicomFrameInfo;
  14. private int index = 0;
  15. public VidFile(string targetPath)
  16. {
  17. _vinnoImageData = new VinnoImageData(targetPath, OperationMode.Create);
  18. }
  19. public void AddImages(DicomImage dicomImage)
  20. {
  21. var encoder = new VinnoImageEncoder();
  22. for (int i = 0; i < dicomImage.NumberOfFrames; i++)
  23. {
  24. using (IImage image = dicomImage.RenderImage(i))
  25. {
  26. var bytes = image.As<byte[]>();
  27. using (MemoryStream ms = new MemoryStream(bytes))
  28. {
  29. using (var skiaBitmap = new SKBitmap(dicomImage.Width, dicomImage.Height))
  30. {
  31. var imagePtr = Marshal.AllocHGlobal(bytes.Length);
  32. Marshal.Copy(bytes, 0, imagePtr, bytes.Length);
  33. skiaBitmap.SetPixels(imagePtr);
  34. // var bytes1 = skiaBitmap.Encode(SKEncodedImageFormat.Jpeg, 100).ToArray();
  35. var vinnoImage = encoder.Encode(skiaBitmap);
  36. if (i == 0)
  37. {
  38. DicomFrameInfo.DicomFirstFrameData = vinnoImage.ImageData;
  39. DicomFrameInfo.FrameCount = dicomImage.NumberOfFrames;
  40. }
  41. index++;
  42. var visual = new Vinno2DVisual();
  43. visual.Modes.Add(new VinnoMode("HAR", "HAR", VinnoModeType.Tissue));
  44. visual.ActiveModeType = VinnoModeType.Tissue;
  45. var physicalCoordinateInfo = new VinnoLinearTVTissuePhysicalCoordinate(1, 0, 1, 0, 0);
  46. var logicalCoordinateInfo = new VinnoLogicalCoordinate(false, false,
  47. new VinnoRect(0, 0, 1, 1), VinnoUnit.None, VinnoUnit.None);
  48. visual.PhysicalCoordinates.Add(VinnoVisualAreaType.Tissue, physicalCoordinateInfo);
  49. visual.LogicalCoordinates.Add(VinnoVisualAreaType.Tissue, logicalCoordinateInfo);
  50. vinnoImage.Visuals.Add(visual);
  51. _vinnoImageData.AddImage(vinnoImage);
  52. }
  53. }
  54. }
  55. }
  56. }
  57. /// <summary>
  58. /// Add probe.
  59. /// </summary>
  60. /// <param name="dataSet">Dicom dataset</param>
  61. public void AddProbe(DicomDataset dataSet)
  62. {
  63. var frame = GetFrameRate(dataSet);
  64. var probe = new VinnoProbe("ThirdPart", VinnoProbeType.Linear, new VinnoApplication("ThirdPart", string.Empty, "ThirdPart", "ThirdPart", false), frame);
  65. _vinnoImageData.AddProbe(probe);
  66. }
  67. /// <summary>
  68. /// Add probe.
  69. /// </summary>
  70. /// <param name="dataSet">Dicom dataset</param>
  71. public void AddProbe(int frame)
  72. {
  73. var probe = new VinnoProbe("ThirdPart", VinnoProbeType.Linear, new VinnoApplication("ThirdPart", string.Empty, "ThirdPart", "ThirdPart", false), frame);
  74. _vinnoImageData.AddProbe(probe);
  75. }
  76. public void AddImages(int Width, int Height, byte[] e)
  77. {
  78. if (e == null || e.Length <= 0)
  79. {
  80. return;
  81. }
  82. if (Width <= 0 || Height <= 0)
  83. {
  84. return;
  85. }
  86. VinnoImage vinnoImage = new VinnoImage(index, Width, Height, e);
  87. index++;
  88. var visual = new Vinno2DVisual();
  89. visual.Modes.Add(new VinnoMode("HAR", "HAR", VinnoModeType.Tissue));
  90. visual.ActiveModeType = VinnoModeType.Tissue;
  91. var physicalCoordinateInfo = new VinnoLinearTVTissuePhysicalCoordinate(1, 0, 1, 0, 0);
  92. var logicalCoordinateInfo = new VinnoLogicalCoordinate(false, false,
  93. new VinnoRect(0, 0, 1, 1), VinnoUnit.None, VinnoUnit.None);
  94. visual.PhysicalCoordinates.Add(VinnoVisualAreaType.Tissue, physicalCoordinateInfo);
  95. visual.LogicalCoordinates.Add(VinnoVisualAreaType.Tissue, logicalCoordinateInfo);
  96. vinnoImage.Visuals.Add(visual);
  97. _vinnoImageData.AddImage(vinnoImage);
  98. }
  99. /// <summary>
  100. /// Add extended data.
  101. /// </summary>
  102. /// <param name="dataSet">Dicom dataset.</param>
  103. public void AddExtendedData(DicomDataset dataSet)
  104. {
  105. var extendedData = VinnoExtendedDataGenerator.Generate(dataSet);
  106. _vinnoImageData.ExtendedData = extendedData.ToBytes();
  107. }
  108. public void Dispose()
  109. {
  110. _vinnoImageData.Dispose();
  111. }
  112. private static int GetFrameRate(DicomDataset dataSet)
  113. {
  114. if (dataSet.Contains(DicomTag.CineRate))
  115. {
  116. var cineRate = dataSet.GetSingleValue<int>(DicomTag.CineRate);
  117. if (cineRate > 0)
  118. {
  119. return cineRate;
  120. }
  121. }
  122. if (dataSet.Contains(DicomTag.RecommendedDisplayFrameRate))
  123. {
  124. var recommendedDisplayFrameRate = dataSet.GetSingleValue<int>(DicomTag.RecommendedDisplayFrameRate);
  125. return recommendedDisplayFrameRate > 0 ? recommendedDisplayFrameRate : DefaultFrameRate;
  126. }
  127. return 1;
  128. }
  129. }
  130. public struct DicomFrameInfo
  131. {
  132. public object DicomFirstFrameData;
  133. public int FrameCount;
  134. }
  135. }