private static IEnumerable <ISopDataSource> CreateSopSeries(int sopCount,
                                                             string patientId, string patientName,
                                                             string studyId, string studyInstanceUid,
                                                             string seriesDesc, int seriesNumber, string seriesInstanceUid,
                                                             string frameOfReferenceUid, Modality modality,
                                                             bool attnCorrected, bool lossyCompressed)
 {
     for (int n = 0; n < sopCount; n++)
     {
         var dicomFile = new DicomFile();
         var dataset   = dicomFile.DataSet;
         dataset[DicomTags.PatientId].SetStringValue(patientId);
         dataset[DicomTags.PatientsName].SetStringValue(patientName);
         dataset[DicomTags.StudyId].SetStringValue(studyId);
         dataset[DicomTags.StudyInstanceUid].SetStringValue(studyInstanceUid);
         dataset[DicomTags.SeriesDescription].SetStringValue(seriesDesc);
         dataset[DicomTags.SeriesNumber].SetInt32(0, seriesNumber);
         dataset[DicomTags.SeriesInstanceUid].SetStringValue(seriesInstanceUid);
         dataset[DicomTags.SopInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
         dataset[DicomTags.SopClassUid].SetStringValue(ModalityConverter.ToSopClassUid(modality));
         dataset[DicomTags.Modality].SetStringValue(modality.ToString());
         dataset[DicomTags.LossyImageCompression].SetStringValue(lossyCompressed ? "01" : "00");
         dataset[DicomTags.LossyImageCompressionRatio].SetFloat32(0, lossyCompressed ? 9999 : 1);
         dataset[DicomTags.LossyImageCompressionMethod].SetStringValue(lossyCompressed ? "IDUNNO" : string.Empty);
         dataset[DicomTags.CorrectedImage].SetStringValue(attnCorrected ? "ATTN" : string.Empty);
         dataset[DicomTags.FrameOfReferenceUid].SetStringValue(frameOfReferenceUid);
         dataset[DicomTags.ImageOrientationPatient].SetStringValue(string.Format(@"{0}\{1}\{2}\{3}\{4}\{5}", 1, 0, 0, 0, 1, 0));
         dataset[DicomTags.ImagePositionPatient].SetStringValue(string.Format(@"{0}\{1}\{2}", 0, 0, n));
         dataset[DicomTags.PixelSpacing].SetStringValue(string.Format(@"{0}\{1}", 0.5, 0.5));
         dataset[DicomTags.PhotometricInterpretation].SetStringValue("MONOCHROME2");
         dataset[DicomTags.SamplesPerPixel].SetInt32(0, 1);
         dataset[DicomTags.BitsStored].SetInt32(0, 16);
         dataset[DicomTags.BitsAllocated].SetInt32(0, 16);
         dataset[DicomTags.HighBit].SetInt32(0, 15);
         dataset[DicomTags.PixelRepresentation].SetInt32(0, 1);
         dataset[DicomTags.Rows].SetInt32(0, 100);
         dataset[DicomTags.Columns].SetInt32(0, 100);
         dataset[DicomTags.WindowCenter].SetInt32(0, 0);
         dataset[DicomTags.WindowWidth].SetInt32(0, 65536);
         dataset[DicomTags.WindowCenterWidthExplanation].SetString(0, "Full Window");
         dataset[DicomTags.PixelData].Values  = new byte[2 * 100 * 100];
         dicomFile.MediaStorageSopClassUid    = dataset[DicomTags.SopClassUid];
         dicomFile.MediaStorageSopInstanceUid = dataset[DicomTags.SopInstanceUid];
         yield return(new XSopDataSource(dicomFile));
     }
 }
        /// <summary>
        /// Reference implementation of the image fusion operator.
        /// </summary>
        private static IPresentationImage Fuse(IPresentationImage baseImage, IPresentationImage overlayImage, IColorMap colorMap, float opacity, bool thresholding)
        {
            Platform.CheckTrue(baseImage is IImageSopProvider, "baseImage must be a IImageSopProvider.");
            Platform.CheckTrue(overlayImage is IImageSopProvider, "overlayImage must be a IImageSopProvider.");
            Platform.CheckTrue(baseImage is IImageGraphicProvider, "baseImage must be a IImageGraphicProvider.");
            Platform.CheckTrue(overlayImage is IImageGraphicProvider, "overlayImage must be a IImageGraphicProvider.");

            var baseImageSopProvider        = (IImageSopProvider)baseImage;
            var baseImageGraphicProvider    = (IImageGraphicProvider)baseImage;
            var overlayImageSopProvider     = (IImageSopProvider)overlayImage;
            var overlayImageGraphicProvider = (IImageGraphicProvider)overlayImage;
            var rows      = baseImageSopProvider.Frame.Rows;
            var cols      = baseImageSopProvider.Frame.Columns;
            var pixelData = new byte[3 * rows * cols];

            colorMap.MinInputValue = ushort.MinValue;
            colorMap.MaxInputValue = ushort.MaxValue;

            // this here is the magic
            baseImageGraphicProvider.ImageGraphic.PixelData.ForEachPixel(
                (n, x, y, i) =>
            {
                // and this is why the base and overlay slices must be unsigned precisely coincident
                var patientLocation   = baseImageSopProvider.Frame.ImagePlaneHelper.ConvertToPatient(new PointF(x, y));
                var overlayCoordinate = overlayImageSopProvider.Frame.ImagePlaneHelper.ConvertToImagePlane(patientLocation);
                var baseValue         = (ushort)baseImageGraphicProvider.ImageGraphic.PixelData.GetPixel(i);
                var overlayValue      = overlayImageGraphicProvider.ImageGraphic.PixelData.GetPixel((int)overlayCoordinate.X, (int)overlayCoordinate.Y);

                // the fusion operator: output = underlyingGrey*(1-alpha) + overlayingColour*(alpha) (see DICOM 2009 PS 3.4 N.2.4.3)
                var compositeColor   = ToRgbVectorFromGrey(baseValue) * (1 - opacity) + ToRgbVector(colorMap[overlayValue]) * opacity;
                pixelData[3 * n]     = (byte)compositeColor.X;
                pixelData[3 * n + 1] = (byte)compositeColor.Y;
                pixelData[3 * n + 2] = (byte)compositeColor.Z;
            });

            var dicomFile = new DicomFile();
            var dataset   = dicomFile.DataSet;

            dataset[DicomTags.PatientId].SetStringValue(baseImageSopProvider.ImageSop.PatientId);
            dataset[DicomTags.PatientsName].SetStringValue(baseImageSopProvider.ImageSop.PatientsName);
            dataset[DicomTags.StudyId].SetStringValue(baseImageSopProvider.ImageSop.StudyId);
            dataset[DicomTags.StudyInstanceUid].SetStringValue(baseImageSopProvider.ImageSop.StudyInstanceUid);
            dataset[DicomTags.SeriesDescription].SetStringValue(baseImageSopProvider.ImageSop.SeriesDescription);
            dataset[DicomTags.SeriesNumber].SetInt32(0, 9001);
            dataset[DicomTags.SeriesInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
            dataset[DicomTags.SopInstanceUid].SetStringValue(DicomUid.GenerateUid().UID);
            dataset[DicomTags.SopClassUid].SetStringValue(ModalityConverter.ToSopClassUid(Modality.SC));
            dataset[DicomTags.Modality].SetStringValue("SC");
            dataset[DicomTags.FrameOfReferenceUid].SetStringValue(baseImageSopProvider.Frame.FrameOfReferenceUid);
            dataset[DicomTags.ImageOrientationPatient].SetStringValue(baseImageSopProvider.Frame.ImageOrientationPatient.ToString());
            dataset[DicomTags.ImagePositionPatient].SetStringValue(baseImageSopProvider.Frame.ImagePositionPatient.ToString());
            dataset[DicomTags.PixelSpacing].SetStringValue(baseImageSopProvider.Frame.PixelSpacing.ToString());
            dataset[DicomTags.PhotometricInterpretation].SetStringValue("RGB");
            dataset[DicomTags.SamplesPerPixel].SetInt32(0, 3);
            dataset[DicomTags.BitsStored].SetInt32(0, 8);
            dataset[DicomTags.BitsAllocated].SetInt32(0, 8);
            dataset[DicomTags.HighBit].SetInt32(0, 7);
            dataset[DicomTags.PixelRepresentation].SetInt32(0, 0);
            dataset[DicomTags.Rows].SetInt32(0, rows);
            dataset[DicomTags.Columns].SetInt32(0, cols);
            dataset[DicomTags.PixelData].Values  = pixelData;
            dicomFile.MediaStorageSopClassUid    = dataset[DicomTags.SopClassUid];
            dicomFile.MediaStorageSopInstanceUid = dataset[DicomTags.SopInstanceUid];

            using (var sopDataSource = new XSopDataSource(dicomFile))
            {
                return(PresentationImageFactory.Create(new ImageSop(sopDataSource))[0]);
            }
        }