/// <summary>
 /// Create a copy of the specified DICOM file with requested transfer syntax.
 /// </summary>
 /// <param name="file">DICOM file to copy.</param>
 /// <param name="syntax">Requested transfer syntax for the created DICOM file.</param>
 /// <param name="parameters">Codec parameters.</param>
 /// <returns>DICOM file with modified transfer syntax.</returns>
 public static DicomFile ChangeTransferSyntax(
     this DicomFile file,
     DicomTransferSyntax syntax,
     DicomCodecParams parameters = null)
 {
     var transcoder = new DicomTranscoder(file.FileMetaInfo.TransferSyntax, syntax, parameters, parameters);
     return transcoder.Transcode(file);
 }
Beispiel #2
0
        /// <summary>
        /// Create grayscale render options based on pixel data histogram.
        /// </summary>
        /// <param name="dataset">DICOM dataset from which render options should be obtained.</param>
        /// <param name="percent">Percentage of histogram window to include.</param>
        /// <returns>Grayscale render options based on pixel data histogram.</returns>
        public static GrayscaleRenderOptions FromHistogram(DicomDataset dataset, int percent = 90)
        {
            var bits    = BitDepth.FromDataset(dataset);
            var options = new GrayscaleRenderOptions(bits);

            options.RescaleSlope     = dataset.Get <double>(DicomTag.RescaleSlope, 1.0);
            options.RescaleIntercept = dataset.Get <double>(DicomTag.RescaleIntercept, 0.0);

            var transcoder = new DicomTranscoder(
                dataset.InternalTransferSyntax,
                DicomTransferSyntax.ExplicitVRLittleEndian);

            var pixels    = transcoder.DecodePixelData(dataset, 0);
            var histogram = pixels.GetHistogram(0);

            int padding = dataset.Get <int>(DicomTag.PixelPaddingValue, 0, Int32.MinValue);

            if (padding != Int32.MinValue)
            {
                histogram.Clear(padding);
            }

            histogram.ApplyWindow(percent);

            var min = histogram.WindowStart * options.RescaleSlope + options.RescaleIntercept;
            var max = histogram.WindowEnd * options.RescaleSlope + options.RescaleIntercept;

            options.WindowWidth  = Math.Abs(max - min);
            options.WindowCenter = (max + min) / 2.0;

            options.VOILUTFunction = dataset.Get <string>(DicomTag.VOILUTFunction, "LINEAR");
            options.ColorMap       = GetColorMap(dataset);

            return(options);
        }
Beispiel #3
0
        public void DicomTranscoderTranscode_ToCompressedCodecInParallel_NoMultithreadIssues(DicomTransferSyntax syntax, int filesToTranscode)
        {
            var original = DicomFile.Open(TestData.Resolve("CT-MONO2-16-ankle")).Dataset;

            var datasets   = Enumerable.Range(0, filesToTranscode).Select(_ => original.Clone()).ToList();
            var transcoder = new DicomTranscoder(original.InternalTransferSyntax, syntax);

            var originalTranscoded = transcoder.Transcode(original);

            var bag = new ConcurrentBag <DicomDataset>();

            var exception =
                Record.Exception(() => Parallel.ForEach(datasets, dataset =>
            {
                var transcoded = transcoder.Transcode(dataset);
                bag.Add(transcoded);
            }));

            Assert.Null(exception);

            var refPixelData = originalTranscoded.GetDicomItem <DicomFragmentSequence>(DicomTag.PixelData);

            foreach (var dataset in bag)
            {
                var pixelData = dataset.GetDicomItem <DicomFragmentSequence>(DicomTag.PixelData);
                Assert.Equal(refPixelData, pixelData);
            }
        }
Beispiel #4
0
        /// <summary>
        /// If necessary, prepare new frame data, and return appropriate frame index.
        /// </summary>
        /// <param name="frame">The frame number to create pixeldata for.</param>
        /// <returns>Index of the frame, might be diffrent than the frame number for encapsulated images.</returns>
        private int GetFrameIndex(int frame)
        {
            EstablishPipeline();

            if (_dataset.InternalTransferSyntax.IsEncapsulated)
            {
                if (!_frameIndices.TryGetValue(frame, out int index))
                {
                    // decompress single frame from source dataset
                    var transcoder = new DicomTranscoder(
                        _dataset.InternalTransferSyntax,
                        DicomTransferSyntax.ExplicitVRLittleEndian);
                    var buffer = transcoder.DecodeFrame(_dataset, frame);

                    // Additional check to ensure that frame has not been provided by other thread.
                    if (!_frameIndices.TryGetValue(frame, out index))
                    {
                        // Get frame/index mapping for previously unstored frame.
                        index = _pixelData.NumberOfFrames;
                        _frameIndices.Add(frame, index);

                        _pixelData.AddFrame(buffer);
                    }
                }

                return(index);
            }

            return(frame);
        }
Beispiel #5
0
        public static GrayscaleRenderOptions FromMinMax(DicomDataset dataset)
        {
            var bits    = BitDepth.FromDataset(dataset);
            var options = new GrayscaleRenderOptions(bits);

            options.RescaleSlope     = dataset.Get <double>(DicomTag.RescaleSlope, 1.0);
            options.RescaleIntercept = dataset.Get <double>(DicomTag.RescaleIntercept, 0.0);

            int padding = dataset.Get <int>(DicomTag.PixelPaddingValue, 0, Int32.MinValue);

            var transcoder = new DicomTranscoder(dataset.InternalTransferSyntax, DicomTransferSyntax.ExplicitVRLittleEndian);

            var pixels = transcoder.DecodePixelData(dataset, 0);
            var range  = pixels.GetMinMax(padding);

            if (range.Minimum < bits.MinimumValue || range.Minimum == Double.MaxValue)
            {
                range.Minimum = bits.MinimumValue;
            }
            if (range.Maximum > bits.MaximumValue || range.Maximum == Double.MinValue)
            {
                range.Maximum = bits.MaximumValue;
            }

            options.WindowWidth  = Math.Abs(range.Maximum - range.Minimum);
            options.WindowCenter = range.Minimum + (options.WindowWidth / 2.0);

            options.VOILUTFunction = dataset.Get <string>(DicomTag.VOILUTFunction, "LINEAR");
            options.Monochrome1    = dataset.Get <PhotometricInterpretation>(DicomTag.PhotometricInterpretation) == PhotometricInterpretation.Monochrome1;

            return(options);
        }
Beispiel #6
0
        public static GrayscaleRenderOptions FromHistogram(DicomDataset dataset, int percent = 90)
        {
            var bits    = BitDepth.FromDataset(dataset);
            var options = new GrayscaleRenderOptions(bits);

            options.RescaleSlope     = dataset.Get <double>(DicomTag.RescaleSlope, 1.0);
            options.RescaleIntercept = dataset.Get <double>(DicomTag.RescaleIntercept, 0.0);

            var transcoder = new DicomTranscoder(dataset.InternalTransferSyntax, DicomTransferSyntax.ExplicitVRLittleEndian);

            var pixels    = transcoder.DecodePixelData(dataset, 0);
            var histogram = pixels.GetHistogram(0);

            int padding = dataset.Get <int>(DicomTag.PixelPaddingValue, 0, Int32.MinValue);

            if (padding != Int32.MinValue)
            {
                histogram.Clear(padding);
            }

            histogram.ApplyWindow(percent);

            options.WindowWidth  = histogram.WindowEnd - histogram.WindowStart;
            options.WindowCenter = histogram.WindowStart + (options.WindowWidth / 2.0);

            options.VOILUTFunction = dataset.Get <string>(DicomTag.VOILUTFunction, "LINEAR");
            options.Monochrome1    = dataset.Get <PhotometricInterpretation>(DicomTag.PhotometricInterpretation) == PhotometricInterpretation.Monochrome1;

            return(options);
        }
 /// <summary>
 /// Create a copy of the specified DICOM dataset with requested transfer syntax.
 /// </summary>
 /// <param name="dataset">DICOM dataset to copy.</param>
 /// <param name="syntax">Requested transfer syntax for the created DICOM dataset.</param>
 /// <param name="parameters">Codec parameters.</param>
 /// <returns>DICOM dataset with modified transfer syntax.</returns>
 public static DicomDataset ChangeTransferSyntax(
     this DicomDataset dataset,
     DicomTransferSyntax syntax,
     DicomCodecParams parameters = null)
 {
     var transcoder = new DicomTranscoder(dataset.InternalTransferSyntax, syntax, parameters, parameters);
     return transcoder.Transcode(dataset);
 }
Beispiel #8
0
        /// <summary>
        /// Convert the byte data retrieved from DCM file to Image
        /// </summary>
        /// <param name="imagedata"></param>
        /// <returns></returns>
        private Bitmap ConvertDCMData2BitImage(DicomFile dcm)
        {
            DicomFile newDcmFile = null;

            if (dcm.FileMetaInfo.TransferSyntax.IsEncapsulated)//if the data is compressed
            {
                // System.Reflection.Assembly.LoadFrom(Path.Combine(Application.StartupPath,"Dicom.Native64.dll"));
                DicomTranscoder.LoadCodecs(Application.StartupPath, "Dicom.Native*.dll");
                newDcmFile = dcm.ChangeTransferSyntax(DicomTransferSyntax.ExplicitVRLittleEndian, new DicomJpegLsParams());
            }
            DicomImage imageDcm = null;

            if (newDcmFile != null)
            {
                imageDcm = new DicomImage(newDcmFile.Dataset);
            }
            else
            {
                imageDcm = new DicomImage(dcm.Dataset);
            }
            DicomDataset dataset = dcm.Dataset;

            byte[] fs      = imageDcm.PixelData.NumberOfFrames < 2 ? imageDcm.PixelData.GetFrame(0).Data : imageDcm.PixelData.GetFrame(1).Data;
            uint   size    = (uint)Marshal.SizeOf(typeof(short));
            uint   padding = (uint)fs.Length % size;
            uint   count   = (uint)fs.Length / size;

            short[] values = new short[count];
            System.Buffer.BlockCopy(fs, 0, values, 0, (int)(fs.Length - padding));

            int height        = dataset.Get <int>(DicomTag.Rows);
            int width         = dataset.Get <int>(DicomTag.Columns);
            int windowsWidth  = (int)dataset.Get <double>(DicomTag.WindowWidth);
            int windowsCenter = (int)dataset.Get <double>(DicomTag.WindowCenter);

            //if the windowsWidth = 0, the DCM file is not standard type.
            if (windowsWidth == 0 || windowsCenter == 0)
            {
                windowsWidth  = values.Max <short>() - values.Min <short>();
                windowsCenter = windowsWidth / 2;
            }
            int    low    = windowsCenter - windowsWidth / 2;
            int    high   = windowsCenter + windowsWidth / 2;
            Bitmap bitmap = new Bitmap(width, height);

            for (int i = 0; i < height; ++i)
            {
                for (int j = 0; j < width; ++j)
                {
                    int r, g, b;
                    int temp = (int)values[(width - j - 1) * height + i];
                    int val  = temp > high ? 255 : (temp < low ? 0 : ((temp - low) * 255 / windowsWidth));
                    r = g = b = val;
                    bitmap.SetPixel(i, width - j - 1, Color.FromArgb(r, g, b));
                }
            }
            return(bitmap);
        }
Beispiel #9
0
        /// <summary>
        /// Create a copy of the specified DICOM file with requested transfer syntax.
        /// </summary>
        /// <param name="file">DICOM file to copy.</param>
        /// <param name="syntax">Requested transfer syntax for the created DICOM file.</param>
        /// <param name="parameters">Codec parameters.</param>
        /// <returns>DICOM file with modified transfer syntax.</returns>
        public static DicomFile ChangeTransferSyntax(
            this DicomFile file,
            DicomTransferSyntax syntax,
            DicomCodecParams parameters = null)
        {
            var transcoder = new DicomTranscoder(file.FileMetaInfo.TransferSyntax, syntax, parameters, parameters);

            return(transcoder.Transcode(file));
        }
Beispiel #10
0
        /// <summary>
        /// Create a copy of the specified DICOM dataset with requested transfer syntax.
        /// </summary>
        /// <param name="dataset">DICOM dataset to copy.</param>
        /// <param name="syntax">Requested transfer syntax for the created DICOM dataset.</param>
        /// <param name="parameters">Codec parameters.</param>
        /// <returns>DICOM dataset with modified transfer syntax.</returns>
        public static DicomDataset ChangeTransferSyntax(
            this DicomDataset dataset,
            DicomTransferSyntax syntax,
            DicomCodecParams parameters = null)
        {
            var transcoder = new DicomTranscoder(dataset.InternalTransferSyntax, syntax, parameters, parameters);

            return(transcoder.Transcode(dataset));
        }
Beispiel #11
0
 public static DicomFile ChangeTransferSyntax(
     this DicomFile file,
     DicomTransferSyntax syntax,
     DicomCodecParams parameters = null)
 {
     DicomTranscoder transcoder = new DicomTranscoder(file.FileMetaInfo.TransferSyntax, syntax);
     transcoder.InputCodecParams = parameters;
     transcoder.OutputCodecParams = parameters;
     return transcoder.Transcode(file);
 }
Beispiel #12
0
 public static DicomDataset ChangeTransferSyntax(
     this DicomDataset dataset,
     DicomTransferSyntax syntax,
     DicomCodecParams parameters = null)
 {
     DicomTranscoder transcoder = new DicomTranscoder(dataset.InternalTransferSyntax, syntax);
     transcoder.InputCodecParams = parameters;
     transcoder.OutputCodecParams = parameters;
     return transcoder.Transcode(dataset);
 }
Beispiel #13
0
        private string defaultImageBG;//the default background image
        public DICOMProcessDemo()
        {
            InitializeComponent();
            string appPath   = Application.StartupPath;
            string imagePath = appPath + @"\..\..\..\..\" + @"Resource\defaultbackgroundImage.bmp";

            defaultImageBG    = imagePath;
            pictureBox1.Image = Image.FromFile(imagePath);
            DicomTranscoder.LoadCodecs(Application.StartupPath, "Dicom.Native*.dll");
        }
Beispiel #14
0
        /// <summary>
        /// Loads the pixel data for specified frame and set the internal dataset
        ///
        /// </summary>
        /// <param name="dataset">dataset to load pixeldata from</param>
        /// <param name="frame">The frame number to create pixeldata for</param>
        private void Load(DicomDataset dataset, int frame)
        {
            Dataset = dataset;

            if (PixelData == null)
            {
                PixelData = DicomPixelData.Create(Dataset);
                PhotometricInterpretation = PixelData.PhotometricInterpretation;
            }

            if (Dataset.InternalTransferSyntax.IsEncapsulated)
            {
                // decompress single frame from source dataset
                DicomCodecParams cparams = null;
                if (Dataset.InternalTransferSyntax == DicomTransferSyntax.JPEGProcess1 || Dataset.InternalTransferSyntax == DicomTransferSyntax.JPEGProcess2_4)
                {
                    cparams = new DicomJpegParams {
                        ConvertColorspaceToRGB = true
                    };
                }

                var transcoder = new DicomTranscoder(Dataset.InternalTransferSyntax, DicomTransferSyntax.ExplicitVRLittleEndian);
                transcoder.InputCodecParams  = cparams;
                transcoder.OutputCodecParams = cparams;
                var buffer = transcoder.DecodeFrame(Dataset, frame);

                // clone the dataset because modifying the pixel data modifies the dataset
                var clone = Dataset.Clone();
                clone.InternalTransferSyntax = DicomTransferSyntax.ExplicitVRLittleEndian;

                var pixelData = DicomPixelData.Create(clone, true);
                pixelData.AddFrame(buffer);

                // temporary fix for JPEG compressed YBR images
                if ((Dataset.InternalTransferSyntax == DicomTransferSyntax.JPEGProcess1 || Dataset.InternalTransferSyntax == DicomTransferSyntax.JPEGProcess2_4) && pixelData.SamplesPerPixel == 3)
                {
                    pixelData.PhotometricInterpretation = PhotometricInterpretation.Rgb;
                }

                _pixelData = PixelDataFactory.Create(pixelData, 0);
            }
            else
            {
                // pull uncompressed frame from source pixel data
                _pixelData = PixelDataFactory.Create(PixelData, frame);
            }

            _pixelData.Rescale(_scale);

            _overlays = DicomOverlayData.FromDataset(Dataset).Where(x => x.Type == DicomOverlayType.Graphics && x.Data != null).ToArray();

            _currentFrame = frame;

            CreatePipeline();
        }
Beispiel #15
0
        /// <summary>
        /// Loads the pixel data for specified frame and set the internal dataset
        ///
        /// </summary>
        /// <param name="dataset">dataset to load pixeldata from</param>
        /// <param name="frame">The frame number to create pixeldata for</param>
        private void Load(DicomDataset dataset, int frame)
        {
            Dataset = DicomTranscoder.ExtractOverlays(dataset);

            if (PixelData == null)
            {
                PixelData = DicomPixelData.Create(Dataset);
                PhotometricInterpretation = PixelData.PhotometricInterpretation;
            }
            if (frame < 0)
            {
                CurrentFrame = frame;
                return;
            }

            if (Dataset.InternalTransferSyntax.IsEncapsulated)
            {
                // decompress single frame from source dataset
                var transcoder = new DicomTranscoder(
                    this.Dataset.InternalTransferSyntax,
                    DicomTransferSyntax.ExplicitVRLittleEndian);
                var buffer = transcoder.DecodeFrame(Dataset, frame);

                // clone the dataset because modifying the pixel data modifies the dataset
                var clone = Dataset.Clone();
                clone.InternalTransferSyntax = DicomTransferSyntax.ExplicitVRLittleEndian;

                var pixelData = DicomPixelData.Create(clone, true);
                TrimDecodedPixelDataProperties(pixelData, Dataset.InternalTransferSyntax);
                pixelData.AddFrame(buffer);

                _pixelData = PixelDataFactory.Create(pixelData, 0);
            }
            else
            {
                // pull uncompressed frame from source pixel data
                _pixelData = PixelDataFactory.Create(PixelData, frame);
            }

            _pixelData = _pixelData.Rescale(_scale);

            _overlays =
                DicomOverlayData.FromDataset(Dataset)
                .Where(x => x.Type == DicomOverlayType.Graphics && x.Data != null)
                .ToArray();

            CurrentFrame = frame;

            if (_pipeline == null)
            {
                CreatePipeline();
            }
        }
Beispiel #16
0
        /// <summary>Creates DICOM image object from dataset</summary>
        /// <param name="dataset">Source dataset</param>
        /// <param name="frame">Zero indexed frame number. If <paramref name="frame"/> is set to a negative number, the
        /// <see cref="DicomImage"/> object will remain in a partly initialized state, allowing for <see cref="WindowCenter"/>,
        /// <see cref="WindowWidth"/> and <see cref="GrayscaleColorMap"/> to be configured prior to rendering the image frames.</param>
        public DicomImage(DicomDataset dataset, int frame = 0)
        {
            ShowOverlays = true;

            _scale        = 1.0;
            _rerender     = true;
            _frameIndices = new ConcurrentDictionary <int, int>();

            _dataset     = DicomTranscoder.ExtractOverlays(dataset);
            _pixelData   = CreateDicomPixelData(_dataset);
            CurrentFrame = frame;
        }
        public IList <TestInstanceInfo> Save(string destDir, string filenamePrefix, DicomTransferSyntax transferSyntax, int instancesToGenerate = 1, string sopClassUid = "1.2.840.10008.5.1.4.1.1.11.1")
        {
            Console.Write("Generating test files.");
            if (!Directory.Exists(destDir))
            {
                Directory.CreateDirectory(destDir);
            }

            var dataset = new DicomDataset();

            baseDataset.CopyTo(dataset);
            dataset.AddOrUpdate(DicomTag.SOPClassUID, sopClassUid);

            var dicomFile = new DicomFile(dataset);

            if (transferSyntax != dicomFile.Dataset.InternalTransferSyntax)
            {
                var transcoder = new DicomTranscoder(dicomFile.Dataset.InternalTransferSyntax, transferSyntax, outputCodecParams: new DicomJpegParams()
                {
                    Quality = 100, ConvertColorspaceToRGB = true
                });
                dicomFile = transcoder.Transcode(dicomFile);
            }

            var instancesCreated = new List <TestInstanceInfo>();

            for (int i = 0; i < instancesToGenerate; i++)
            {
                Console.Write(".");
                var sopInstanceUid = DicomUIDGenerator.GenerateDerivedFromUUID();
                var filePath       = Path.Combine(destDir, $"{filenamePrefix}-{i:00000}.dcm");
                dicomFile.Dataset.AddOrUpdate(DicomTag.SOPInstanceUID, sopInstanceUid);
                dicomFile.FileMetaInfo.AddOrUpdate(DicomTag.MediaStorageSOPInstanceUID, sopInstanceUid);
                dicomFile.FileMetaInfo.AddOrUpdate(DicomTag.MediaStorageSOPClassUID, sopClassUid);

                dicomFile.Clone().Save(filePath);

                instancesCreated.Add(new TestInstanceInfo
                {
                    PatientId         = dicomFile.Dataset.GetSingleValue <string>(DicomTag.PatientID),
                    StudyInstanceUid  = dicomFile.Dataset.GetSingleValue <string>(DicomTag.StudyInstanceUID),
                    SeriesInstanceUid = dicomFile.Dataset.GetSingleValue <string>(DicomTag.SeriesInstanceUID),
                    SopInstanceUid    = dicomFile.Dataset.GetSingleValue <string>(DicomTag.SOPInstanceUID),
                    FilePath          = filePath
                });
            }
            Console.WriteLine(".");
            return(instancesCreated);
        }
Beispiel #18
0
 private IByteBuffer TranscodeFrame(DicomDataset dataset, int frameIndex, DicomTransferSyntax targetSyntax)
 {
     // DicomTranscoder doesn't support transcoding frame(s), one workaround is to transcode entire dicomdataset, and return required frame, which would be inefficent when there are multiple frames (imaging 100 frames in one dataset).
     // A better workaround is to create a dataset including only the required frame, and transcode it.
     try
     {
         DicomDataset datasetForFrame = CreateDatasetForFrame(dataset, frameIndex);
         var          transcoder      = new DicomTranscoder(dataset.InternalTransferSyntax, targetSyntax);
         DicomDataset result          = transcoder.Transcode(datasetForFrame);
         return(DicomPixelData.Create(result).GetFrame(0));
     }
     catch (Exception ex)
     {
         LogTranscodingFrameErrorDelegate(_logger, frameIndex, dataset?.InternalTransferSyntax?.UID?.UID, targetSyntax?.UID?.UID, ex);
         throw new TranscodingException();
     }
 }
Beispiel #19
0
        /// <summary>
        /// Gets the uncompressed pixel data from the provided DICOM dataset.
        /// </summary>
        /// <param name="dataset">The DICOM dataset.</param>
        /// <returns>The uncompressed pixel data as a byte array.</returns>
        /// <exception cref="ArgumentNullException">The provided DICOM dataset was null.</exception>
        public static byte[] GetUncompressedPixelData(DicomDataset dataset)
        {
            dataset = dataset ?? throw new ArgumentNullException(nameof(dataset));

            if (dataset.InternalTransferSyntax.IsEncapsulated)
            {
                // Decompress single frame from source dataset
                var transcoder = new DicomTranscoder(
                    inputSyntax: dataset.InternalTransferSyntax,
                    outputSyntax: DicomTransferSyntax.ExplicitVRLittleEndian);

                return(transcoder.DecodeFrame(dataset, 0).Data);
            }
            else
            {
                // Pull uncompressed frame from source pixel data
                var pixelData = DicomPixelData.Create(dataset);
                return(pixelData.GetFrame(0).Data);
            }
        }
Beispiel #20
0
        private async Task <Stream> TranscodeFileAsync(DicomFile dicomFile, DicomTransferSyntax requestedTransferSyntax)
        {
            try
            {
                var transcoder = new DicomTranscoder(
                    dicomFile.Dataset.InternalTransferSyntax,
                    requestedTransferSyntax);
                dicomFile = transcoder.Transcode(dicomFile);
            }
            catch (Exception ex)
            {
                LogTranscodingFileErrorDelegate(_logger, dicomFile?.Dataset?.InternalTransferSyntax?.UID?.UID, requestedTransferSyntax?.UID?.UID, ex);

                // TODO: Reevaluate this while fixing transcoding handling.
                // We catch all here as Transcoder can throw a wide variety of things.
                // Basically this means codec failure - a quite extraordinary situation, but not impossible
                // Proper solution here would be to actually try transcoding all the files that we are
                // returning and either form a PartialContent or NotAcceptable response with an extra error message in
                // the headers. Because transcoding is an expensive operation, we choose to do it from within the
                // LazyTransformReadOnlyStream at the time when response is being formed by the server, therefore this code
                // is called from ASP.NET framework and at this point we can not change our server response.
                // The decision for now is just to return an empty stream here letting the client handle it.
                // In the future a more optimal solution may involve maintaining a cache of transcoded images and
                // using that to determine if transcoding is possible from within the Handle method.

                throw new TranscodingException();
            }

            MemoryStream resultStream = _recyclableMemoryStreamManager.GetStream();

            if (dicomFile != null)
            {
                await dicomFile.SaveAsync(resultStream);

                resultStream.Seek(offset: 0, loc: SeekOrigin.Begin);
            }

            return(resultStream);
        }
Beispiel #21
0
        /// <summary>
        /// Create grayscale render options based on identified minimum and maximum pixel values.
        /// </summary>
        /// <param name="dataset">DICOM dataset from which render options should be obtained.</param>
        /// <returns>Grayscale render options based on identified minimum and maximum pixel values.</returns>
        public static GrayscaleRenderOptions FromMinMax(DicomDataset dataset)
        {
            var bits    = BitDepth.FromDataset(dataset);
            var options = new GrayscaleRenderOptions(bits);

            options.RescaleSlope     = dataset.Get <double>(DicomTag.RescaleSlope, 1.0);
            options.RescaleIntercept = dataset.Get <double>(DicomTag.RescaleIntercept, 0.0);

            int padding = dataset.Get <int>(DicomTag.PixelPaddingValue, 0, Int32.MinValue);

            var transcoder = new DicomTranscoder(
                dataset.InternalTransferSyntax,
                DicomTransferSyntax.ExplicitVRLittleEndian);

            var pixels = transcoder.DecodePixelData(dataset, 0);
            var range  = pixels.GetMinMax(padding);

            if (range.Minimum < bits.MinimumValue || range.Minimum == Double.MaxValue)
            {
                range.Minimum = bits.MinimumValue;
            }
            if (range.Maximum > bits.MaximumValue || range.Maximum == Double.MinValue)
            {
                range.Maximum = bits.MaximumValue;
            }

            var min = range.Minimum * options.RescaleSlope + options.RescaleIntercept;
            var max = range.Maximum * options.RescaleSlope + options.RescaleIntercept;

            options.WindowWidth  = Math.Abs(max - min);
            options.WindowCenter = (max + min) / 2.0;

            options.VOILUTFunction = dataset.Get <string>(DicomTag.VOILUTFunction, "LINEAR");
            options.ColorMap       = GetColorMap(dataset);

            return(options);
        }
    protected void Page_Load(object sender, EventArgs e)
    {
        Bitmap bmp;
        string fileName;

        try
        {
            fileName = Request.QueryString["fileName"];
        }
        catch (Exception)
        {
            throw new HttpException(400, "Bad Request");
        }
        if (string.IsNullOrEmpty(fileName))
        {
            throw new HttpException(400, "Bad Request");
        }
        try
        {
            DicomTranscoder.LoadCodecs(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"), "Dicom.Native*.dll");
            var image = new DicomImage(Context.Server.MapPath("~/DICOMs/" + fileName));
            bmp = new Bitmap(image.RenderImage());
        }
        catch (Exception)
        {
            throw new HttpException(500, "Internal Server Error");
        }
        StringBuilder sb = new StringBuilder();

        sb.Append("{\"x\" : ");
        sb.Append(bmp.Width);
        sb.Append(",\"y\" : ");
        sb.Append(bmp.Height);
        sb.Append("}");
        Response.Write(sb.ToString());
    }
Beispiel #23
0
        public static DicomFile GenerateDicomFile(
            string studyInstanceUid,
            string seriesInstanceUid,
            string sopInstanceUid,
            string sopClassUid,
            int rows,
            int cols,
            TestFileBitDepth bitDepth,
            string transferSyntax,
            bool encode,
            int frames = 1,
            string photometricInterpretation = null)
        {
            DicomTransferSyntax initialTs = DicomTransferSyntax.ExplicitVRLittleEndian;

            if (!encode)
            {
                initialTs = DicomTransferSyntax.Parse(transferSyntax);
            }

            var rand = new Random();

            var dicomFile = new DicomFile(
                new DicomDataset(initialTs)
            {
                { DicomTag.StudyInstanceUID, studyInstanceUid ?? TestUidGenerator.Generate() },
                { DicomTag.SeriesInstanceUID, seriesInstanceUid ?? TestUidGenerator.Generate() },
                { DicomTag.SOPInstanceUID, sopInstanceUid ?? TestUidGenerator.Generate() },
                { DicomTag.SOPClassUID, sopClassUid ?? TestUidGenerator.Generate() },
                { DicomTag.Rows, (ushort)rows },
                { DicomTag.Columns, (ushort)cols },
                { DicomTag.PhotometricInterpretation, photometricInterpretation ?? PhotometricInterpretation.Monochrome2.Value },
                { DicomTag.BitsAllocated, (ushort)bitDepth },
                { DicomTag.WindowWidth, ((bitDepth == TestFileBitDepth.EightBit) ? "256" : "65536") },
                { DicomTag.WindowCenter, ((bitDepth == TestFileBitDepth.EightBit) ? "128" : "32768") },
                { DicomTag.AccessionNumber, rand.Next(11111111, 19999999) },
                { DicomTag.PatientID, TestUidGenerator.Generate() },
            });

            var pixelData = DicomPixelData.Create(dicomFile.Dataset, true);

            pixelData.SamplesPerPixel     = 1;
            pixelData.BitsStored          = (ushort)bitDepth;
            pixelData.HighBit             = (ushort)(bitDepth - 1);
            pixelData.PixelRepresentation = PixelRepresentation.Unsigned;

            for (int i = 0; i < frames; i++)
            {
                var buffer = new MemoryByteBuffer(
                    (bitDepth == TestFileBitDepth.SixteenBit)
                        ? GetBytesFor16BitImage(rows, cols, i)
                        : GetBytesFor8BitImage(rows, cols, i));

                pixelData.AddFrame(buffer);
            }

            if (encode && transferSyntax != DicomTransferSyntax.ExplicitVRLittleEndian.UID.UID)
            {
                var transcoder =
                    new DicomTranscoder(
                        dicomFile.Dataset.InternalTransferSyntax,
                        DicomTransferSyntax.Parse(transferSyntax));
                dicomFile = transcoder.Transcode(dicomFile);
            }

            return(dicomFile);
        }