txt - c#: ¿cómo leer partes de un archivo?(DICOM)
manejo de archivos binarios c# (6)
Aquí hay una muestra en C #: http://www.codeproject.com/KB/graphics/dicomImageViewer.aspx
Me gustaría leer un archivo DICOM en C #. No quiero hacer nada elegante, solo por ahora me gustaría saber cómo leer en los elementos, pero primero me gustaría saber cómo leer el encabezado para ver si es un archivo DICOM válido .
Consiste en elementos de datos binarios. Los primeros 128 bytes no se utilizan (se establece en cero), seguidos de la cadena ''DICM''. A esto le sigue la información del encabezado, que está organizada en grupos.
Un encabezado DICOM de muestra
First 128 bytes: unused DICOM format. Followed by the characters ''D'',''I'',''C'',''M'' Followed by extra header information such as: 0002,0000, File Meta Elements Groups Len: 132 0002,0001, File Meta Info Version: 256 0002,0010, Transfer Syntax UID: 1.2.840.10008.1.2.1. 0008,0000, Identifying Group Length: 152 0008,0060, Modality: MR 0008,0070, Manufacturer: MRIcro
En el ejemplo anterior, el encabezado está organizado en grupos. El grupo 0002 hex es el grupo de metainformación de archivos que contiene 3 elementos: uno define la longitud del grupo, uno almacena la versión del archivo y su almacena la sintaxis de transferencia.
Preguntas
- ¿Cómo leo el archivo de encabezado y verifico si es un archivo DICOM al buscar los caracteres ''D'', ''I'', ''C'', ''M'' después del preámbulo de 128 bytes?
- ¿Cómo continúo analizando el archivo leyendo las otras partes de los datos?
Algo así debería leer el archivo, es básico y no maneja todos los casos, pero sería un punto de partida:
public void ReadFile(string filename)
{
using (FileStream fs = File.OpenRead(filename))
{
fs.Seek(128, SeekOrigin.Begin);
if (!(fs.ReadByte() != (byte)''D'' ||
fs.ReadByte() != (byte)''I'' ||
fs.ReadByte() != (byte)''C'' ||
fs.ReadByte() != (byte)''M''))
{
Console.WriteLine("Not a DCM");
return;
}
BinaryReader reader = new BinaryReader(fs);
ushort g;
ushort e;
do
{
g = reader.ReadUInt16();
e = reader.ReadUInt16();
string vr = new string(reader.ReadChars(2));
long length;
if (vr.Equals("AE") || vr.Equals("AS") || vr.Equals("AT")
|| vr.Equals("CS") || vr.Equals("DA") || vr.Equals("DS")
|| vr.Equals("DT") || vr.Equals("FL") || vr.Equals("FD")
|| vr.Equals("IS") || vr.Equals("LO") || vr.Equals("PN")
|| vr.Equals("SH") || vr.Equals("SL") || vr.Equals("SS")
|| vr.Equals("ST") || vr.Equals("TM") || vr.Equals("UI")
|| vr.Equals("UL") || vr.Equals("US"))
length = reader.ReadUInt16();
else
{
// Read the reserved byte
reader.ReadUInt16();
length = reader.ReadUInt32();
}
byte[] val = reader.ReadBytes((int) length);
} while (g == 2);
fs.Close();
}
return ;
}
El código en realidad no intenta tener en cuenta que la sintaxis de transferencia de los datos codificados puede cambiar después de los elementos del grupo 2, sino que tampoco intenta hacer nada con los valores reales leídos.
Solo algunos pseudológicos
¿Cómo leo el archivo de encabezado y verifico si es un archivo DICOM al buscar los caracteres ''D'', ''I'', ''C'', ''M'' después del preámbulo de 128 bytes?
- Abrir como archivo binario, utilizando File.OpenRead
- Busque la posición 128 y lea 4 bytes en la matriz y compárela con el valor de bytes por [] para DICM. Puedes usar ASCIIEncoding.GetBytes () para eso
¿Cómo continúo analizando el archivo leyendo las otras partes de los datos?
- Continúe leyendo el archivo usando Read o ReadByte usando el manejador de objetos FileStream que tiene anteriormente
- Use el mismo método como arriba para hacer su comparación.
No te olvides de cerrar y desechar el archivo.
también puedes usar esto.
FileStream fs = File.OpenRead(path);
byte[] data = new byte[132];
fs.Read(data, 0, data.Length);
int b0 = data[0] & 255, b1 = data[1] & 255, b2 = data[2] & 255, b3 = data[3] & 255;
if (data[128] == 68 && data[129] == 73 && data[130] == 67 && data[131] == 77)
{
//dicom file
}
else if ((b0 == 8 || b0 == 2) && b1 == 0 && b3 == 0)
{
//dicom file
}
Tomado de EvilDicom.Helper.DicomReader de la biblioteca Evil Dicom :
public static bool IsValidDicom(BinaryReader r)
{
try
{
//128 null bytes
byte[] nullBytes = new byte[128];
r.Read(nullBytes, 0, 128);
foreach (byte b in nullBytes)
{
if (b != 0x00)
{
//Not valid
Console.WriteLine("Missing 128 null bit preamble. Not a valid DICOM file!");
return false;
}
}
}
catch (Exception)
{
Console.WriteLine("Could not read 128 null bit preamble. Perhaps file is too short");
return false;
}
try
{
//4 DICM characters
char[] dicm = new char[4];
r.Read(dicm, 0, 4);
if (dicm[0] != ''D'' || dicm[1] != ''I'' || dicm[2] != ''C'' || dicm[3] != ''M'')
{
//Not valid
Console.WriteLine("Missing characters D I C M in bits 128-131. Not a valid DICOM file!");
return false;
}
return true;
}
catch (Exception)
{
Console.WriteLine("Could not read DICM letters in bits 128-131.");
return false;
}
}