public static DicomDataSet GeneratePresentationState(string seriesInstanceUID, string annotationData, string description, DicomDataSet seriesDs, int windowCenter, int windowWidth, out string sopInstanceUID) { AnnCodecs codec = new AnnCodecs(); using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(annotationData))) { ms.Position = 0; AnnCodecsInfo codecInfo = codec.GetInfo(ms); ms.Position = 0; JavaScriptSerializer jsSerialzer = new JavaScriptSerializer(); DicomAnnotationsUtilities dicomAnnotationsUtilities = new DicomAnnotationsUtilities(); DicomDataSet ds = new DicomDataSet(); sopInstanceUID = SeriesGenerator.GenerateDicomUniqueIdentifier(); //Patient Module C.7.1.1 ds.InsertElementAndSetValue(DicomTag.PatientName, seriesDs.GetValue <string>(DicomTag.PatientName, string.Empty)); ds.InsertElementAndSetValue(DicomTag.PatientID, seriesDs.GetValue <string>(DicomTag.PatientID, string.Empty)); ds.InsertElementAndSetValue(DicomTag.PatientBirthDate, ""); ds.InsertElementAndSetValue(DicomTag.PatientSex, ""); //Study Module C.7.2.1 ds.InsertElementAndSetValue(DicomTag.StudyInstanceUID, seriesDs.GetValue <string>(DicomTag.StudyInstanceUID, string.Empty)); ds.InsertElementAndSetValue(DicomTag.StudyDate, ""); ds.InsertElementAndSetValue(DicomTag.StudyTime, ""); ds.InsertElementAndSetValue(DicomTag.ReferringPhysicianName, ""); ds.InsertElementAndSetValue(DicomTag.StudyID, seriesDs.GetValue <string>(DicomTag.StudyID, string.Empty)); ds.InsertElementAndSetValue(DicomTag.AccessionNumber, seriesDs.GetValue <string>(DicomTag.AccessionNumber, string.Empty)); //Series Module C.7.3.1 ds.InsertElementAndSetValue(DicomTag.SeriesInstanceUID, SeriesGenerator.GenerateDicomUniqueIdentifier()); ds.InsertElementAndSetValue(DicomTag.Modality, "PR"); ds.InsertElementAndSetValue(DicomTag.SeriesNumber, 1); ds.InsertElementAndSetValue(DicomTag.SeriesDate, DicomDateValue.Now); ds.InsertElementAndSetValue(DicomTag.SeriesTime, DicomTimeValue.Now); ds.InsertElementAndSetValue(DicomTag.SeriesDescription, "Study layout presentation state"); //General Equipment Module C.7.5.1 ds.InsertElementAndSetValue(DicomTag.Manufacturer, "LEADTOOLS IMAGING"); ds.InsertElementAndSetValue(DicomTag.InstitutionName, "LEADTOOLS, INC."); ds.InsertElementAndSetValue(DicomTag.StationName, "HTML5 Viewer"); //Presentation State Identification Module C.11.10 ds.InsertElementAndSetValue(DicomTag.PresentationCreationDate, DicomDateValue.Now); ds.InsertElementAndSetValue(DicomTag.PresentationCreationTime, DicomTimeValue.Now); //Content Identification Macro Table 10-12 ds.InsertElementAndSetValue(DicomTag.InstanceNumber, 1); ds.InsertElementAndSetValue(DicomTag.ContentLabel, "STUDY LAYOUT PRESENTATION"); ds.InsertElementAndSetValue(DicomTag.ContentDescription, description); //ds.InsertElementAndSetValue(DicomTag.ContentCreatorName, userName); //Presentation State RelationShip Module C11.11 PresentationStateRelationShip referncedSeriesSeq = new PresentationStateRelationShip(); referncedSeriesSeq.ReferencedSeriesSequence = new List <ReferencedSeries>(); ReferencedSeries referencedSeries = new ReferencedSeries(); referencedSeries.SeriesInstanceUID = seriesInstanceUID; referencedSeries.ReferencedImageSequence = new List <SopInstanceReference>(); referncedSeriesSeq.ReferencedSeriesSequence.Add(referencedSeries); Dictionary <LeadSize, List <ImageSopInstanceReference> > displayedAreaInstance = new Dictionary <LeadSize, List <ImageSopInstanceReference> >(); for (int index = 0; index < codecInfo.Pages.Length; index++) { AnnContainer container = codec.Load(ms, codecInfo.Pages[index]); ms.Position = 0; if (null == container.UserData) { continue; } AnnUserData refInstance = (AnnUserData)jsSerialzer.Deserialize <AnnUserData>(container.UserData.ToString()); if (null != refInstance && null != refInstance.ReferencedImageSequence) { referncedSeriesSeq.ReferencedSeriesSequence[0].ReferencedImageSequence.Add(refInstance.ReferencedImageSequence); // The Medical Viewer defaults dpi to 150 // In this case, there is enough information to compute the dpi, which should be 150 //double dpiX = 0; //double dpiY = 0; //container.CalculateDpi(out dpiX, out dpiY); //if (dpiX == 0 || dpiY == 0) //{ // dpiX = 150.0; // dpiY = 150.0; //} double xDpi = 150; double yDpi = 150; dicomAnnotationsUtilities.ImageDpiX = xDpi; dicomAnnotationsUtilities.ImageDpiY = yDpi; DicomElement graphicSequenceItem = dicomAnnotationsUtilities.FromAnnContainerToDataSet(ds, container); DicomElement layerElement = ds.FindFirstElement(graphicSequenceItem, DicomTag.GraphicLayer, false); if (null == layerElement) { ds.InsertElementAndSetValue(graphicSequenceItem, true, DicomTag.GraphicLayer, "LAYER1"); } else { ds.SetStringValue(layerElement, "LAYER1", DicomCharacterSetType.Default); } GraphicAnnotationsModule annModule = new GraphicAnnotationsModule(); annModule.ReferencedImageSequence = new List <ImageSopInstanceReference>(); annModule.ReferencedImageSequence.Add(refInstance.ReferencedImageSequence); ds.Set(graphicSequenceItem, annModule); } if (!refInstance.ImageSize.IsEmpty) { if (!displayedAreaInstance.ContainsKey(refInstance.ImageSize)) { displayedAreaInstance[refInstance.ImageSize] = new List <ImageSopInstanceReference>(); } displayedAreaInstance[refInstance.ImageSize].Add(refInstance.ReferencedImageSequence); } } ds.Set(referncedSeriesSeq); //Displayed Area Module // // DisplayedAreaModule displayedAreaModule = new DisplayedAreaModule(); displayedAreaModule.DisplayedAreaSelection = new List <DisplayedAreaSelection>(); foreach (KeyValuePair <LeadSize, List <ImageSopInstanceReference> > areaInstance in displayedAreaInstance) { DisplayedAreaSelection displayedArea = new DisplayedAreaSelection(); displayedAreaModule.DisplayedAreaSelection.Add(displayedArea); displayedArea.DisplayedAreaTopLeftHandCorner = new List <long>(); displayedArea.DisplayedAreaBottomRightHandCorner = new List <long>(); displayedArea.DisplayedAreaTopLeftHandCorner.Add(1); displayedArea.DisplayedAreaTopLeftHandCorner.Add(1); displayedArea.DisplayedAreaBottomRightHandCorner.Add(areaInstance.Key.Width); displayedArea.DisplayedAreaBottomRightHandCorner.Add(areaInstance.Key.Height); displayedArea.PresentationSizeMode = PresentationSizeMode.ScaleToFit; displayedArea.PresentationPixelAspectRatio = new List <int>(); displayedArea.PresentationPixelAspectRatio.Add(1); displayedArea.PresentationPixelAspectRatio.Add(1); if (displayedAreaInstance.Count > 1) { displayedArea.ReferencedImageSequence = areaInstance.Value; } } ds.Set(displayedAreaModule); //Graphic Layer Module GraphicLayerModule graphicLayerModule = new GraphicLayerModule(); GraphicLayer layer = new GraphicLayer(); graphicLayerModule.GraphicLayerSequence = new List <GraphicLayer>(); layer.GraphicLayerName = "LAYER1"; layer.GraphicLayerOrder = 1; graphicLayerModule.GraphicLayerSequence.Add(layer); ds.Set(graphicLayerModule); //Softcopy Presentation LUT Module SoftCopyPresentationLutModule presentationLut = new SoftCopyPresentationLutModule(); presentationLut.PresentationLutShape = PresentationLutShape.Identity; if (windowCenter != -1 || windowWidth != -1) { SoftCopyVoiLutModule module = new SoftCopyVoiLutModule(); module.WindowCenter = new List <double>(); module.WindowCenter.Add(windowCenter); module.WindowWidth = new List <double>(); module.WindowWidth.Add(windowWidth); ds.Set(module); } ds.Set(presentationLut); //SOP Common Module ds.InsertElementAndSetValue(DicomTag.SOPClassUID, DicomUidType.GrayscaleSoftcopyPresentationStateStorage); ds.InsertElementAndSetValue(DicomTag.SOPInstanceUID, sopInstanceUID); ds.InsertElementAndSetValue(DicomTag.InstanceCreationDate, DicomDateValue.Now); ds.InsertElementAndSetValue(DicomTag.InstanceCreationTime, DicomDateValue.Now); ds.InsertElementAndSetValue(DicomTag.InstanceNumber, 1); return(ds); } }
public static DicomDataSet GeneratePresentationStateForAnnotations ( string userName, string seriesInstanceUID, string annotationData, string description, string userData, DataSet seriesDs ) { AnnCodecs codec = new AnnCodecs(); using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(annotationData))) { ms.Position = 0; AnnCodecsInfo codecInfo = codec.GetInfo(ms); ms.Position = 0; JavaScriptSerializer jsSerialzer = new JavaScriptSerializer(); DicomAnnotationsUtilities dicomAnnotationsUtilities = new DicomAnnotationsUtilities(); if (null == seriesDs || seriesDs.Tables[DataTableHelper.PatientTableName].Rows.Count == 0 || seriesDs.Tables[DataTableHelper.StudyTableName].Rows.Count == 0) { throw new Exception("Series not found"); } DicomDataSet ds = new DicomDataSet(); { DataRow patient = seriesDs.Tables[DataTableHelper.PatientTableName].Rows[0]; DataRow study = seriesDs.Tables[DataTableHelper.StudyTableName].Rows[0]; IPatientInfo patientInfo = RegisteredDataRows.PatientInfo; PersonNameComponent pn = patientInfo.Name(patient); string sFamilyName = pn.FamilyName; string sGivenName = pn.GivenName; string sMiddleName = pn.MiddleName; string sNamePrefix = pn.NamePrefix; string sNameSuffix = pn.NameSuffix; string sPatientId = patientInfo.GetElementValue(patient, DicomTag.PatientID); //Patient Module C.7.1.1 ds.InsertElementAndSetValue(DicomTag.PatientName, string.Format("{0}^{1}^{2}^{3}^{4}", string.IsNullOrEmpty(sFamilyName) ? "" : sFamilyName, string.IsNullOrEmpty(sGivenName) ? "" : sGivenName, string.IsNullOrEmpty(sMiddleName) ? "" : sMiddleName, string.IsNullOrEmpty(sNamePrefix) ? "" : sNamePrefix, string.IsNullOrEmpty(sNameSuffix) ? "" : sNameSuffix)); ds.InsertElementAndSetValue(DicomTag.PatientID, sPatientId); ds.InsertElementAndSetValue(DicomTag.PatientBirthDate, ""); ds.InsertElementAndSetValue(DicomTag.PatientSex, ""); IStudyInfo studyInfo = RegisteredDataRows.StudyInfo; string sStudyInstanceUid = studyInfo.GetElementValue(study, DicomTag.StudyInstanceUID); string sAccessionNumber = studyInfo.GetElementValue(study, DicomTag.AccessionNumber); string sStudyId = studyInfo.GetElementValue(study, DicomTag.StudyID); //Study Module C.7.2.1 ds.InsertElementAndSetValue(DicomTag.StudyInstanceUID, sStudyInstanceUid); ds.InsertElementAndSetValue(DicomTag.StudyDate, ""); ds.InsertElementAndSetValue(DicomTag.StudyTime, ""); ds.InsertElementAndSetValue(DicomTag.ReferringPhysicianName, ""); ds.InsertElementAndSetValue(DicomTag.StudyID, string.IsNullOrEmpty(sStudyId) ? "" : sStudyId); ds.InsertElementAndSetValue(DicomTag.AccessionNumber, string.IsNullOrEmpty(sAccessionNumber) ? "" : sAccessionNumber); //Series Module C.7.3.1 ds.InsertElementAndSetValue(DicomTag.SeriesInstanceUID, SeriesGenerator.GenerateDicomUniqueIdentifier()); ds.InsertElementAndSetValue(DicomTag.Modality, "PR"); ds.InsertElementAndSetValue(DicomTag.SeriesNumber, 1); ds.InsertElementAndSetValue(DicomTag.SeriesDate, DicomDateValue.Now); ds.InsertElementAndSetValue(DicomTag.SeriesTime, DicomTimeValue.Now); ds.InsertElementAndSetValue(DicomTag.SeriesDescription, "Annotations presentation state"); //General Equipment Module C.7.5.1 ds.InsertElementAndSetValue(DicomTag.Manufacturer, "LEADTOOLS IMAGING"); ds.InsertElementAndSetValue(DicomTag.InstitutionName, "LEADTOOLS, INC."); ds.InsertElementAndSetValue(DicomTag.StationName, "HTML5 Viewer"); //Presentation State Identification Module C.11.10 ds.InsertElementAndSetValue(DicomTag.PresentationCreationDate, DicomDateValue.Now); ds.InsertElementAndSetValue(DicomTag.PresentationCreationTime, DicomTimeValue.Now); //Content Identification Macro Table 10-12 ds.InsertElementAndSetValue(DicomTag.InstanceNumber, 1); ds.InsertElementAndSetValue(DicomTag.ContentLabel, "ANNOTATIONS"); ds.InsertElementAndSetValue(DicomTag.ContentDescription, description); ds.InsertElementAndSetValue(DicomTag.ContentCreatorName, userName); //Presentation State RelationShip Module C11.11 PresentationStateRelationShip referncedSeriesSeq = new PresentationStateRelationShip(); referncedSeriesSeq.ReferencedSeriesSequence = new List <ReferencedSeries>(); ReferencedSeries referencedSeries = new ReferencedSeries(); referencedSeries.SeriesInstanceUID = seriesInstanceUID; referencedSeries.ReferencedImageSequence = new List <SopInstanceReference>(); referncedSeriesSeq.ReferencedSeriesSequence.Add(referencedSeries); Dictionary <LeadSize, List <ImageSopInstanceReference> > displayedAreaInstance = new Dictionary <LeadSize, List <ImageSopInstanceReference> >(); for (int index = 0; index < codecInfo.Pages.Length; index++) { AnnContainer container = codec.Load(ms, codecInfo.Pages[index]); ms.Position = 0; if (null == container.UserData) { continue; } AnnUserData refInstance = (AnnUserData)jsSerialzer.Deserialize <AnnUserData>(container.UserData.ToString()); if (null != refInstance && null != refInstance.ReferencedImageSequence) { referncedSeriesSeq.ReferencedSeriesSequence[0].ReferencedImageSequence.Add(refInstance.ReferencedImageSequence); // The Medical Viewer defaults dpi to 150 // In this case, there is enough information to compute the dpi, which should be 150 //double dpiX = 0; //double dpiY = 0; //container.CalculateDpi(out dpiX, out dpiY); //if (dpiX == 0 || dpiY == 0) //{ // dpiX = 150.0; // dpiY = 150.0; //} double xDpi = 150; double yDpi = 150; dicomAnnotationsUtilities.ImageDpiX = xDpi; dicomAnnotationsUtilities.ImageDpiY = yDpi; DicomElement graphicSequenceItem = dicomAnnotationsUtilities.FromAnnContainerToDataSet(ds, container); DicomElement layerElement = ds.FindFirstElement(graphicSequenceItem, DicomTag.GraphicLayer, false); if (null == layerElement) { ds.InsertElementAndSetValue(graphicSequenceItem, true, DicomTag.GraphicLayer, "LAYER1"); } else { ds.SetStringValue(layerElement, "LAYER1", DicomCharacterSetType.Default); } GraphicAnnotationsModule annModule = new GraphicAnnotationsModule(); annModule.ReferencedImageSequence = new List <ImageSopInstanceReference>(); annModule.ReferencedImageSequence.Add(refInstance.ReferencedImageSequence); ds.Set(graphicSequenceItem, annModule); } if (!refInstance.ImageSize.IsEmpty) { if (!displayedAreaInstance.ContainsKey(refInstance.ImageSize)) { displayedAreaInstance[refInstance.ImageSize] = new List <ImageSopInstanceReference>(); } displayedAreaInstance[refInstance.ImageSize].Add(refInstance.ReferencedImageSequence); } } ds.Set(referncedSeriesSeq); //Displayed Area Module // // DisplayedAreaModule displayedAreaModule = new DisplayedAreaModule(); displayedAreaModule.DisplayedAreaSelection = new List <DisplayedAreaSelection>(); foreach (KeyValuePair <LeadSize, List <ImageSopInstanceReference> > areaInstance in displayedAreaInstance) { DisplayedAreaSelection displayedArea = new DisplayedAreaSelection(); displayedAreaModule.DisplayedAreaSelection.Add(displayedArea); displayedArea.DisplayedAreaTopLeftHandCorner = new List <long>(); displayedArea.DisplayedAreaBottomRightHandCorner = new List <long>(); displayedArea.DisplayedAreaTopLeftHandCorner.Add(1); displayedArea.DisplayedAreaTopLeftHandCorner.Add(1); displayedArea.DisplayedAreaBottomRightHandCorner.Add(areaInstance.Key.Width); displayedArea.DisplayedAreaBottomRightHandCorner.Add(areaInstance.Key.Height); displayedArea.PresentationSizeMode = PresentationSizeMode.ScaleToFit; displayedArea.PresentationPixelAspectRatio = new List <int>(); displayedArea.PresentationPixelAspectRatio.Add(1); displayedArea.PresentationPixelAspectRatio.Add(1); if (displayedAreaInstance.Count > 1) { displayedArea.ReferencedImageSequence = areaInstance.Value; } } ds.Set(displayedAreaModule); //Graphic Layer Module GraphicLayerModule graphicLayerModule = new GraphicLayerModule(); graphicLayerModule.GraphicLayerSequence = new List <GraphicLayer>(); GraphicLayer layer = new GraphicLayer(); layer.GraphicLayerName = "LAYER1"; layer.GraphicLayerOrder = 1; graphicLayerModule.GraphicLayerSequence.Add(layer); ds.Set(graphicLayerModule); //Softcopy Presentation LUT Module SoftCopyPresentationLutModule presentationLut = new SoftCopyPresentationLutModule(); presentationLut.PresentationLutShape = PresentationLutShape.Identity; ds.Set(presentationLut); //SOP Common Module ds.InsertElementAndSetValue(DicomTag.SOPClassUID, DicomUidType.GrayscaleSoftcopyPresentationStateStorage); ds.InsertElementAndSetValue(DicomTag.SOPInstanceUID, SeriesGenerator.GenerateDicomUniqueIdentifier()); ds.InsertElementAndSetValue(DicomTag.InstanceCreationDate, DicomDateValue.Now); ds.InsertElementAndSetValue(DicomTag.InstanceCreationTime, DicomDateValue.Now); ds.InsertElementAndSetValue(DicomTag.InstanceNumber, 1); } return(ds); } }