public void Init(Stream fileStream) { InitializeDicom(); file = new BinaryReader(fileStream); location = 0; // Reset the location dicomInfo.Clear(); try { bool readResult = ReadFileInfo(); if (readResult && widthTagFound && heightTagFound && pixelDataTagFound) { ReadPixels(); if (dicmFound == true) { typeofDicomFile = TypeOfDicomFile.Dicom3File; } else { typeofDicomFile = TypeOfDicomFile.DicomOldTypeFile; } } } catch { // Nothing here } finally { file.Close(); } }
public DicomDecoder(DicomDecoder dicomDecoder, List <byte> pixels24) { CopyFromClone(dicomDecoder); _pixels24 = pixels24; _typeofDicomFile = dicomDecoder._typeofDicomFile; _PixelsHaveBeenRead = true; }
public DicomDecoder(DicomDecoder dicomDecoder, List <List <ushort> > newPixels) { CopyFromClone(dicomDecoder); _pixels16 = newPixels; _typeofDicomFile = dicomDecoder._typeofDicomFile; _PixelsHaveBeenRead = true; }
private BitmapSource ReadDicomFile(string fileName, int minWin, int maxWin) { dd.DicomFileName = fileName; List <ushort> pixels16 = new List <ushort>(); int imageWidth; int imageHeight; int bitDepth; int samplesPerPixel; TypeOfDicomFile typeOfDicomFile = dd.typeofDicomFile; if (typeOfDicomFile == TypeOfDicomFile.Dicom3File || typeOfDicomFile == TypeOfDicomFile.DicomOldTypeFile) { imageWidth = dd.width; imageHeight = dd.height; bitDepth = dd.bitsAllocated; samplesPerPixel = dd.samplesPerPixel; if (samplesPerPixel == 1 && bitDepth == 16) { pixels16.Clear(); dd.GetPixels16(ref pixels16); return(BitmapHelper.ToBitmapImage(pixels16.ToArray(), imageWidth, imageHeight, minWin, maxWin)); } else { MessageBox.Show("Unsupported bits per pixel number (only 16bpp supported)"); } } else { if (typeOfDicomFile == TypeOfDicomFile.DicomUnknownTransferSyntax) { MessageBox.Show("Invalid dicom file"); } else { MessageBox.Show("Invalid file"); } return(null); } return(null); }
public void LoadDicomFromStream(byte[] fileContents) { try { if (DicomFileName == "") { DicomFileName = "NOTSET"; } InitializeDicom(); MemoryStream stream = new MemoryStream(fileContents); file = new BinaryReader(stream); //file = new BinaryReader(File.Open(DicomFileName, FileMode.Open, FileAccess.Read)); location = 0; // Reset the location _dicomInfo.Clear(); bool readResult = ReadFileInfo(); if (readResult && _widthTagFound && _heightTagFound && _pixelDataTagFound) { if (_dicmFound == true) { _typeofDicomFile = TypeOfDicomFile.Dicom3File; } else { _typeofDicomFile = TypeOfDicomFile.DicomOldTypeFile; } ReadPixels(); } } catch (Exception ex) { Console.WriteLine("Exception: " + ex.ToString()); } finally { if (file != null) { file.Close(); } } }
public void SetDicomFileName(String filename, bool lazyLoad = false) { try { DicomFileName = filename; InitializeDicom(); // Thanks to CodeProject member Alphons van der Heijden for // suggesting to add this - FileAccess.Read (July 2010) file = new BinaryReader(File.Open(DicomFileName, FileMode.Open, FileAccess.Read)); location = 0; // Reset the location _dicomInfo.Clear(); bool readResult = ReadFileInfo(); if (readResult && _widthTagFound && _heightTagFound && _pixelDataTagFound) { if (_dicmFound == true) { _typeofDicomFile = TypeOfDicomFile.Dicom3File; } else { _typeofDicomFile = TypeOfDicomFile.DicomOldTypeFile; } if (!lazyLoad) { ReadPixels(); } } } catch (Exception ex) { Console.WriteLine("Exception: " + ex.ToString()); } finally { if (file != null) { file.Close(); } } }
void InitializeDicom() { bitsAllocated = 0; width = 1; height = 1; offset = 1; nImages = 1; samplesPerPixel = 1; photoInterpretation = ""; unit = "mm"; windowCentre = 0; windowWidth = 0; signedImage = false; widthTagFound = false; heightTagFound = false; pixelDataTagFound = false; rescaleIntercept = 0.0; // Default value rescaleSlope = 1.0; // Default value typeofDicomFile = TypeOfDicomFile.NotDicom; }
void InitializeDicom() { _bitsAllocated = 0; _imageWidth = 1; _imageHeight = 1; _offset = 1; _nImages = 1; _samplesPerPixel = 1; _photoInterpretation = ""; _unit = "mm"; _windowCentre = 0; _windowWidth = 0; _signedImage = false; _widthTagFound = false; _heightTagFound = false; _pixelDataTagFound = false; _rescaleIntercept = 0.0; // Default value _rescaleSlope = 1.0; // Default value _pixels16 = new List <List <ushort> >(); _typeofDicomFile = TypeOfDicomFile.NotDicom; _PixelsHaveBeenRead = false; }
public bool ReadFileInfo() { long skipCount = Convert.ToInt32(ID_OFFSET); bitsAllocated = 16; file.BaseStream.Seek(skipCount, SeekOrigin.Begin); location += ID_OFFSET; if (GetString(4) != DICM) { // This is for reading older DICOM files (Before 3.0) // Seek from the beginning of the file file.BaseStream.Seek(0, SeekOrigin.Begin); location = 0; // Older DICOM files do not have the preamble and prefix dicmFound = false; // Continue reading further. // See whether the width, height and pixel data tags // are present. If these tags are present, then it we conclude that this is a // DICOM file, because all DICOM files should have at least these three tags. // Otherwise, it is not a DICOM file. } else { // We have a DICOM 3.0 file dicmFound = true; } bool decodingTags = true; samplesPerPixel = 1; int planarConfiguration = 0; photoInterpretation = ""; string modality; while (decodingTags) { int tag = GetNextTag(); if ((location & 1) != 0) oddLocations = true; if (inSequence) { AddInfo(tag, null); continue; } string s; switch (tag) { case (int)(TRANSFER_SYNTAX_UID): s = GetString(elementLength); AddInfo(tag, s); if (s.IndexOf("1.2.4") > -1 || s.IndexOf("1.2.5") > -1) { file.Close(); typeofDicomFile = TypeOfDicomFile.DicomUnknownTransferSyntax; // Return gracefully indicating that this type of // Transfer Syntax cannot be handled return false; } if (s.IndexOf("1.2.840.10008.1.2.2") >= 0) bigEndianTransferSyntax = true; break; case (int)MODALITY: modality = GetString(elementLength); AddInfo(tag, modality); break; case (int)(NUMBER_OF_FRAMES): s = GetString(elementLength); AddInfo(tag, s); double frames = Convert.ToDouble(s, new CultureInfo("en-US")); if (frames > 1.0) nImages = (int)frames; break; case (int)(SAMPLES_PER_PIXEL): samplesPerPixel = GetShort(); AddInfo(tag, samplesPerPixel); break; case (int)(PHOTOMETRIC_INTERPRETATION): photoInterpretation = GetString(elementLength); photoInterpretation = photoInterpretation.Trim(); AddInfo(tag, photoInterpretation); break; case (int)(PLANAR_CONFIGURATION): planarConfiguration = GetShort(); AddInfo(tag, planarConfiguration); break; case (int)(ROWS): height = GetShort(); AddInfo(tag, height); heightTagFound = true; break; case (int)(COLUMNS): width = GetShort(); AddInfo(tag, width); widthTagFound = true; break; case (int)(PIXEL_SPACING): String scale = GetString(elementLength); GetSpatialScale(scale); AddInfo(tag, scale); break; case (int)(SLICE_THICKNESS): case (int)(SLICE_SPACING): String spacing = GetString(elementLength); pixelDepth = Convert.ToDouble(spacing, new CultureInfo("en-US")); AddInfo(tag, spacing); break; case (int)(BITS_ALLOCATED): bitsAllocated = GetShort(); AddInfo(tag, bitsAllocated); break; case (int)(PIXEL_REPRESENTATION): pixelRepresentation = GetShort(); AddInfo(tag, pixelRepresentation); break; case (int)(WINDOW_CENTER): String center = GetString(elementLength); int index = center.IndexOf('\\'); if (index != -1) center = center.Substring(index + 1); windowCentre = Convert.ToDouble(center, new CultureInfo("en-US")); AddInfo(tag, center); break; case (int)(WINDOW_WIDTH): String widthS = GetString(elementLength); index = widthS.IndexOf('\\'); if (index != -1) widthS = widthS.Substring(index + 1); windowWidth = Convert.ToDouble(widthS, new CultureInfo("en-US")); AddInfo(tag, widthS); break; case (int)(RESCALE_INTERCEPT): String intercept = GetString(elementLength); rescaleIntercept = Convert.ToDouble(intercept, new CultureInfo("en-US")); AddInfo(tag, intercept); break; case (int)(RESCALE_SLOPE): String slop = GetString(elementLength); rescaleSlope = Convert.ToDouble(slop, new CultureInfo("en-US")); AddInfo(tag, slop); break; case (int)(RED_PALETTE): reds = GetLut(elementLength); AddInfo(tag, elementLength / 2); break; case (int)(GREEN_PALETTE): greens = GetLut(elementLength); AddInfo(tag, elementLength / 2); break; case (int)(BLUE_PALETTE): blues = GetLut(elementLength); AddInfo(tag, elementLength / 2); break; case (int)(PIXEL_DATA): // Start of image data... if (elementLength != 0) { offset = location; AddInfo(tag, location); decodingTags = false; } else AddInfo(tag, null); pixelDataTagFound = true; break; default: AddInfo(tag, null); break; } } return true; }
private BitmapSource ReadDicomFile(string fileName, out int minWin, out int maxWin) { dd.DicomFileName = fileName; List <ushort> pixels16 = new List <ushort>(); int imageWidth; int imageHeight; int bitDepth; int samplesPerPixel; double winCentre; double winWidth; maxWin = 0; minWin = 0; TypeOfDicomFile typeOfDicomFile = dd.typeofDicomFile; if (typeOfDicomFile == TypeOfDicomFile.Dicom3File || typeOfDicomFile == TypeOfDicomFile.DicomOldTypeFile) { imageWidth = dd.width; imageHeight = dd.height; bitDepth = dd.bitsAllocated; winCentre = dd.windowCentre; winWidth = dd.windowWidth; samplesPerPixel = dd.samplesPerPixel; if (samplesPerPixel == 1 && bitDepth == 16) { pixels16.Clear(); dd.GetPixels16(ref pixels16); int minPixelValue = pixels16.Min(); int maxPixelValue = pixels16.Max(); if (Math.Abs(winWidth) < 0.001) { winWidth = maxPixelValue - minPixelValue; } if ((winCentre == 0) || (minPixelValue > winCentre) || (maxPixelValue < winCentre)) { winCentre = (maxPixelValue + minPixelValue) / 2; } maxWin = Convert.ToInt32(winCentre + 0.5 * winWidth); minWin = maxWin - Convert.ToInt32(winWidth); return(BitmapHelper.ToBitmapImage(pixels16.ToArray(), imageWidth, imageHeight, minWin, maxWin)); } else { MessageBox.Show("Unsupported bits per pixel number (only 16bpp supported)"); } } else { if (typeOfDicomFile == TypeOfDicomFile.DicomUnknownTransferSyntax) { MessageBox.Show("Invalid dicom file"); } else { MessageBox.Show("Invalid file"); } return(null); } return(null); }
public bool ReadFileInfo() { long skipCount = Convert.ToInt32(ID_OFFSET); bitsAllocated = 16; file.BaseStream.Seek(skipCount, SeekOrigin.Begin); location += ID_OFFSET; if (GetString(4) != DICM) { file.BaseStream.Seek(0, SeekOrigin.Begin); location = 0; dicmFound = false; } else { dicmFound = true; } bool decodingTags = true; samplesPerPixel = 1; int planarConfiguration = 0; photoInterpretation = ""; string modality; while (decodingTags) { int tag = GetNextTag(); if ((location & 1) != 0) { oddLocations = true; } if (inSequence) { AddInfo(tag, null); continue; } string s; switch (tag) { case (int)(TRANSFER_SYNTAX_UID): s = GetString(elementLength); AddInfo(tag, s); if (s.IndexOf("1.2.4") > -1 || s.IndexOf("1.2.5") > -1) { file.Close(); typeofDicomFile = TypeOfDicomFile.DicomUnknownTransferSyntax; return(false); } if (s.IndexOf("1.2.840.10008.1.2.2") >= 0) { bigEndianTransferSyntax = true; } break; case (int)MODALITY: modality = GetString(elementLength); AddInfo(tag, modality); break; case (int)(NUMBER_OF_FRAMES): s = GetString(elementLength); AddInfo(tag, s); double frames = Convert.ToDouble(s, new CultureInfo("en-US")); if (frames > 1.0) { nImages = (int)frames; } break; case (int)(SAMPLES_PER_PIXEL): samplesPerPixel = GetShort(); AddInfo(tag, samplesPerPixel); break; case (int)(PHOTOMETRIC_INTERPRETATION): photoInterpretation = GetString(elementLength); photoInterpretation = photoInterpretation.Trim(); AddInfo(tag, photoInterpretation); break; case (int)(PLANAR_CONFIGURATION): planarConfiguration = GetShort(); AddInfo(tag, planarConfiguration); break; case (int)(ROWS): height = GetShort(); AddInfo(tag, height); heightTagFound = true; break; case (int)(COLUMNS): width = GetShort(); AddInfo(tag, width); widthTagFound = true; break; case (int)(PIXEL_SPACING): String scale = GetString(elementLength); GetSpatialScale(scale); AddInfo(tag, scale); break; case (int)(SLICE_THICKNESS): case (int)(SLICE_SPACING): String spacing = GetString(elementLength); pixelDepth = Convert.ToDouble(spacing, new CultureInfo("en-US")); AddInfo(tag, spacing); break; case (int)(BITS_ALLOCATED): bitsAllocated = GetShort(); AddInfo(tag, bitsAllocated); break; case (int)(PIXEL_REPRESENTATION): pixelRepresentation = GetShort(); AddInfo(tag, pixelRepresentation); break; case (int)(WINDOW_CENTER): String center = GetString(elementLength); int index = center.IndexOf('\\'); if (index != -1) { center = center.Substring(index + 1); } windowCentre = Convert.ToDouble(center, new CultureInfo("en-US")); AddInfo(tag, center); break; case (int)(WINDOW_WIDTH): String widthS = GetString(elementLength); index = widthS.IndexOf('\\'); if (index != -1) { widthS = widthS.Substring(index + 1); } windowWidth = Convert.ToDouble(widthS, new CultureInfo("en-US")); AddInfo(tag, widthS); break; case (int)(RESCALE_INTERCEPT): String intercept = GetString(elementLength); rescaleIntercept = Convert.ToDouble(intercept, new CultureInfo("en-US")); AddInfo(tag, intercept); break; case (int)(RESCALE_SLOPE): String slop = GetString(elementLength); rescaleSlope = Convert.ToDouble(slop, new CultureInfo("en-US")); AddInfo(tag, slop); break; case (int)(RED_PALETTE): reds = GetLut(elementLength); AddInfo(tag, elementLength / 2); break; case (int)(GREEN_PALETTE): greens = GetLut(elementLength); AddInfo(tag, elementLength / 2); break; case (int)(BLUE_PALETTE): blues = GetLut(elementLength); AddInfo(tag, elementLength / 2); break; case (int)(PIXEL_DATA): if (elementLength != 0) { offset = location; AddInfo(tag, location); decodingTags = false; } else { AddInfo(tag, null); } pixelDataTagFound = true; break; default: AddInfo(tag, null); break; } } return(true); }
/// <summary> /// 更换显示图片 /// </summary> /// <param name="filefullnamimage"></param> /// <returns></returns> public Bitmap fB_ChangeImage(string filefullnamimage) { dd.DicomFileName = filefullnamimage; TypeOfDicomFile typeOfDicomFile = dd.typeofDicomFile; if (typeOfDicomFile == TypeOfDicomFile.Dicom3File || typeOfDicomFile == TypeOfDicomFile.DicomOldTypeFile) { imageWidth = dd.width; imageHeight = dd.height; bitDepth = dd.bitsAllocated; if (winCD == DBLNULL) { winCD = dd.windowCentre; } if (winWD == DBLNULL) { winWD = dd.windowWidth; } //if (winCentreD == DBLNULL) winCentreD = dd.windowCentre; //if (winWidthD == DBLNULL) winWidthD = dd.windowWidth; winCentreD = winCD; winWidthD = winWD; samplesPerPixel = dd.samplesPerPixel; signedImage = dd.signedImage; this.NewImage = true; if (samplesPerPixel == 1 && bitDepth == 8) { pixels8.Clear(); pixels16.Clear(); pixels24.Clear(); dd.GetPixels8(ref pixels8); minPixelValue = pixels8.Min(); maxPixelValue = pixels8.Max(); // Bug fix dated 24 Aug 2013 - for proper window/level of signed images // Thanks to Matias Montroull from Argentina for pointing this out. if (dd.signedImage) { winCentreD -= char.MinValue; } if (Math.Abs(winWidthD) < 0.001) { winWidthD = maxPixelValue - minPixelValue; } if ((winCentreD == 0) || (minPixelValue > winCentreD) || (maxPixelValue < winCentreD)) { winCentreD = (maxPixelValue + minPixelValue) / 2; } SetParameters(ref pixels8, imageWidth, imageHeight, winWidthD, winCentreD, samplesPerPixel, true); } if (samplesPerPixel == 1 && bitDepth == 16) { pixels16.Clear(); pixels8.Clear(); pixels24.Clear(); dd.GetPixels16(ref pixels16); minPixelValue = pixels16.Min(); maxPixelValue = pixels16.Max(); // Bug fix dated 24 Aug 2013 - for proper window/level of signed images // Thanks to Matias Montroull from Argentina for pointing this out. if (dd.signedImage) { winCentreD -= short.MinValue; } if (Math.Abs(winWidthD) < 0.001) { winWidthD = maxPixelValue - minPixelValue; } if ((winCentreD == 0) || (minPixelValue > winCentreD) || (maxPixelValue < winCentreD)) { winCentreD = (maxPixelValue + minPixelValue) / 2; } Signed16Image = dd.signedImage; SetParameters(ref pixels16, imageWidth, imageHeight, winWidthD, winCentreD, true); } if (samplesPerPixel == 3 && bitDepth == 8) { // This is an RGB colour image pixels8.Clear(); pixels16.Clear(); pixels24.Clear(); dd.GetPixels24(ref pixels24); SetParameters(ref pixels24, imageWidth, imageHeight, winWidthD, winCentreD, samplesPerPixel, true); } } else { if (typeOfDicomFile == TypeOfDicomFile.DicomUnknownTransferSyntax) { //MessageBox.Show("Sorry, I can't read a DICOM file with this Transfer Syntax.", // "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { //MessageBox.Show("Sorry, I can't open this file. " + // "This file does not appear to contain a DICOM image.", // "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } //Text = "DICOM Image Viewer: "; // Show a plain grayscale image instead try { pixels8.Clear(); pixels16.Clear(); pixels24.Clear(); samplesPerPixel = 1; imageWidth = this.Width - 25; // 25 is a magic number imageHeight = this.Height - 25; // Same magic number int iNoPix = imageWidth * imageHeight; for (int i = 0; i < iNoPix; ++i) { pixels8.Add(240);// 240 is the grayvalue corresponding to the Control colour } winWidthD = 256; winCentreD = 127; this.SetParameters(ref pixels8, imageWidth, imageHeight, winWidthD, winCentreD, samplesPerPixel, true); } catch (Exception) { } //this.Invalidate(); } //fv_BitMapCopy(ref btmtmp, bmp); //复制图片 //fv_ImageWriter(ref btmtmp,ddlist.Count-1); //添加文字 fv_ImageWriter(ref bmp); ComputeScrollBarParameters();//显示位置 return(bmp); }
private void readDicom(string fileName, string fileNameOnly) { dd.DicomFileName = fileName; TypeOfDicomFile typeOfDicomFile = dd.typeofDicomFile; if (typeOfDicomFile == TypeOfDicomFile.Dicom3File || typeOfDicomFile == TypeOfDicomFile.DicomOldTypeFile) { imageWidth = dd.width; imageHeight = dd.height; bitDepth = dd.bitsAllocated; winCentre = dd.windowCentre; winWidth = dd.windowWidth; samplesPerPixel = dd.samplesPerPixel; signedImage = dd.signedImage; label1.Visible = true; label2.Visible = true; label3.Visible = true; label4.Visible = true; bnSave.Enabled = true; bnTags.Enabled = true; bnResetWL.Enabled = true; label2.Text = imageWidth.ToString() + " X " + imageHeight.ToString(); if (samplesPerPixel == 1) { label4.Text = bitDepth.ToString() + " bit"; } else { label4.Text = bitDepth.ToString() + " bit, " + samplesPerPixel + " samples per pixel"; } imagePanelControl.NewImage = true; Text = "DICOM Image Viewer: " + fileNameOnly; pixels16.Clear(); pixels8.Clear(); pixels24.Clear(); dd.GetPixels16(ref pixels16); // This is primarily for debugging purposes, // to view the pixel values as ascii data. //if (true) //{ // System.IO.StreamWriter file = new System.IO.StreamWriter( // "C:\\imageSigned.txt"); // for (int ik = 0; ik < pixels16.Count; ++ik) // file.Write(pixels16[ik] + " "); // file.Close(); //} minPixelValue = pixels16.Min(); maxPixelValue = pixels16.Max(); // Bug fix dated 24 Aug 2013 - for proper window/level of signed images // Thanks to Matias Montroull from Argentina for pointing this out. if (dd.signedImage) { winCentre -= short.MinValue; } if (Math.Abs(winWidth) < 0.001) { winWidth = maxPixelValue - minPixelValue; } if ((winCentre == 0) || (minPixelValue > winCentre) || (maxPixelValue < winCentre)) { winCentre = (maxPixelValue + minPixelValue) / 2; } imagePanelControl.Signed16Image = dd.signedImage; imagePanelControl.SetParameters(ref pixels16, imageWidth, imageHeight, winWidth, winCentre, true, this); } }
public int SaveImage(string Path, string path) { DirectoryInfo d = new DirectoryInfo(Path); FileInfo[] files = d.GetFiles(); int i = 1; foreach (FileInfo f in files) { string PathSave = HttpContext.Current.Server.MapPath("~/DicomImage/" + path); if (!Directory.Exists(PathSave)) { Directory.CreateDirectory(PathSave); } Class.File file = new Class.File(); file.NameFile = f.Name; file.TypeFile = f.Extension; DicomDecoder dd = new DicomDecoder(); dd.DicomFileName = f.FullName; double winCentre = dd.windowCentre; double winWidth = dd.windowWidth; int samplesPerPixel = dd.samplesPerPixel; bool signedImage = dd.signedImage; int minPixelValue = 1; int maxPixelValue = 0; PathSave += i + ".png"; TypeOfDicomFile typeOfDicomFile = dd.typeofDicomFile; int imageWidth = dd.width; int imageHeight = dd.height; bmp = new Bitmap(imageWidth, imageHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb); dd.GetPixels8(ref pixels8); dd.GetPixels16(ref pixels16); dd.GetPixels24(ref pixels24); if (pixels8 != null) { minPixelValue = pixels8.Min(); maxPixelValue = pixels8.Max(); // Bug fix dated 24 Aug 2013 - for proper window/level of signed images // Thanks to Matias Montroull from Argentina for pointing this out. if (dd.signedImage) { winCentre -= char.MinValue; } if (Math.Abs(winWidth) < 0.001) { winWidth = maxPixelValue - minPixelValue; } if ((winCentre == 0) || (minPixelValue > winCentre) || (maxPixelValue < winCentre)) { winCentre = (maxPixelValue + minPixelValue) / 2; } ResetValues(winWidth, winCentre); pix8 = pixels8; ComputeLookUpTable8(); CreateImage8(imageWidth, imageHeight); } else if (pixels16 != null) { minPixelValue = pixels16.Min(); maxPixelValue = pixels16.Max(); // Bug fix dated 24 Aug 2013 - for proper window/level of signed images // Thanks to Matias Montroull from Argentina for pointing this out. if (dd.signedImage) { winCentre -= short.MinValue; } if (Math.Abs(winWidth) < 0.001) { winWidth = maxPixelValue - minPixelValue; } if ((winCentre == 0) || (minPixelValue > winCentre) || (maxPixelValue < winCentre)) { winCentre = (maxPixelValue + minPixelValue) / 2; } ResetValues(winWidth, winCentre); pix16 = pixels16; ComputeLookUpTable16(); CreateImage16(imageWidth, imageHeight); } else if (pixels24 != null) { minPixelValue = pixels8.Min(); maxPixelValue = pixels8.Max(); // Bug fix dated 24 Aug 2013 - for proper window/level of signed images // Thanks to Matias Montroull from Argentina for pointing this out. if (dd.signedImage) { winCentre -= char.MinValue; } if (Math.Abs(winWidth) < 0.001) { winWidth = maxPixelValue - minPixelValue; } if ((winCentre == 0) || (minPixelValue > winCentre) || (maxPixelValue < winCentre)) { winCentre = (maxPixelValue + minPixelValue) / 2; } ResetValues(winWidth, winCentre); pix24 = pixels24; ComputeLookUpTable8(); CreateImage24(imageWidth, imageHeight); } i++; if (bmp != null) { bmp.Save(PathSave, ImageFormat.Png); } } return(i); }
private void ReadAndDisplayDicomFile(string fileName, string fileNameOnly) { dd.DicomFileName = fileName; TypeOfDicomFile typeOfDicomFile = dd.typeofDicomFile; if (typeOfDicomFile == TypeOfDicomFile.Dicom3File || typeOfDicomFile == TypeOfDicomFile.DicomOldTypeFile) { imageWidth = dd.width; imageHeight = dd.height; bitDepth = dd.bitsAllocated; winCentre = dd.windowCentre; winWidth = dd.windowWidth; samplesPerPixel = dd.samplesPerPixel; signedImage = dd.signedImage; label1.Visible = true; label2.Visible = true; label3.Visible = true; label4.Visible = true; bnSave.Enabled = true; bnTags.Enabled = true; bnResetWL.Enabled = true; label2.Text = imageWidth.ToString() + " X " + imageHeight.ToString(); if (samplesPerPixel == 1) { label4.Text = bitDepth.ToString() + " bit"; } else { label4.Text = bitDepth.ToString() + " bit, " + samplesPerPixel + " samples per pixel"; } imagePanelControl.NewImage = true; Text = "DICOM Image Viewer: " + fileNameOnly; if (samplesPerPixel == 1 && bitDepth == 8) { pixels8.Clear(); pixels16.Clear(); pixels24.Clear(); dd.GetPixels8(ref pixels8); // This is primarily for debugging purposes, // to view the pixel values as ascii data. //if (true) //{ // System.IO.StreamWriter file = new System.IO.StreamWriter( // "C:\\imageSigned.txt"); // for (int ik = 0; ik < pixels8.Count; ++ik) // file.Write(pixels8[ik] + " "); // file.Close(); //} minPixelValue = pixels8.Min(); maxPixelValue = pixels8.Max(); // Bug fix dated 24 Aug 2013 - for proper window/level of signed images // Thanks to Matias Montroull from Argentina for pointing this out. if (dd.signedImage) { winCentre -= char.MinValue; } if (Math.Abs(winWidth) < 0.001) { winWidth = maxPixelValue - minPixelValue; } if ((winCentre == 0) || (minPixelValue > winCentre) || (maxPixelValue < winCentre)) { winCentre = (maxPixelValue + minPixelValue) / 2; } imagePanelControl.SetParameters(ref pixels8, imageWidth, imageHeight, winWidth, winCentre, samplesPerPixel, true, this); } if (samplesPerPixel == 1 && bitDepth == 16) { pixels16.Clear(); pixels8.Clear(); pixels24.Clear(); dd.GetPixels16(ref pixels16); // This is primarily for debugging purposes, // to view the pixel values as ascii data. //if (true) //{ // System.IO.StreamWriter file = new System.IO.StreamWriter( // "C:\\imageSigned.txt"); // for (int ik = 0; ik < pixels16.Count; ++ik) // file.Write(pixels16[ik] + " "); // file.Close(); //} minPixelValue = pixels16.Min(); maxPixelValue = pixels16.Max(); // Bug fix dated 24 Aug 2013 - for proper window/level of signed images // Thanks to Matias Montroull from Argentina for pointing this out. if (dd.signedImage) { winCentre -= short.MinValue; } if (Math.Abs(winWidth) < 0.001) { winWidth = maxPixelValue - minPixelValue; } if ((winCentre == 0) || (minPixelValue > winCentre) || (maxPixelValue < winCentre)) { winCentre = (maxPixelValue + minPixelValue) / 2; } imagePanelControl.Signed16Image = dd.signedImage; imagePanelControl.SetParameters(ref pixels16, imageWidth, imageHeight, winWidth, winCentre, true, this); } if (samplesPerPixel == 3 && bitDepth == 8) { // This is an RGB colour image pixels8.Clear(); pixels16.Clear(); pixels24.Clear(); dd.GetPixels24(ref pixels24); // This code segment is primarily for debugging purposes, // to view the pixel values as ascii data. //if (true) //{ // System.IO.StreamWriter file = new System.IO.StreamWriter( // "C:\\image24.txt"); // for (int ik = 0; ik < pixels24.Count; ++ik) // file.Write(pixels24[ik] + " "); // file.Close(); //} imagePanelControl.SetParameters(ref pixels24, imageWidth, imageHeight, winWidth, winCentre, samplesPerPixel, true, this); } } else { if (typeOfDicomFile == TypeOfDicomFile.DicomUnknownTransferSyntax) { MessageBox.Show("Sorry, I can't read a DICOM file with this Transfer Syntax.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { MessageBox.Show("Sorry, I can't open this file. " + "This file does not appear to contain a DICOM image.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } Text = "DICOM Image Viewer: "; // Show a plain grayscale image instead pixels8.Clear(); pixels16.Clear(); pixels24.Clear(); samplesPerPixel = 1; imageWidth = imagePanelControl.Width - 25; // 25 is a magic number imageHeight = imagePanelControl.Height - 25; // Same magic number int iNoPix = imageWidth * imageHeight; for (int i = 0; i < iNoPix; ++i) { pixels8.Add(240);// 240 is the grayvalue corresponding to the Control colour } winWidth = 256; winCentre = 127; imagePanelControl.SetParameters(ref pixels8, imageWidth, imageHeight, winWidth, winCentre, samplesPerPixel, true, this); imagePanelControl.Invalidate(); label1.Visible = false; label2.Visible = false; label3.Visible = false; label4.Visible = false; bnSave.Enabled = false; bnTags.Enabled = false; bnResetWL.Enabled = false; } }
private void ReadAndDisplayDicomFile(string fileName, string fileNameOnly) { dd.DicomFileName = fileName; TypeOfDicomFile typeOfDicomFile = dd.typeofDicomFile; if (typeOfDicomFile == TypeOfDicomFile.Dicom3File || typeOfDicomFile == TypeOfDicomFile.DicomOldTypeFile) { imageWidth = dd.width; imageHeight = dd.height; bitDepth = dd.bitsAllocated; winCentre = dd.windowCentre; winWidth = dd.windowWidth; samplesPerPixel = dd.samplesPerPixel; signedImage = dd.signedImage; bnTags.Enabled = true; imagePanelControl.NewImage = true; Text = "DICOM Image Viewer: " + fileNameOnly; if (samplesPerPixel == 1 && bitDepth == 8) { pixels8.Clear(); pixels16.Clear(); pixels24.Clear(); dd.GetPixels8(ref pixels8); minPixelValue = pixels8.Min(); maxPixelValue = pixels8.Max(); if (dd.signedImage) { winCentre -= char.MinValue; } if (Math.Abs(winWidth) < 0.001) { winWidth = maxPixelValue - minPixelValue; } if ((winCentre == 0) || (minPixelValue > winCentre) || (maxPixelValue < winCentre)) { winCentre = (maxPixelValue + minPixelValue) / 2; } imagePanelControl.SetParameters(ref pixels8, imageWidth, imageHeight, winWidth, winCentre, samplesPerPixel, true, this); } if (samplesPerPixel == 1 && bitDepth == 16) { pixels16.Clear(); pixels8.Clear(); pixels24.Clear(); dd.GetPixels16(ref pixels16); minPixelValue = pixels16.Min(); maxPixelValue = pixels16.Max(); if (dd.signedImage) { winCentre -= short.MinValue; } if (Math.Abs(winWidth) < 0.001) { winWidth = maxPixelValue - minPixelValue; } if ((winCentre == 0) || (minPixelValue > winCentre) || (maxPixelValue < winCentre)) { winCentre = (maxPixelValue + minPixelValue) / 2; } imagePanelControl.Signed16Image = dd.signedImage; imagePanelControl.SetParameters(ref pixels16, imageWidth, imageHeight, winWidth, winCentre, true, this); } if (samplesPerPixel == 3 && bitDepth == 8) { // This is an RGB colour image pixels8.Clear(); pixels16.Clear(); pixels24.Clear(); dd.GetPixels24(ref pixels24); imagePanelControl.SetParameters(ref pixels24, imageWidth, imageHeight, winWidth, winCentre, samplesPerPixel, true, this); } } else { if (typeOfDicomFile == TypeOfDicomFile.DicomUnknownTransferSyntax) { MessageBox.Show("Xin lỗi, File DiCOM này không thể mở!", "Chú Ý !!!", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { MessageBox.Show("Xin lỗi, File này không tồn tại ảnh", "Chú Ý !!!", MessageBoxButtons.OK, MessageBoxIcon.Error); } Text = "DICOM Image Viewer: "; // Show a plain grayscale image instead pixels8.Clear(); pixels16.Clear(); pixels24.Clear(); samplesPerPixel = 1; imageWidth = imagePanelControl.Width - 25; // 25 is a magic number imageHeight = imagePanelControl.Height - 25; // Same magic number int iNoPix = imageWidth * imageHeight; for (int i = 0; i < iNoPix; ++i) { pixels8.Add(240);// 240 is the grayvalue corresponding to the Control colour } winWidth = 256; winCentre = 127; imagePanelControl.SetParameters(ref pixels8, imageWidth, imageHeight, winWidth, winCentre, samplesPerPixel, true, this); imagePanelControl.Invalidate(); //bnSave.Enabled = false; bnTags.Enabled = false; } List <string> lstString = dd.dicomInfo; SetString(ref lstString); }
public bool ReadFileInfo() { long skipCount = Convert.ToInt32(ID_OFFSET); bitsAllocated = 16; file.BaseStream.Seek(skipCount, SeekOrigin.Begin); location += ID_OFFSET; if (GetString(4) != DICM) { // This is for reading older DICOM files (Before 3.0) // Seek from the beginning of the file file.BaseStream.Seek(0, SeekOrigin.Begin); location = 0; // Older DICOM files do not have the preamble and prefix dicmFound = false; // Continue reading further. // See whether the width, height and pixel data tags // are present. If these tags are present, then it we conclude that this is a // DICOM file, because all DICOM files should have at least these three tags. // Otherwise, it is not a DICOM file. } else { // We have a DICOM 3.0 file dicmFound = true; } bool decodingTags = true; samplesPerPixel = 1; photoInterpretation = ""; string modality; while (decodingTags) { int tag = GetNextTag(); if ((location & 1) != 0) { oddLocations = true; } if (inSequence) { AddInfo(tag, null); continue; } string s; switch (tag) { case (int)(TRANSFER_SYNTAX_UID): s = GetString(elementLength); AddInfo(tag, s); if (s.IndexOf("1.2.4", StringComparison.Ordinal) > -1 || s.IndexOf("1.2.5", StringComparison.Ordinal) > -1) { file.Close(); typeofDicomFile = TypeOfDicomFile.DicomUnknownTransferSyntax; // Return gracefully indicating that this type of // Transfer Syntax cannot be handled return(false); } if (s.IndexOf("1.2.840.10008.1.2.2", StringComparison.Ordinal) >= 0) { bigEndianTransferSyntax = true; } break; case (int)(SERIES_NUMBER): s = GetString(elementLength); SeriesNumber = Convert.ToInt32(s); AddInfo(tag, s); break; case (int)(INSTANCE_NUMBER): s = GetString(elementLength); InstanceNumber = Convert.ToInt32(s); ; AddInfo(tag, s); break; case (int)MODALITY: modality = GetString(elementLength); AddInfo(tag, modality); break; case (int)(NUMBER_OF_FRAMES): s = GetString(elementLength); AddInfo(tag, s); double frames = Convert.ToDouble(s, new CultureInfo("en-US")); if (frames > 1.0) { nImages = (int)frames; } break; case (int)(SAMPLES_PER_PIXEL): samplesPerPixel = GetShort(); AddInfo(tag, samplesPerPixel); break; case (int)(PHOTOMETRIC_INTERPRETATION): photoInterpretation = GetString(elementLength); photoInterpretation = photoInterpretation.Trim(); AddInfo(tag, photoInterpretation); break; case (int)(PLANAR_CONFIGURATION): int planarConfiguration = GetShort(); AddInfo(tag, planarConfiguration); break; case (int)(ROWS): height = GetShort(); AddInfo(tag, height); heightTagFound = true; break; case (int)(COLUMNS): width = GetShort(); AddInfo(tag, width); widthTagFound = true; break; case (int)(PIXEL_SPACING): String scale = GetString(elementLength); PixelSpacingValue = scale.Split(new char[] { '\\' }, 2); GetSpatialScale(scale); AddInfo(tag, scale); break; case (int)(SLICE_SPACING): String space = GetString(elementLength); pixeSpace = Convert.ToDouble(space, new CultureInfo("en-US")); AddInfo(tag, space); break; case (int)(SLICE_THICKNESS): String spacing = GetString(elementLength); pixelDepth = Convert.ToDouble(spacing, new CultureInfo("en-US")); AddInfo(tag, spacing); break; case (int)(BITS_ALLOCATED): bitsAllocated = GetShort(); AddInfo(tag, bitsAllocated); break; case (int)(PIXEL_REPRESENTATION): pixelRepresentation = GetShort(); AddInfo(tag, pixelRepresentation); break; case (int)(WINDOW_CENTER): String center = GetString(elementLength); int index = center.IndexOf('\\'); if (index != -1) { center = center.Substring(index + 1); } windowCentre = Convert.ToDouble(center, new CultureInfo("en-US")); AddInfo(tag, center); break; case (int)(WINDOW_WIDTH): String widthS = GetString(elementLength); index = widthS.IndexOf('\\'); if (index != -1) { widthS = widthS.Substring(index + 1); } windowWidth = Convert.ToDouble(widthS, new CultureInfo("en-US")); AddInfo(tag, widthS); break; case (int)(RESCALE_INTERCEPT): String intercept = GetString(elementLength); rescaleIntercept = Convert.ToDouble(intercept, new CultureInfo("en-US")); AddInfo(tag, intercept); break; case (int)(RESCALE_SLOPE): String slop = GetString(elementLength); rescaleSlope = Convert.ToDouble(slop, new CultureInfo("en-US")); AddInfo(tag, slop); break; case (int)(RED_PALETTE): reds = GetLut(elementLength); AddInfo(tag, elementLength / 2); break; case (int)(GREEN_PALETTE): greens = GetLut(elementLength); AddInfo(tag, elementLength / 2); break; case (int)(BLUE_PALETTE): blues = GetLut(elementLength); AddInfo(tag, elementLength / 2); break; case (int)(PIXEL_DATA): if (elementLength != 0) { offset = location; AddInfo(tag, location); decodingTags = false; } else { AddInfo(tag, null); } pixelDataTagFound = true; break; default: AddInfo(tag, null); break; } } return(true); }
public bool ReadFileInfo() /////读取各个DataElement中的VF,并将其保存起来 { long skipCount = Convert.ToInt32(ID_OFFSET); //数据元素起始地址128 bitsAllocated = 16; file.BaseStream.Seek(skipCount, SeekOrigin.Begin);//访问skipCount二进制 location += ID_OFFSET; if (GetString(4) != DICM)//128字节后的四个字节存放“DICM” //GetString()是自定义方法:从当前位置起,读取指定字节数,并返回为字符串类型 { //用于读取3.0之前的DICOM文件 // 找文件开始处 file.BaseStream.Seek(0, SeekOrigin.Begin); location = 0; // 3.0之前的DICOM文件没有序言和前缀( preamble and prefix) dicmFound = false; // 继续读取信息. //查看宽、高、像素标签是否存在。 //如果这些标记存在,那么我们就会得出结论,这是一个DICOM文件, //因为所有的DICOM文件都应该至少有这三个标记。 //否则,它不是DICOM文件。 } else { // true表示文件是3.0的版本 dicmFound = true; } /////接下来读取DICOM文件信息 bool decodingTags = true; samplesPerPixel = 1;///通道数为1 int planarConfiguration = 0; photoInterpretation = ""; string modality; while (decodingTags) { int tag = GetNextTag();///读取下一个Tag if ((location & 1) != 0) { oddLocations = true; } if (inSequence)/////未定义标签?????? { AddInfo(tag, null); continue; } string s; switch (tag) { case (int)(TRANSFER_SYNTAX_UID): ///00020010决定普通Tag的读取方式Little-Endlian还是Big-Endlian,以及VR的显式隐式 s = GetString(elementLength); //读取elementLength长度的数据 AddInfo(tag, s); ////Tag为00020010时可以通过VF值判断Little/Big,VR显式/隐式 if (s.IndexOf("1.2.4") > -1 || s.IndexOf("1.2.5") > -1) ///字符串匹配返回第一次出现的位置 { file.Close(); typeofDicomFile = TypeOfDicomFile.DicomUnknownTransferSyntax; // 表示无法处理 return(false); } if (s.IndexOf("1.2.840.10008.1.2.2") >= 0) { bigEndianTransferSyntax = true; } break; case (int)MODALITY: ///检查模态(MRI/CT/CR/DR) modality = GetString(elementLength); AddInfo(tag, modality); break; case (int)(NUMBER_OF_FRAMES): s = GetString(elementLength); AddInfo(tag, s); double frames = Convert.ToDouble(s, new CultureInfo("en-US")); if (frames > 1.0) { nImages = (int)frames; } break; case (int)(SAMPLES_PER_PIXEL): ///图像上的采样率. samplesPerPixel = GetShort(); ////采样率 AddInfo(tag, samplesPerPixel); break; case (int)(PHOTOMETRIC_INTERPRETATION): ///光度计的解释,对于CT图像,用两个枚举值MONOCHROME1,MONOCHROME //2.用来判断图像是否是彩色的,MONOCHROME1/2是灰度图, RGB则是真彩色图,还有其他. photoInterpretation = GetString(elementLength); photoInterpretation = photoInterpretation.Trim(); AddInfo(tag, photoInterpretation); break; case (int)(PLANAR_CONFIGURATION): planarConfiguration = GetShort(); AddInfo(tag, planarConfiguration); break; case (int)(ROWS): //图像的总行数,行分辨率. height = GetShort(); AddInfo(tag, height); heightTagFound = true; break; case (int)(COLUMNS): //图像的总列数,列分辨率. width = GetShort(); AddInfo(tag, width); widthTagFound = true; break; case (int)(PIXEL_SPACING): //像素间距.像素中心之间的物理间距. String scale = GetString(elementLength); GetSpatialScale(scale); ///赋值像素行距,列距 AddInfo(tag, scale); break; case (int)(SLICE_THICKNESS): //层厚 case (int)(SLICE_SPACING): //层与层之间的间距,单位为mm String spacing = GetString(elementLength); pixelDepth = Convert.ToDouble(spacing, new CultureInfo("en-US")); AddInfo(tag, spacing); break; case (int)(BITS_ALLOCATED): //分配的位数:存储每一个像素值时分配的位数,每一个样本应该拥有相同的这个值. bitsAllocated = GetShort(); AddInfo(tag, bitsAllocated); break; case (int)(PIXEL_REPRESENTATION): //像素数据的表现类型:这是一个枚举值,分别为十六进制数0000和0001.0000H = 无符号整数,0001H = 2的补码. pixelRepresentation = GetShort(); AddInfo(tag, pixelRepresentation); break; case (int)(WINDOW_CENTER): //窗位******* String center = GetString(elementLength); int index = center.IndexOf('\\'); if (index != -1) { center = center.Substring(index + 1); } windowCentre = Convert.ToDouble(center, new CultureInfo("en-US")); ///********** AddInfo(tag, center); break; case (int)(WINDOW_WIDTH): //窗宽******* String widthS = GetString(elementLength); index = widthS.IndexOf('\\'); if (index != -1) { widthS = widthS.Substring(index + 1); } windowWidth = Convert.ToDouble(widthS, new CultureInfo("en-US")); ////********** AddInfo(tag, widthS); break; case (int)(RESCALE_INTERCEPT): ///截距:如果表明不同模态的LUT颜色对应表不存在时,则使用方程Units = m*SV + b,计算真实的像素值到呈现像素值。其中这个值为表达式中的b。 String intercept = GetString(elementLength); rescaleIntercept = Convert.ToDouble(intercept, new CultureInfo("en-US")); AddInfo(tag, intercept); break; case (int)(RESCALE_SLOPE): ///斜率.这个值为表达式中的m String slop = GetString(elementLength); rescaleSlope = Convert.ToDouble(slop, new CultureInfo("en-US")); AddInfo(tag, slop); break; case (int)(RED_PALETTE): reds = GetLut(elementLength); AddInfo(tag, elementLength / 2); break; case (int)(GREEN_PALETTE): greens = GetLut(elementLength); AddInfo(tag, elementLength / 2); break; case (int)(BLUE_PALETTE): blues = GetLut(elementLength); AddInfo(tag, elementLength / 2); break; case (int)(PIXEL_DATA): // 图像数据开始处 if (elementLength != 0) { offset = location; AddInfo(tag, location); decodingTags = false; } else { AddInfo(tag, null); } pixelDataTagFound = true; break; default: AddInfo(tag, null); /////不用的Tag暂时赋值为空 break; } } return(true); }