Descargar el proyecto - ELAI-UPM

Anuncio
Desarrollo de aplicaciones DICOM para la gestión
de imágenes biomédicas
Fernando Ballesteros Herranz
Octubre 2003
“En los momentos de crisis, sólo la imaginación es más importante que el
conocimiento”
(Albert Einstein)
“Lo único que podemos decidir es qué hacer con el tiempo que se nos ha dado”
(Gandalf)
“Al final todo es pasajero, incluso la oscuridad se acaba para dar paso a un nuevo
dı́a, y cuando el sol brilla, brilla más radiante aún”
(SamSagaz Gamyi)
Dedicado a mis padres Juli y Heliodoro, mi tı́a Encarni, mi hermana Helena y
especialmente a mi novia Araceli por todo el apoyo y la ayuda que me ha prestado
en la realización de este proyecto durante este largo tiempo.
También lo dedico a mis compañeros de proyecto, Ricardo, David, Marta, Iván,
José, Bakali, Thomas, Wouter y Jeroen con los que tanto momentos buenos he pasado
y a un compañero de fatigas a lo largo de toda la carrera, Pedro Luı́s.
Agradecer a Carlos Platero, Roberto González y Miguel Ángel Sanchez-Urán la
confianza depositada en mı́ y la guı́a que han sido para mı́ en la realización de este
proyecto y la posibilidad que me han dado de poder aprender.
Resumen
El estándar DICOM (Digital Imaging and Communications in Medicine) nació en
el año 1993, a partir de un rediseñado completo de la publicación normalizada No
33-1988 de ACR-NEMA, y pertenece al campo de la informática médica, por lo que,
en principio esta norma se solapa con otras de este campo.
El estándar DICOM 3.0 permite la transmisión, tratamiento e impresión de archivos
DICOM, que son imágenes biomédicas con un informe cada uno del estudio realizado.
Se ha realizado una aplicación basándonos en el estándar, que permita compartir
archivos en un entorno distribuido; dicho de otra manera, una aplicación que permita
a los clientes visualizar, mandar y recibir los archivos contenidos de un servidor.
El presente trabajo, describe un sistema multiplataforma desarrollado para el
manejo, procesamiento y auditorı́a de Imágenes de Diagnóstico Médico a través de
redes (Intra o Internet). El sistema está basado en un diseño Cliente/Servidor orientado a objetos, para el cual se utilizó como lenguaje de programación JAVA, y se
realizó de acuerdo a la norma DICOM 3.0.
Para la realización de la aplicación se ha trabajado con librerı́as JDT (Java Dicom
Toolkit), con las librerı́as JDK 1.4.1., en el entorno JBuilder Enterprise 7. Ha sido
desarrollada enteramente en JAVA y puede ser utilizable en cualquier sistema operativo.
Como parte del proyecto fin de carrera, también se han realizado las tareas de
administración de sistemas (Windows NT, 2000 y Linux) y mantenimiento del servidor
Web Apache (www.elai.upm.es) del departamento.
Abstract
The standard DICOM (Digital Imaging and Communications in Medicine) was
born in the year 1993, from complete re-designed of the normalized publication No
33-1988 of ACR-NEMA, and it belongs to the field of the medical computer science,
for what, at first this norm lapel with others of this field.
The standard DICOM 3.0 allows the transmission, treatment and impression of
files DICOM, which are biomedical images with a report each of the realized study.
An application has been realized basing on the standard, which allows to share
files in a distributed environment; said otherwise, an application that it allows the
clients to visualize, to order and to receive the files contained of a servant.
The present work, a system describes multiplatform developed for the managing,
processing and audit of Images of Medical Diagnosis across nets (Intra or Internet).
The system is based on a design Cliente/Servidor orientated to objects, for which was
used as language of programming JAVA, and were realized in agreement to the norm
DICOM 3.0.
For the accomplishment of the application one has worked with libraries JDT (Java
Dicom Toolkit), with the libraries JDK 1.4.1., in the environment JBuilder Enterprise
7. It has been developed entirely in JAVA and can be usable in any operative system.
As a part of my project, I have done system administration tasks (Windows
NT, 2000 and Linux) and the maintenance of the department Apache Web server
(www.elai.upm.es).
Índice general
1. Introducción
1
1.1. Marco del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
1.2. Objetivos del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . .
3
1.3. Sumario del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
2. El Estado de la técnica
5
2.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
2.2. Librerı́a de Imágenes Médicas . . . . . . . . . . . . . . . . . . . . . .
6
2.2.1. Librerı́as de Imágenes Médicas . . . . . . . . . . . . . . . . . .
7
2.2.2. Arquitecturas para librerı́as digitales de imágenes . . . . . . .
12
2.3. Estándar DICOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
2.3.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
2.3.2. Historia de DICOM . . . . . . . . . . . . . . . . . . . . . . . .
17
2.3.3. Procesamiento Distribuido . . . . . . . . . . . . . . . . . . . .
19
2.3.4. Conceptos generales de DICOM . . . . . . . . . . . . . . . . .
21
2.3.5. Conceptos de DICOM Network . . . . . . . . . . . . . . . . .
33
2.3.6. Clases de Servicio soportados . . . . . . . . . . . . . . . . . .
37
i
ÍNDICE GENERAL
Fernando Ballesteros Herranz
2.3.7. Conectividad . . . . . . . . . . . . . . . . . . . . . . . . . . .
41
2.3.8. Estándar DICOM . . . . . . . . . . . . . . . . . . . . . . . . .
43
2.3.9. Instancias SOP de imágenes DICOM . . . . . . . . . . . . . .
46
2.3.10. Modelo de información de las imágenes . . . . . . . . . . . . .
46
2.3.11. Instancias imagen SOP . . . . . . . . . . . . . . . . . . . . . .
49
2.3.12. Relaciones e indentificación . . . . . . . . . . . . . . . . . . .
50
2.3.13. Clasificación de los datos de imagen . . . . . . . . . . . . . . .
53
2.3.14. Extensión de la información . . . . . . . . . . . . . . . . . . .
58
2.3.15. Tipos de imágenes . . . . . . . . . . . . . . . . . . . . . . . .
59
2.3.16. Procesando imagen . . . . . . . . . . . . . . . . . . . . . . . .
63
2.3.17. Aplicación de los Datos de las Imagenes . . . . . . . . . . . .
72
2.3.18. El futuro de DICOM . . . . . . . . . . . . . . . . . . . . . . .
74
2.4. Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
76
3. Librerı́as DCMTK de Offis
ii
77
3.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
77
3.2. Estandarización de la Comunicación de Imagenes Médicas . . . . . .
77
3.3. Descripción de DICOM según Offis . . . . . . . . . . . . . . . . . . .
78
3.3.1. Estructura de los datos en el estándar DICOM . . . . . . . . .
79
3.3.2. Servicios de Red . . . . . . . . . . . . . . . . . . . . . . . . .
79
3.3.3. Intercambio de medios de comunicación . . . . . . . . . . . . .
79
3.3.4. Declaración de Conformidad . . . . . . . . . . . . . . . . . . .
80
3.4. Librerı́as DCMTK . . . . . . . . . . . . . . . . . . . . . . . . . . . .
80
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
ÍNDICE GENERAL
3.4.1. Instalación de librerı́as . . . . . . . . . . . . . . . . . . . . . .
81
3.4.2. Dcmnet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
83
3.4.3. Dcmjpeg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
85
3.4.4. DicomScope . . . . . . . . . . . . . . . . . . . . . . . . . . . .
85
3.5. Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
90
4. Programación en JAVA
91
4.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
91
4.2. Instalación de la JVM . . . . . . . . . . . . . . . . . . . . . . . . . .
92
4.3. El compilador de Java . . . . . . . . . . . . . . . . . . . . . . . . . .
94
4.4. Variables y tipos de datos . . . . . . . . . . . . . . . . . . . . . . . .
95
4.4.1. Comentarios . . . . . . . . . . . . . . . . . . . . . . . . . . . .
95
4.4.2. Identificadores . . . . . . . . . . . . . . . . . . . . . . . . . . .
96
4.4.3. Palabras clave reservadas . . . . . . . . . . . . . . . . . . . . .
96
4.4.4. Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
96
4.4.5. Matrices o vectores . . . . . . . . . . . . . . . . . . . . . . . .
98
4.5. Operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
99
4.5.1. Operadores aritméticos . . . . . . . . . . . . . . . . . . . . . .
99
4.5.2. Operadores de asignación
99
. . . . . . . . . . . . . . . . . . . .
4.5.3. Operadores a nivel de bit . . . . . . . . . . . . . . . . . . . . . 100
4.5.4. Operadores relacionales . . . . . . . . . . . . . . . . . . . . . . 100
4.5.5. Operadores lógicos booleanos . . . . . . . . . . . . . . . . . . 101
4.6. Control del flujo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
r
GVA-ELAI-UPMPFC0075-2003
iii
ÍNDICE GENERAL
Fernando Ballesteros Herranz
4.6.1. Instrucción condicional if-else . . . . . . . . . . . . . . . . . . 101
4.6.2. Instrucción condicional switch . . . . . . . . . . . . . . . . . . 102
4.6.3. Bucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
4.6.4. Otras instrucciones . . . . . . . . . . . . . . . . . . . . . . . . 104
4.7. Clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
4.7.1. Referencias a objetos . . . . . . . . . . . . . . . . . . . . . . . 106
4.7.2. Variables de una instancia . . . . . . . . . . . . . . . . . . . . 106
4.7.3. Operador new . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
4.7.4. Operador(.) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
4.7.5. Declaración de métodos . . . . . . . . . . . . . . . . . . . . . 107
4.7.6. Llamada a métodos . . . . . . . . . . . . . . . . . . . . . . . . 108
4.7.7. Constructores . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
4.7.8. Sobrecarga de métodos . . . . . . . . . . . . . . . . . . . . . . 109
4.7.9. Operador this . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
4.7.10. Herencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
4.8. Paquetes e interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
4.8.1. Paquetes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
4.8.2. Protección de accesos . . . . . . . . . . . . . . . . . . . . . . . 113
4.8.3. Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
4.9. Gestión de cadenas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
4.9.1. Constructores . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
4.9.2. Métodos de String . . . . . . . . . . . . . . . . . . . . . . . . 114
iv
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
ÍNDICE GENERAL
4.9.3. Conversión a String . . . . . . . . . . . . . . . . . . . . . . . . 115
4.10. Gestión de excepciones . . . . . . . . . . . . . . . . . . . . . . . . . . 116
4.10.1. try y catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
4.10.2. throw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
4.10.3. finally . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
4.10.4. Gestión incompleta de las excepciones . . . . . . . . . . . . . 118
4.11. Hilos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
4.11.1. Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
4.11.2. Runnable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
4.11.3. Prioridades de los hilos . . . . . . . . . . . . . . . . . . . . . . 121
4.11.4. Sincronización . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
4.11.5. Comunicación entre hilos . . . . . . . . . . . . . . . . . . . . . 122
4.11.6. Métodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
4.12. Utilidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
4.12.1. Envolturas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
4.12.2. Enumeraciones . . . . . . . . . . . . . . . . . . . . . . . . . . 126
4.12.3. Runtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
4.12.4. System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
4.12.5. Date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
4.13. Entrada/Salida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
4.13.1. File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
4.13.2. InputStream . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
r
GVA-ELAI-UPMPFC0075-2003
v
ÍNDICE GENERAL
Fernando Ballesteros Herranz
4.13.3. OutputStream . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
4.13.4. Flujo de archivo . . . . . . . . . . . . . . . . . . . . . . . . . . 131
4.13.5. Flujos filtrados . . . . . . . . . . . . . . . . . . . . . . . . . . 132
4.13.6. SequenceInputStream . . . . . . . . . . . . . . . . . . . . . . . 133
4.13.7. Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
4.14. Trabajo en Red . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
4.14.1. InetAddress . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
4.14.2. Datagramas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
4.14.3. Conectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
4.14.4. Conexión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
4.15. Interfaces Gráficas de Usuario . . . . . . . . . . . . . . . . . . . . . . 140
4.15.1. Componentes AWT . . . . . . . . . . . . . . . . . . . . . . . . 140
4.15.2. Organización . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
4.15.3. Componentes de menú . . . . . . . . . . . . . . . . . . . . . . 143
4.15.4. Componentes Swing . . . . . . . . . . . . . . . . . . . . . . . 143
4.15.5. Eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
4.16. Encriptación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
4.16.1. Arquitectura Criptográfica de Java (JCA) . . . . . . . . . . . 145
4.16.2. Extensión criptográfica de Java (JCE) . . . . . . . . . . . . . 148
4.17. Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
5. Estudio de librerı́as JDT
151
5.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
vi
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
ÍNDICE GENERAL
5.2. Terminologı́a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
5.3. Datasets o conjunto de datos . . . . . . . . . . . . . . . . . . . . . . . 152
5.3.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
5.3.2. Manipulación de los atributos . . . . . . . . . . . . . . . . . . 152
5.3.3. Entrada/Salida de los datasets DICOM . . . . . . . . . . . . . 155
5.3.4. Métodos útiles . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
5.4. Depósitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
5.4.1. Clase DDict: depósito de atributos . . . . . . . . . . . . . . . 159
5.4.2. Clase UID: depósitos UID . . . . . . . . . . . . . . . . . . . . 160
5.5. Imágenes en JDT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
5.5.1. La clase DicomImage . . . . . . . . . . . . . . . . . . . . . . . 161
5.6. Guı́a para usuarios de JDT . . . . . . . . . . . . . . . . . . . . . . . . 161
5.6.1. Insertar datos que no son de imagen . . . . . . . . . . . . . . 161
5.6.2. Insertar datos de imagen con los métodos de DicomImage . . . 162
5.6.3. Insertando los datos de imagen con ImageProducer . . . . . . 162
5.6.4. Compresión . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
5.7. Creación de una conexión . . . . . . . . . . . . . . . . . . . . . . . . 165
5.7.1. Iniciador de la asociación . . . . . . . . . . . . . . . . . . . . . 165
5.7.2. Receptor de la asociación . . . . . . . . . . . . . . . . . . . . . 167
5.8. Estructura de JDT . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
5.8.1. Árbol de clases . . . . . . . . . . . . . . . . . . . . . . . . . . 170
5.8.2. Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
r
GVA-ELAI-UPMPFC0075-2003
vii
ÍNDICE GENERAL
Fernando Ballesteros Herranz
5.9. Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
6. Desarrollo de aplicación
177
6.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
6.2. Uso de SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
6.2.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
6.2.2. Instalación en Windows 98 . . . . . . . . . . . . . . . . . . . . 178
6.2.3. Instalación en Windows 2000 . . . . . . . . . . . . . . . . . . 181
6.2.4. Utilidades del SDK . . . . . . . . . . . . . . . . . . . . . . . . 182
6.3. Uso de TextPad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
6.3.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
6.3.2. Caracterı́sticas . . . . . . . . . . . . . . . . . . . . . . . . . . 186
6.3.3. Uso con Java . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
6.4. Uso de JBuilder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
6.4.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
6.4.2. Instalación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
6.4.3. JDK y JBuilder . . . . . . . . . . . . . . . . . . . . . . . . . . 189
6.4.4. Creación de aplicaciones en JBuilder . . . . . . . . . . . . . . 190
6.5. Instalación de JDT . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
6.5.1. Instalación en Windows 95/98 . . . . . . . . . . . . . . . . . . 212
6.5.2. Instalación en Windows NT/2000/XP
. . . . . . . . . . . . . 213
6.5.3. Incluir JDT en JBuilder . . . . . . . . . . . . . . . . . . . . . 213
6.6. Implementación de Servidor DICOM . . . . . . . . . . . . . . . . . . 215
viii
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
ÍNDICE GENERAL
6.6.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
6.6.2. Listar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
6.6.3. Enviar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
6.6.4. Guardar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
6.6.5. Query/Retrieve . . . . . . . . . . . . . . . . . . . . . . . . . . 219
6.6.6. Editar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
6.6.7. Encriptación/Desencriptación . . . . . . . . . . . . . . . . . . 221
6.7. Implementación de Cliente DICOM . . . . . . . . . . . . . . . . . . . 222
6.7.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
6.7.2. Panel Cliente-Servidor . . . . . . . . . . . . . . . . . . . . . . 223
6.7.3. Panel VisorDicom . . . . . . . . . . . . . . . . . . . . . . . . . 228
6.7.4. Panel Procesamiento . . . . . . . . . . . . . . . . . . . . . . . 241
6.7.5. Panel Crear DICOM . . . . . . . . . . . . . . . . . . . . . . . 245
6.7.6. Distribución e instalación de la aplicación . . . . . . . . . . . 253
6.8. Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
A. Administración de sistemas
257
A.1. Introducción a Windows NT y 2000 . . . . . . . . . . . . . . . . . . . 257
A.1.1. Presentación del sistema operativo NT . . . . . . . . . . . . . 257
A.1.2. Sistemas de archivos . . . . . . . . . . . . . . . . . . . . . . . 258
A.1.3. El interfaz de usuario de NT . . . . . . . . . . . . . . . . . . . 259
A.2. La red Microsoft Windows . . . . . . . . . . . . . . . . . . . . . . . . 260
A.2.1. Los grupos de trabajo . . . . . . . . . . . . . . . . . . . . . . 260
r
GVA-ELAI-UPMPFC0075-2003
ix
ÍNDICE GENERAL
Fernando Ballesteros Herranz
A.2.2. Los dominios NT . . . . . . . . . . . . . . . . . . . . . . . . . 261
A.2.3. Uso de los dominios de NT . . . . . . . . . . . . . . . . . . . . 261
A.2.4. Elementos de un dominio . . . . . . . . . . . . . . . . . . . . . 262
A.2.5. El sistema de recursos de red . . . . . . . . . . . . . . . . . . 263
A.2.6. Inicio de sesión en un grupo de trabajo . . . . . . . . . . . . . 266
A.2.7. Inicio de sesión en un dominio . . . . . . . . . . . . . . . . . . 267
A.2.8. Los controladores de dominio . . . . . . . . . . . . . . . . . . 268
A.2.9. Diferencias entre NT Workstation y NT Server . . . . . . . . . 268
A.3. El Administrador de usuarios . . . . . . . . . . . . . . . . . . . . . . 269
A.3.1. Creación y modificación de usuarios en el dominio . . . . . . . 270
A.3.2. Creación de grupos . . . . . . . . . . . . . . . . . . . . . . . . 275
A.4. Permisos y seguridad . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
A.4.1. Administración del plan de cuentas . . . . . . . . . . . . . . . 277
A.4.2. Administración del plan de derechos de usuarios . . . . . . . . 278
A.5. Permisos y seguridad en NT . . . . . . . . . . . . . . . . . . . . . . . 279
A.5.1. Los perfiles de usuario en NT . . . . . . . . . . . . . . . . . . 279
A.5.2. Perfiles de usuario frente a perfiles obligatorios . . . . . . . . . 280
A.5.3. Tipos de perfiles de usuarios . . . . . . . . . . . . . . . . . . . 280
A.5.4. El directorio de perfiles en NT . . . . . . . . . . . . . . . . . . 281
A.5.5. Creación de un perfil en NT 4.0 . . . . . . . . . . . . . . . . . 282
A.6. El editor de directivas POLEDIT.EXE . . . . . . . . . . . . . . . . . 283
A.6.1. Funcionamiento de las directivas . . . . . . . . . . . . . . . . . 284
x
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
ÍNDICE GENERAL
A.6.2. Creación de las directivas del sistema para un dominio . . . . 284
A.6.3. Modo de funcionamiento de las directivas . . . . . . . . . . . . 285
A.6.4. Directivas para sistemas, usuarios y grupos . . . . . . . . . . . 286
A.7. El protocolo TCP/IP . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
A.7.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
A.7.2. El protocolo TCP/IP frente a otros protocolos . . . . . . . . . 287
A.7.3. Elementos del protocolo TCP/IP . . . . . . . . . . . . . . . . 288
A.7.4. El sistema de direcciones del protocolo IP . . . . . . . . . . . 289
A.7.5. El mecanismo de difusión (broadcast) en el protocolo IP . . . 291
A.7.6. Implementación del protocolo TCP/IP en NT . . . . . . . . . 291
A.7.7. Configuración del protocolo TCP/IP en NT . . . . . . . . . . 291
r
GVA-ELAI-UPMPFC0075-2003
xi
Índice de figuras
2.1. Clasificación de las imágenes médicas . . . . . . . . . . . . . . . . . .
7
2.2. Arquitectura de una libreria digital de imágenes . . . . . . . . . . . .
12
2.3. Modelo de protocolo de comunicaciones DICOM . . . . . . . . . . . .
19
2.4. Procesamiento distribuido . . . . . . . . . . . . . . . . . . . . . . . .
19
2.5. Transmisión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
2.6. Modelo de un proceso distribuido . . . . . . . . . . . . . . . . . . . .
21
2.7. Clases de Servicio de DICOM . . . . . . . . . . . . . . . . . . . . . .
22
2.8. Relación entre los IODs y los atributos . . . . . . . . . . . . . . . . .
24
2.9. Ejemplo de un IOD de imagen compuesto . . . . . . . . . . . . . . .
25
2.10. Ejemplo de los atributos del módulo Paciente . . . . . . . . . . . . .
26
2.11. Estructura del mensaje DICOM . . . . . . . . . . . . . . . . . . . . .
28
2.12. Estructura del Data Element . . . . . . . . . . . . . . . . . . . . . . .
29
2.13. Visión general de la codificación y decodificación de las instacias SOP
32
2.14. DICOM y el intercambio “network” . . . . . . . . . . . . . . . . . . .
33
2.15. Ejemplos de Contextos de Presentación . . . . . . . . . . . . . . . . .
35
2.16. Capas OSI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
xiii
ÍNDICE DE FIGURAS
Fernando Ballesteros Herranz
2.17. Conexión TCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
2.18. Definición de objeto compartido con Media Service Class . . . . . . .
40
2.19. Conformance Statement con Perfil de Sistema . . . . . . . . . . . . .
41
2.20. Conformance Statement con Perfil de Aplicación . . . . . . . . . . . .
43
2.21. Relaciones entre las Partes del estándar DICOM. . . . . . . . . . . .
45
2.22. Modelo de información . . . . . . . . . . . . . . . . . . . . . . . . . .
47
2.23. Ejemplo de mapeado de una imagen CT . . . . . . . . . . . . . . . .
49
2.24. Modelo de información de una imagen compuesta DICOM . . . . . .
51
2.25. Clasificación de la información de la imagen . . . . . . . . . . . . . .
54
2.26. Juego básico de atributos de las instancias de imagen SOP . . . . . .
60
2.27. Pasos del proceso y tipos de datos de la imagen . . . . . . . . . . . .
64
2.28. Muestreo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
65
2.29. Datos de pixel con la conversión de los valores del pixel . . . . . . . .
66
2.30. Pasos del proceso de la presentación de una imagen . . . . . . . . . .
67
2.31. Decodificación de los Datos de Pixel . . . . . . . . . . . . . . . . . . .
69
2.32. Modalidad dependiendo de la escala y la conversión . . . . . . . . . .
70
2.33. Conversión a escala de grises . . . . . . . . . . . . . . . . . . . . . . .
71
2.34. Ciclo de vida de la información de una Image SOP Instance . . . . .
72
3.1. Librerı́as DCMTK . . . . . . . . . . . . . . . . . . . . . . . . . . . .
83
3.2. Base de Datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
3.3. Archivo de configuración de DicomScope . . . . . . . . . . . . . . . .
87
3.4. Viewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
88
xiv
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
ÍNDICE DE FIGURAS
3.5. Print . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
3.6. Process Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
90
4.1. Evolución de Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
92
4.2. Bibliotecas de clases de Java . . . . . . . . . . . . . . . . . . . . . . .
93
4.3. Compilación y ejecución . . . . . . . . . . . . . . . . . . . . . . . . .
95
4.4. Palabras clave de Java . . . . . . . . . . . . . . . . . . . . . . . . . .
96
4.5. Operaderes relacionales . . . . . . . . . . . . . . . . . . . . . . . . . . 101
4.6. Operaderes lógicos booleanos
. . . . . . . . . . . . . . . . . . . . . . 101
4.7. Propagación de excepciones . . . . . . . . . . . . . . . . . . . . . . . 116
4.8. Flujos estándar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
4.9. Jerarquı́a de componentes del AWT . . . . . . . . . . . . . . . . . . . 142
4.10. Componentes Swing . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
4.11. Layout de Swing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
5.1. Conversión entre tipo Java y tipo DICOM . . . . . . . . . . . . . . . 152
5.2. Conversión de tipo DICOM a tipo Java . . . . . . . . . . . . . . . . . 175
6.1. API de SDK 1.4.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
6.2. Compilación con SDK . . . . . . . . . . . . . . . . . . . . . . . . . . 183
6.3. Api generada con Javadocs . . . . . . . . . . . . . . . . . . . . . . . . 184
6.4. Entorno de trabajo de TextPad 4.7.0 . . . . . . . . . . . . . . . . . . 187
6.5. Configuración de JDK . . . . . . . . . . . . . . . . . . . . . . . . . . 189
6.6. Designación de nuevas JDK . . . . . . . . . . . . . . . . . . . . . . . 190
r
GVA-ELAI-UPMPFC0075-2003
xv
ÍNDICE DE FIGURAS
Fernando Ballesteros Herranz
6.7. Asistente para proyectos . . . . . . . . . . . . . . . . . . . . . . . . . 191
6.8. Galerı́a de objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
6.9. Asistente para aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . 193
6.10. Vista en diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
6.11. contentPane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
6.12. Editor de texto ejecutado
. . . . . . . . . . . . . . . . . . . . . . . . 196
6.13. Menú . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
6.14. Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
6.15. actionPerformed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
6.16. jMenu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
6.17. Bibliotecas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
6.18. Configurar bibliotecas
. . . . . . . . . . . . . . . . . . . . . . . . . . 214
6.19. Listado en Servidor . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
6.20. El servidor envı́a objeto Dicom . . . . . . . . . . . . . . . . . . . . . 217
6.21. El servidor recibe objeto Dicom . . . . . . . . . . . . . . . . . . . . . 218
6.22. Panel Ciente-Servidor . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
6.23. Botón Base De Datos y Enviar
. . . . . . . . . . . . . . . . . . . . . 225
6.24. Botón Coger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
6.25. Botón Editar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
6.26. Panel Visor DICOM . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
6.27. Zoom In y Zoom Out . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
6.28. Zoom con eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
xvi
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
ÍNDICE DE FIGURAS
6.29. Botones Siguiente y Anterior . . . . . . . . . . . . . . . . . . . . . . . 234
6.30. Botón Seguidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
6.31. Botón Guardar JPEG . . . . . . . . . . . . . . . . . . . . . . . . . . 236
6.32. Insertar y ver datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
6.33. Crear campos nuevos . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
6.34. Nuevo campo insertado . . . . . . . . . . . . . . . . . . . . . . . . . . 241
6.35. Panel Procesamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
6.36. Botón para añadir archivos al proyecto . . . . . . . . . . . . . . . . . 244
6.37. Botón para abrir imagen a procesar . . . . . . . . . . . . . . . . . . . 244
6.38. Botón para procesar imagen . . . . . . . . . . . . . . . . . . . . . . . 245
6.39. Panel Crear DICOM . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
6.40. Imagen para crear un archivo Dicom . . . . . . . . . . . . . . . . . . 247
6.41. Datos de texto a insertar . . . . . . . . . . . . . . . . . . . . . . . . . 248
6.42. Comprobación de la creación de archivo Dicom en escala de grises . . 249
6.43. Comprobación de la creación de archivo Dicom en RGB . . . . . . . . 250
6.44. Generación de ejecutables . . . . . . . . . . . . . . . . . . . . . . . . 253
6.45. Creador de ejecutables . . . . . . . . . . . . . . . . . . . . . . . . . . 253
6.46. Marcas de la creación de ejecutables . . . . . . . . . . . . . . . . . . . 254
A.1. Conectar a unidad de red . . . . . . . . . . . . . . . . . . . . . . . . . 265
A.2. Administrador de Usuarios . . . . . . . . . . . . . . . . . . . . . . . . 269
A.3. Administrador de Usuarios; usuario nuevo . . . . . . . . . . . . . . . 270
A.4. Administrador de Usuarios; usuario nuevo; grupos . . . . . . . . . . . 272
r
GVA-ELAI-UPMPFC0075-2003
xvii
ÍNDICE DE FIGURAS
Fernando Ballesteros Herranz
A.5. Administrador de Usuarios; usuario nuevo; perfil . . . . . . . . . . . . 272
A.6. Administrador de Usuarios; usuario nuevo; horas . . . . . . . . . . . . 273
A.7. Administrador de Usuarios; usuario nuevo; iniciar de sesión . . . . . . 274
A.8. Administrador de Usuarios; usuario nuevo; cuenta . . . . . . . . . . . 274
A.9. Administrador de Usuarios; usuario nuevo; marcado . . . . . . . . . . 275
A.10.Administrador de Usuario; directivas; plan de derechos de usuarios . . 278
A.11.Panel de Control; Sistema; Perfiles de Usuario; Copiar a
. . . . . . . 282
A.12.El editor de directivas del sistema . . . . . . . . . . . . . . . . . . . . 285
A.13.El Editor de Directivas del Sistema, Equipo . . . . . . . . . . . . . . 286
A.14.Panel de control. Red . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
A.15.Panel de control. Red. Protocolos. Agregar protocolo TCP/IP . . . . 293
A.16.Protocolo TCP/IP, Dirección IP, Avanzado . . . . . . . . . . . . . . . 294
A.17.Protocolo TCP/IP, Dirección IP, Avanzadas . . . . . . . . . . . . . . 295
A.18.Protocolo TCP/IP, Enrutamiento . . . . . . . . . . . . . . . . . . . . 296
xviii
r
GVA-ELAI-UPMPFC0075-2003
Capı́tulo 1
Introducción
DICOM1 es un estándar en comunicación e imágenes en medicina, que facilita el
manejo de información médica entre hospitales y centros de investigación.
La gran importancia de este estándar es que da la posibilidad de interconectar
sistemas informáticos de diferentes fabricantes y hace posible la comunicación entre
ellos; en un hospital donde los aparatos médicos son de muchas marcas diferentes
debido a la especialización.
DICOM hace posible que los archivos médicos puedan viajar de forma segura entre
hospitales, centros de investigación y departamentos. Luego esa información puede ser
vista remotamente para que los médicos puedan diagnosticar desde su casa y buscar
diferentes opiniones de otros expertos de una forma rápida y sencilla.
La creciente utilización de sistemas de adquisición y tratamiento digital de imágenes
médicas ha hecho necesaria la adopción de un estándar que posibilite el intercambio
de éstas. Las imágenes médicas son muy importantes para los diagnósticos de pacientes, tratamientos terapéuticos y evaluación de resultados. Gracias a las nuevas
técnicas de imágenes digitales, tales como la topografı́a computarizada, angiografı́a
por sustracción digital, resonancia magnética y ası́ sucesivamente, han reducido las
dosis de radiación a los pacientes y los cortes anatómicos.
DICOM poco a poco se está introduciendo en todo el ámbito sanitario, y que sin
duda facilitará el manejo de la información médica.
Los objetivos del estándar son:
Lograr una interfaz común para todos los dispositivos de imágenes (tomografı́a,
1
Digital Imaging and Communications in Medicine
1
CAPÍTULO 1. INTRODUCCIÓN
Fernando Ballesteros Herranz
resonancia magnética, ultrasonido, rayos x, etc.)
Intentar desligar Dicom de las instituciones que lo desarrollan para que realmente pueda ser un estándar independiente.
Dicom 3.0 debe ser aplicable a toda la esfera de las imágenes médicas, desde su
transmisión hasta el tratamiento e impresión.
De momento la estandarización poco a poco va tomando forma:
Se define la utilización de protocolos OSI, para asegurar una comunicación eficiente y que soporte una amplia variedad de tecnologı́as de red basadas en
normas OSI, CSMA/CD, ATM, X.25, etc. Y TCP/IP como protocolo de transporte, que es abierto y compatible con las redes que se están instalando en los
centros sanitarios.
Los estándares de codificación de la información y los datos resultantes de utilizar los Objetos de Información (imágenes, informes, etc.) con las Clases de
Servicio (impresión, almacenamiento, etc.), se homogeneizan.
Técnicas de compresión normalizadas (JPEG con y sin pérdidas)
Reglas de codificación para construir una secuencia de datos para ser transmitida como un mensaje.
1.1.
Marco del proyecto
El marco del proyecto realizado es:
en primer lugar, el estudio del estándar Dicom
en segundo lugar, estudio de librerı́as DCMTK2
en tercer lugar, estudio de librerı́as JDT3
y en cuarto lugar, desarrollo de la aplicación.
El presente trabajo ha sido realizado en etapas, la primera de las cuales consistió en
el estudio de la norma DICOM 3.0, base fundamental de este trabajo.
2
3
2
DICOM Toolkit
Java DICOM Toolkit
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
1.2. OBJETIVOS DEL PROYECTO
La siguiente etapa fue el estudio y prueba de las librerı́as DCMTK desarrolladas
en C++ y de las cuales se vieron aplicaciones como DicomScope o la conectividad
entre dos máquinas.
Luego se estudió el Toolkit de Java, y paralelamente este lenguaje de programación
orientado a objetos.
Una vez visto que las librerı́as JDT son las que más nos interesaron, se llevó a
cabo la implementación de nuestra aplicación.
La aplicación que se ha creado está desarrollada en lenguaje Java,con la herramienta JBuilder Enterprise 7 y el editor TextPad, bajo plataforma Intel y sistema
operativo Windows 2000.
También se han estado haciendo labores de mantenimiento de la red del laboratorio
del Grupo de Visión Artificial(GVA) del Departamento de Electrónica, Automática
e Informática Industrial y la web (www.elai.upm.es) del departamento.
Cabe reseñar, que tratándose de un proyecto realizado en el ámbito de la investigación, la mejor forma ha sido escribirlo en formato LATEX.
1.2.
Objetivos del proyecto
Este proyecto trata de ser una guı́a completa para el estudio del estándar Dicom,
sus posibles aplicaciones y utilización en el futuro.
Se han estudiado dos toolkit de Dicom con el fin de ver cual serı́a más útil para el
desarrollo de una aplicación final, en la que los principales servicios que proporciona
el estándar puedan ser operativos y utilizables para la medicina del nuevo siglo, ya
que DICOM ha tenido un importante avance en el último año.
1.3.
Sumario del proyecto
Este proyecto se encuentra dividido por capı́tulos y apéndices que pretenden
mostrar los trabajos y conocimientos adquiridos durante el año de trabajo.
De esta forma, en el capı́tulo 2 se desarrolla la base teórica del estándar DICOM,
y es parte fundamental para la comprensión del trabajo realizado y desarrollo de las
aplicaciones, es posible que requiera más de una lectura para entender el estándar.
r
GVA-ELAI-UPMPFC0075-2003
3
CAPÍTULO 1. INTRODUCCIÓN
Fernando Ballesteros Herranz
En el capı́tulo 3, se explica la instalación y utilización de las librerı́as de C++
proporcionadas por OffisDicom, ası́ como una pequeña aplicación realizada con ellas,
para la transmisión de objetos Dicom por la red. También se describe, la utilización de
una aplicación desarrollada parte en Java parte con las librerı́as de C++. Esta aplicación es el DicomScope, y se explica el funcionamiento de cada parte del programa
y la transmisión de estudios por red.
El 4 es una guı́a para aprender a programar en Java, tanto conceptos sencillos
como los más complicados como los hilos, los sockets y la encriptación. Este capı́tulo
es fundamental para entender los siguientes capı́tulos ya que el programa y las librerı́as
utilizadas están desarrollas en Java.
El estudio de las librerı́as JDT y las funciones que implementan del estándar
Dicom están explicadas en el capı́tulo 5.
Finalmente en el capı́tulo 6, se explica el camino seguido y la forma de uso del
programa desarrollado en java y utilizando las librerı́as JDT ası́ como las conclusiones
finales.
El apéndice A pretende ser una pequeña guı́a para la administración de sistemas
Windows de Red, basada en la experiencia a lo largo del proyecto.
4
r
GVA-ELAI-UPMPFC0075-2003
Capı́tulo 2
El Estado de la técnica
2.1.
Introducción
En este capı́tulo se hace una introducción a los conceptos y el estado actual en el
que se encuentran:
Imágenes médicas distribuidas
Estándar DICOM
La primera parte es la relativa a la distribución de imágenes médicas donde se
verá el estado en el que se encuentran las técnicas de distribución de imágenes, principalmente a través de Internet, como las librerı́as digitales de imágenes médicas.
En la segunda parte se van a explicar los conceptos definidos en el estándar
DICOM, partiendo de un modelo de proceso distribuido.
Finalmente, se llegará a la explicación de los conceptos de DICOM Network, para
realizar la conectividad entre las máquinas y la explicación de los servicios que el
estándar ofrece.
5
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
2.2.
Fernando Ballesteros Herranz
Librerı́a de Imágenes Médicas
[BOBA00] [TJAND99]
Los sistemas tradicionales de gestión de imágenes médicas, tales como los sistemas de visualización y de archivo y comunicación, están basados en estaciones de
trabajo especializadas y sistemas de arquitectura cerrada. La tecnologı́a de Internet
está siendo explorada para la distribución eficiente y rentable de imágenes médicas.
Las imágenes médicas son el corazón de los diagnósticos de pacientes, tratamientos
terapeúticos, planificación quirúrgica, muestreo de enfermedades, y a largo plazo para
repetir evaluaciones de resultados. En las pasadas tres décadas, ha habido tremendos cambios con la llegada de nuevas técnicas como la tomografı́a computarizada
(CT), resonancia magnética (MRI), resonancia espectroscópica (MRS), resonancia
magnética funcional (fMRI), angiografı́a por sustracción digital (DSA), tomografı́a
por emisión de positrones (PET), magnetic source imagin (MSI), y ası́ sucesivamente.
Estas modalidades de imágenes digitales, que actualmente constituyen alrededor
del 30 por ciento de los análisis de imágenes médicas en los Estados Unidos, han
revolucionado la manera de adquirir imágenes de pacientes. Han proporcionado un
método no invasivo para ver cortes transversales anatómicos y estados fisiológicos, y
han reducido la dosis de radiación a los pacientes y los traumas de reconocimiento. El
otro 70 por ciento de análisis de imágenes de cráneo, tórax, pecho, abdomen, y hueso
están hechas en los convencionales rayos X o radiografı́a digital (CR). Diferentes tipos
de pelı́culas digitalizadoras, como los escáner, cámaras de estado sólido, escáner de
tambor (drum scanner) y vı́deo cámaras, se usan rutinariamente para convertir las
pelı́culas planas de rayos X en formato digital para su posterior tratamiento y archivo.
En la figura 2.1 se muestra la clasificación de las modalidades de imágenes médicas
conforme al contenido anatómico (estructural) o fisiológico (funcional) de las imágenes
generadas. Cada una de estas modalidades de imagen proporciona una función y
caracterı́sticas únicas que no pueden ser reemplazadas por las otras modalidades. La
dimensión de una imagen digital se encuentra entre 128 x 128 pixels (p.e., PET y
tomografı́a computarizada por emisión de fotones simples –SPECT– de modalidades
de medicina nuclear) y 4000 x 5000 pixels (p.e., mamografı́a).
Estos avances en la tecnologı́a de la imagen van a continuar. Sin embargo, la reorganización y rediseño de los sistemas de sanidad está cambiando el foco de la imagen
digital de la generación y adquisición de imágenes al post-tratamiento y gestión de
datos de imagen. El motivo de este cambio es para poder obtener el mayor beneficio
posible de los datos que ya existen. Los nuevos cambios principales de la próxima
década se centrarán en la recogida, archivo, indexado, comunicación y gestión de
los datos de imágenes multimedia para una mejor rentabilidad en educación médica,
investigación clı́nica y diagnóstico.
6
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.2. LIBRERÍA DE IMÁGENES MÉDICAS
Figura 2.1: Clasificación de las imágenes médicas
Los FS-PACS (full-scale Picture Archiving and Communication Systems), también llamados en castellano “sistemas de archivo y comunicación de imágenes a gran
escala”, son el método predominante para la gestión de información de imágenes en
los hospitales. Un FS-PACS consiste en una integración de PACS, en información
administrativa dependiente del Servicio de Radiologı́a (en inglés, Radiology Information System –RIS–) e información del hospital (en inglés, Hospital Information
System –HIS–). Los FS-PACS de un hospital de tamaño medio (alrededor de 600-800
camas) podrı́an requerir 1 Terabyte de datos digitales por año en su librerı́a o archivo
de imágenes. Desde 1995 ha habido más de 50 instalaciones de FS-PACS en todo el
mundo, con cientos de PACS y aún más mini-PACS en el funcionamiento cotidiano.
Los PACS están diseñados para revisiones diagnósticas por radiólogos y cardiólogos,
pero estos sistemas tampoco están diseñados para funcionar correctamente en una
distribución de imágenes médicas, esto es, comunicando imágenes médicas y datos
relacionados a otros especialistas como médicos e investigadores. Un sistema abierto
con mecanismos omnipresentes de acceso seguros podrı́a permitir a los usuarios utilizar completamente la funcionabilidad de la librerı́a digital de imágenes médicas de
manera rentable. Las tecnologı́as de Internet y la red mundial WWW proporcionan
una plataforma ideal para el desarrollo de librerı́as de imágenes médicas.
2.2.1.
Librerı́as de Imágenes Médicas
Cuando se diseña, gestiona y utiliza una librerı́a digital de imágenes médicas en
Internet hay que tener en cuenta una serie de puntos que se presentan a continuación.
r
GVA-ELAI-UPMPFC0075-2003
7
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Datos centralizados o datos distribuidos
La decisión de adoptar una base de datos centralizada frente a una arquitectura
de objetos distribuidos está basada en varias consideraciones, como el tamaño de la
base de datos, datos localizados o distribuidos, el número de usuarios, y los servicios
requeridos.
La arquitectura de los PACS estándar está basada en el modelo de base de datos
centralizada, y esto también se aplica a otros sistemas integrados de sanidad, tales
como el Registro Computerizado de Pacientes (en inglés, computerized patient record
–CPR–) y el HIS. Incluso los más recientes desarrollos de los FS-PACS todavı́a consolidan información en un gran registro centralizado. En general, los PACS son sistemas
cerrados, facilitando servicios a un número limitado de estaciones de trabajo, con
frecuencia a través de conexiones de alta velocidad tales como ATM (Asynchronous
Transfer Mode) o Ethernet de 100 Mb/s. Los usuarios necesitan acceso instantáneo
a imágenes de alta resolución para revisión de diagnósticos y revisiones clı́nicas.
A diferencia, una librerı́a de imágenes médicas basada en Internet puede necesitar soportar un gran número de peticiones. La información puede ser distribuida a
través de diferentes departamentos y hospitales, o incluso para revisiones externas y
consultas privadas.
La arquitectura de objetos distribuidos es más apropiada para gestionar tales entornos de información heterogéneos y distribuidos. El modelado de datos es separado
de los clientes, y la lógica comercial es desempeñada en los servidores medios. El sistema distribuido puede aumentar proporcionalmente a un gran número de usuarios,
ofreciendo un funcionamiento y fiabilidad mejorados, y aplicando coherencia a los
datos. Un punto a tener en cuenta con los objetos distribuidos es el coste y complejidad adicional cuando se añaden servidores medios.
Servidor de imágenes basado en PACS o basado en Internet
Los controladores de PACS son programas de aplicación del servidor diseñados
para acceso rápido desde las imágenes archivadas hasta las estaciones especializadas
de visualización para lectura de diagnósticos. La práctica común para facilitar acceso
a través de Internet a los archivos de imágenes en PACS es a través de un servidor
HTTP configurado para comunicarse con los controladores de PACS. El usuario envı́a
peticiones al servidor, el cual en turnos pregunta al controlador de PACS por el
conjunto de imágenes correspondientes. Los controladores de PACS, sin embargo, no
están diseñados para procesar un gran número de solicitudes. La carga de trabajo
extra generada por el servidor HTTP degrada el funcionamiento en conjunto de los
controladores de PACS.
8
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.2. LIBRERÍA DE IMÁGENES MÉDICAS
Otro tema relativo al acceso a las imágenes en PACS a través de Internet es el
soporte del navegador para la resolución de imágenes médicas. Las imágenes médicas
son almacenadas como imágenes en escala de grises, con resoluciones entre 12 y 16
bits/pixel. Las estaciones de trabajo de visualización están especı́ficamente diseñadas
para visionar imágenes de alta resolución. Por el contrario, los navegadores de Internet corren en monitores que no soportan más 256 niveles de escala de grises. Para
solucionar este problema, un módulo de aplicación muestrea las imágenes en PACS a
una resolución menor para visionarlas en los navegadores. La adicción de tal módulo
de aplicación hace que el diseño y integración de los PACS sea más difı́cil, y reduce
en conjunto el funcionamiento del sistema.
En resumen, un controlador de PACS está diseñado para un acceso a imagen
rápido para un número reducido de usuarios (p.e., radiólogos y cardiólogos). Por el
contrario, un servidor de Internet puede manipular un gran número de peticiones,
debido a su naturaleza deslocalizada. Por lo tanto, la librerı́a digital de imágenes
médicas basada en Internet deberı́a ser diseñada con el servidor de Internet como
componente principal y central, antes que módulos de aplicación centralizados en los
controladores de PACS.
Grandes clientes o pequeños clientes
El visionado de imágenes en PACS requiere costosas estaciones de trabajo hechas
a medida, configuradas con múltiples monitores de alta resolución, de 1000 x 1500
a 4000 x 4000 pixels de resolución. Los programas de aplicación están desarrollados
especı́ficamente para correr en tales estaciones de trabajo. Como las estaciones de
trabajo son añadidas o modificadas, la instalación, integración y las actualizaciones
de software son gastos costosos que hay que considerar. A veces, las estaciones de
trabajo pueden necesitar ser rediseñadas para soportar una nueva operatividad.
Por otra parte, los navegadores de Internet pueden funcionar en ordenadores personales relativamente económicos. Los documentos hypermedia y las imágenes son
almacenadas en servidores. En el nivel más sencillo, los documentos son textos planos
con hyperlinks incrustados a imágenes y otros recursos. Con la llegada de lenguajes
de programación basados en Internet, tales como Java, los navegadores tienen mayor grado de operatividad. Las nuevas caracterı́sticas son añadidas a una localización
centralizada, resultando en menos costos y mantenimiento más fácil. Los navegadores
de Internet también permiten acceso omnipresente a imágenes médicas a través de
plataformas de múltiples clientes, mientras se mantiene un interface de usuario medianamente coherente. Sin embargo, la baja resolución de las imágenes y la capacidad
para mostrar niveles de grises de los navegadores limita su uso a lecturas de diagnóstico aproximadas.
r
GVA-ELAI-UPMPFC0075-2003
9
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Visualización 2D o visualización 3D
Los PACS están diseñados para soportar varios modelos de visualización de imágenes
2D, que pueden simular a las radiografı́as convencionales. Las caracterı́sticas añadidas
a la visualización de imágenes digitales incluye soporte de zoom, de rotación, ajustes
panorámicos, de ventana, de nivel. Recientes avances en hardware y lenguajes para
imágenes 3D facilitan el movimiento hacia la visualización 3D.
La pregunta es si hay una necesidad de facilitar visualización 3D online en PACS
o librerı́as de imágenes médicas. Los Radiólogos están entrenados con la habilidad
de reconstruir mentalmente la imagen 3D a partir de cortes de imágenes en 2D. El
complejo proceso de visualización en 3D no añade ninguna nueva información y podrı́a
incluso disminuir su lectura eficiente. Por otro lado, la visualización online es útil para
la interpretación combinada o correlación de imágenes 3D anatómicas o fisiológicas, o
datos metabólicos, y para operaciones en tiempo real de terapia de imágenes guiadas
y procedimientos quirúrgicos. El desafı́o que se presenta es debido no solo al gran
tamaño de las imágenes médicas, sino también a la complejidad de las relaciones
entre los distintos datos.
La implementación del las capacidades de visualización en los PACS o en una
librerı́a de imágenes digitales serı́a probablemente una decisión estratégica de como
uno deberı́a expandir los servicios del sistema a otras disciplinas. Un modelo operativo
consiste en añadir un servidor de visualización potente en una arquitectura Three
Tiered y transmitir los resultados de la visualización a las estaciones clientes a través
de redes de alta velocidad. La ventaja de esta configuración es la reducción de carga
computacional de las estaciones clientes.
Recuperación por el contenido de la imagen
El diseño original de los PACS es para soportar el estudio de imágenes; de esta
manera, las imágenes son recuperadas basándose en claves, tales como el nombre
del paciente o el identificador del hospital. La gestión de documentos de imagen
está basado en sistemas de archivos planos. La ventaja es el simple diseño de modelado
de datos. Este enfoque carece de la capacidad de buscar e indexar las grandes bases de
datos de PACS por el contenido (p.e., las caracterı́sticas de la imagen o las relaciones
de nombre). Esto impide grandemente la utilidad de los PACS para otras operaciones
clı́nicas, tales como referencias online.
La recuperación de imágenes por su contenido (BCIR - Content-based image retrieval) ha sido la llave para la actividad en la investigación de una librarı́a digital de
imágenes. Las actuales técnicas de desarrollo en librerı́as digitales pueden ser adaptadas a los PACS. Muchas de las técnicas existentes, sin embargo, se ocupan de la
10
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.2. LIBRERÍA DE IMÁGENES MÉDICAS
búsqueda a través de caracterı́sticas comunes de las imágenes, tales como el color, forma, textura, o una combinación de estas. Pero en el dominio de las imágenes médicas,
deben ser diseñados todavı́a más algoritmos especı́ficos para la extracción de caracterı́sticas y modelos de datos más complejos y costosos para tomar ventaja de la rica
información contenida en las librerı́as de imágenes médicas.
Privacidad y seguridad de las imágenes médicas
La privacidad del paciente y la seguridad de la información médica es una cuestión
importante que tiene que ser considerada cuando se trata con librerı́as de imágenes
digitales basadas en Internet. Para diagnosis, consulta, o investigación, las imágenes
médicas y los datos del paciente pueden ser distribuidos a instituciones externas fuera
del hospital o clı́nica del paciente.
La seguridad punto a punto (point-to-point) se consigue generalmente a través
de la encriptación. Los actuales algoritmos de encriptación son robustos y los suficientemente fuertes para una amplia aceptación por las comunidades industrial y
gubernamental. La cuestión es integrar la tecnologı́a de codificación en la librerı́a
digital, con un mı́nimo gasto y cambio en el funcionamiento.
Otra cuestión relacionada con la seguridad, es el cribado y filtrado de peticiones.
Tiene que implementarse un mecanismo para la gestión de peticiones permitidas para
cada usuario.
Funcionamiento y fiabilidad
Los usuarios de PACS necesitan acceso rápido a las imágenes médicas para lecturas y diagnósticos primarios, y para ello a menudo se necesitan redes de alta velocidad (p.e., ATM y 100 Base T). Los PACS son esencialmente sistemas cerrados
con un pequeño número de usuarios, asegurando de ese modo un buen funcionamiento comparado con los sistemas basados en Internet. La estrecha relación existente
entre las aplicaciones de visualización y el modelo de datos incrementa además el
funcionamiento. Con más nodos siendo añadidos a Internet, la librerı́a digital basada
en ésta necesita considerar esta cuestión de funcionamiento. La librerı́a digital de
imágenes médicas debe ser capaz de organizar las peticiones clı́nicas no primariascomo tareas principales. Una librerı́a digital de imágenes deberı́a ser diseñada para
lecturas secundarias o búsquedas de datos por referencia.
Implementando una librerı́a digital de imágenes con una intranet se puede lograr
un funcionamiento comparable a los tradicionales sistemas de PACS, mientras economizamos con el uso de ordenadores de escritorio económicos en lugar de estaciones
r
GVA-ELAI-UPMPFC0075-2003
11
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Figura 2.2: Arquitectura de una libreria digital de imágenes
de trabajo de alta calidad. El éxito del funcionamiento de los sistemas basados en
Internet es además el uso de aplicaciones ejecutándose dentro del navegador, tales
como applets de Java. Por esta razón, los algoritmos que requieren extensos cálculos,
tales como la manipulación de imágenes, no se ejecutan eficientemente en el entorno
del navegador.
Los sistemas PACS están creados para funcionar de manera continua, con una
fiabilidad de 24 x 71 . La tecnologı́a en auge basada en Internet, que es relativamente
nueva, tiene todavı́a que solucionar el tema de la fiabilidad. La actual implementación
de una Máquina Virtual de Java tiene todavı́a que probarse para su fiabilidad en
largos periodos de tiempo. Se han realizado muchos trabajos en gestión de sistemas
tradicionales de funcionamiento de red, pero para sistemas de objetos distribuidos,
tales como CORBA, muy poco está disponible en términos de interfaces de gestión
de sistemas y herramientas.
2.2.2.
Arquitecturas para librerı́as digitales de imágenes
Arquitectura de Base Centralizada de Datos
Hay que discutir dos arquitecturas; un modelo de base centralizada de datos y
una arquitectura de objetos distribuidos. La figura 2.2 ilustra la arquitectura general
de un sistema centralizado de datos. Este sistema frecuentemente contiene servidores
de aplicaciones de bases de datos y proporciona capacidad de acceder a Internet.
Debido a su gran tamaño, los estudios de imágenes son archivados en un medio de
1
12
Funcionamiento continuo de 24 horas por 7 dı́as a la semana.
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.2. LIBRERÍA DE IMÁGENES MÉDICAS
almacenamiento diferente (p.e., un jukebox o sistemas de cinta digital).
El enfoque centralizado es extensamente utilizado en los RIS, HIS, y otros sistemas integrados de sanidad. Los FS-PACS también se adaptan a esta estructura.
Existen sistemas que almacenan y reproducen datos en una amplia base centralizada.
Para aplicaciones La ventaja principal de las bases centralizadas es su bajo coste de
desarrollo y mantenimiento.
Los datos multimedia de una librerı́a digital de imágenes consisten en datos de los
archivos de imágenes de PACS, RIS, HIS, bases de datos clı́nicas, o archivos externos.
Esta naturaleza de los datos es inherentemente multimedia, consistiendo en imágenes
médicas, historiales médicos, demografı́as, dictados de voz, e indicaciones biomédicas.
Los datos pueden ser almacenados en un archivo del sistema, o en bases de datos
relacionadas. Una tecnologı́a para aplicaciones en Internet que está en auge son las
bases de datos de objetos. Los protocolos estándar de información médica, tales como
DICOM (Digital Imaging and Communication in Medicine) y HL7 (Health Level
Seven), proporcionan un método a los datos para ser compartidos y archivados.
El servidor de Internet funciona como proxy para las peticiones de los usuarios. El
navegador genera peticiones HTTP (Hypertext Transfer Protocol) en representación
del usuario en el servidor de Internet. Sucesivamente, el servidor Web envı́a la petición
a una máquina de reglas, la cual procesa la petición, construye los tipos de datos
requeridos, y devuelve una respuesta al servidor HTTP y al usuario. Las máquinas
de reglas tienen varias funciones, incluyendo un mecanismo de filtrado de preguntas
o un agente que mapea las solicitudes del usuario a tipos de datos apropiados.
El navegador de Internet es el mecanismo de omnipresencia por el cual los usuarios
acceden a tal sistema. La información puede ser presentada en el formato HTML (Hypertext Markup Language). Los documentos pueden ser gestionados estáticamente integrando los procesos del servidor, tales como el CGI (Common Gateway Interface).
El reciente desarrollo de XML (Extended Markup Language) favorecerá las capacidades avanzadas del navegador proporcionando caracteres definidos por el usuario.
El surgimiento de los lenguajes de programación basados en Internet, tales como Java, permiten capacitar al navegador para cargar y ejecutar dinámicamente pequeñas
aplicaciones, llamadas applets. Ventajas de este método es la gestión de aplicaciones
centralizadas y un interface coherente a través de múltiples plataformas. Existen
varias desventajas en el uso de Java y el navegador; el funcionamiento se convierte en
un problema cuando los applets son interpretados dinámicamente por el navegador.
Por esta razón, los applets de Java están restringidos en tamaño y complejidad.
r
GVA-ELAI-UPMPFC0075-2003
13
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Arquitectura de Objetos Distribuidos
Mientras las bases de datos centralizadas ofrecen simplicidad en el desarrollo y
bajo coste de mantenimiento, no trabajan bien con cargas de trabajo grandes y sistemas heterogéneos. Sin embargo, existe una resistencia en las organizaciones médicas actualmente a ser atadas en una arquitectura basada en la solución de un único
vendedor. Los sistemas existentes de soporte de almacenamiento de datos necesitan
protocolos y modelos de datos comunes para facilitar transacciones con las bases de
datos. Los problemas surgen cuando las fuentes de datos existentes utilizan protocolos y modelos de datos diferentes. Además de esto, las transacciones son realizadas
contra una única base centralizada. Un sistema centralizado con un amplio número
de usuarios aplica una considerable carga de trabajo en el servidor. Una parada en el
servidor detiene el sistema entero.
La tecnologı́a de objetos distribuidos soluciona estas cuestiones definiendo el middleware (infraestructura) entre el cliente y la fuente heterogénea de datos, y automatizando muchas tareas de desarrollo tales como inscripción, localización, activación y
demultiplexado de objetos. Los objetos distribuidos son similares a las abstracciones
de objetos en los lenguajes de programación. Los objetos distribuidos proporcionan
un conjunto de campos y métodos accesibles a los clientes. Una framework (sistema)
es proporcionado para la gestión de objetos distribuidos. Los objetos proveen a los
usuarios un modelo virtual de la fuente de datos, permitiendo una integración de
modelos de datos y protocolos heterogéneos. El framework puede replicar dinámicamente a los objetos, facilitando un reequilibrio automático y una tolerancia a fallos
limitada.
14
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3.
2.3. ESTÁNDAR DICOM
Estándar DICOM
[NEMA] [DICOM] [HORI] [KURA] [REVET97]
En esta sección se va a hacer un estudio del estándar de comunicación e imágenes
digitales en medicina DICOM 2 .
2.3.1.
Introducción
El uso de la informática en aplicaciones clı́nicas es una constante hoy en dı́a,
especialmente en el campo del diagnóstico por imagen. El uso de la imagen digital
se ha ido imponiendo debido a los avances tecnológicos, ya que suponen una mejor
calidad de la misma y la posibilidad de transmitirla a distintos puntos de manera
inmediata. El problema fundamental para su empleo es la correcta interpretación
de la información. Es por ello que la ACR3 (American College of Radiology) y la
NEMA4 (National Electrical Manufacturers Association) iniciaron un proyecto para
la elaboración de un estándar para la transferencia de imágenes y la información
asociada a ellas que, tras varios intentos dio origen al formato DICOM 3.0, que es el
estándar habitualmente utilizado por las firmas digitales.
El estándar se ha desarrollado para encontrar las necesidades que fabricantes y
usuarios tienen con el equipamiento de imagen médica para la interconexión de dispositivos sobre redes estándares. Sus partes múltiples proveen medios para la expansión
y actualización, y el diseño del estándar se apuntó para permitir el desarrollo simplificado para todo tipo de imagen médica. DICOM también provee medios por los
que los usuarios de equipamiento de imagen pueden intercambiar información de dispositivos diferentes. Las futuras adiciones a DICOM incluyen apoyo para la creación
de archivos sobre medios extraibles (tales como discos ópticos y cinta magnética),
las nuevas estructuras de radiografı́a como angiografı́a, y extiende el control de la
documentación impresa.
En 1992 en la reunión anual de la Sociedad de Radiologı́a de América del Norte
(RSNA), en la parte 1 (Introducción y Descripción) y en la 8 (Soporte de Comunicaciones de Red e intercambio de Mensaje) del DICOM de ACR-NEMA (Imagen
médica y Comunicaciones en la Medicina) el Estándar se habı́a votado y aprobado.
Las partes restantes 2 a 7 y 9 se hicieron disponibles para comentarios. En infoRAD,
se realizó una demostración de la Versión de DICOM 3.0, la parte 8 usando mensajes
de la versión previa 2.0 de ACR-NEMA. Mientras estas no eran implementaciones
2
Digital Imaging and Communication in Medicine
Asociación de Colegios de Radiologı́a
4
Asociación Nacional de Fabricantes Eléctricos
3
r
GVA-ELAI-UPMPFC0075-2003
15
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
que incluı́an todas las estructuras de datos de DICOM, mostraron que el apoyo de
red era operacional y podrı́a cumplirse exitosamente.
Durante el encuentro anual de 1992 se formaron Grupos de trabajo de ACR-NEMA
(WGs) responsables de las partes restantes y completar el estándar de DICOM en
encuentros mensuales. Se terminó en septiembre de 1993, donde las versiones finales
de muchas de las partes habı́an experimentado la prueba de implementación real a lo
largo de 1993 para asegurar que la calidad de estándar serı́a demostrada por productos
reales en el encuentro de 1.993.
La creciente utilización de sistemas de adquisición y tratamiento digital de Imágenes
Médicas ha hecho necesaria la adopción de estándares que posibiliten el intercambio
de éstas tanto dentro de las propias instituciones como fuera de ellas.
El estándar DICOM 3.0 nace en el año 1993, a partir de un rediseño completo de
la Publicación Normalizada No 300-19885 de ACR-NEMA y pertenece al campo de la
Informática Médica por lo que, en principio, esta norma se solapa con otras de este
campo.
En primer lugar, dejar claro que DICOM 3.0 es aplicable a toda la esfera de las
Imágenes Médicas, desde la transmisión hasta el tratamiento e impresión, independientemente de la “especialidad médica” que la exporte.
En segundo lugar, y quizás lo más importante a dı́a de hoy, indicar que aunque la
Norma tiene el potencial de facilitar la realización de trabajos con PACS, la utilización
de la Norma DICOM 3.0 no garantiza, por si misma que se cumplan todos los objetivos
que se intentan lograr en un sistemas de gestión de imágenes. Se facilita, pero no se
garantiza, la interoperatividad en un entorno multi-vendedor.
En tercer lugar, quedan por delimitar elementos importantes de información asociada a la propia imagen, por lo que se prevee numerosas extensiones que den soporte
a futuras aplicaciones.
El avance de la estandarización poco a poco va siendo una realidad:
Se homogeneı́zan los estándares de codificación de la información y del conjunto
de datos resultantes de utilizar los Objetos de Información (imágenes) con las
Clases de Servicio (impresión, almacenamiento, etc), ası́ como se especifican
varias técnicas de compresión normalizadas (JPEG con y sin perdidas).
Se muestran las reglas de codificación que se deben cumplir para construir un
secuencia de datos para ser transmitida como un mensaje.
5
16
Digital Imaging and Communications Standard: versión 2.0
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Se especifica los servicios de comunicaciones y los protocolos necesarios para,
en un entorno de red, intercambiar mensajes.
Se define la utilización de un conjunto de protocolos OSI (Interconexión de Sistemas Abiertos) para asegurar una comunicación eficiente y que soporte una
amplia variedad de tecnologı́as de red basadas en normas internacionales como la ISO 8802-3 CSMA/CD (la famosa red Ethernet), ATM (muy en boga
actualmente), X.25, etc. Y como protocolo de transporte se puede utilizar el
famoso TCP/IP que hay que recordar que es un protocolo de propósito general, por lo que el sistema, en este apartado, es realmente abierto y compatible
con la mayorı́a de las redes que se están instalando actualmente en los centros
sanitarios.
2.3.2.
Historia de DICOM
En un esfuerzo para desarrollar unos medios estándar para que usuarios de equipamiento de imagen médica (tal como TAC, resonancia magnética, medicina nuclear, y ultrasonidos) puedan intercambiar imágenes u otros dispositivos entre estas máquinas, el
Colegio Estadounidense de Radiologı́a (ACR) y la Asociación Nacional de Fabricantes
Eléctricos (NEMA) formó un comité conjunto a principios de 1983. La misión de este
grupo, el Comité para estandarizar las comunicaciones y la Imagen digital de ACRNEMA, estuvo en hallar o desarrollar una interfase entre el equipamiento y cualquier
otro dispositivo que el usuario quiera conectar. Además de las especificaciones para
la conexión de hardware, el estándar se desarrolları́a para incluir un diccionario de
los elementos de datos necesitados para interpretación y la exhibición de imágenes.
La comisión inspeccionó muchos patrones de interfase existentes, pero no se encontró ninguno que fuera enteramente satisfactorio. En algunos, sin embargo, se encontraron ideas útiles. La Asociación Estadounidense de Fı́sicos en la Medicina (AAPM)
habı́a, un año antes, desarrollado un formato estándar para grabar imágenes sobre
la cinta magnética. La porción de cabecera contendrı́a una descripción de la imagen
junto con los elementos de datos (tal como nombre paciente) para identificarlo. El
concepto de usar elementos de longitud variable identificados con una etiqueta o la
llave (el nombre del elemento) se creyó que era particularmente importante y fue
adoptado por la comisión.
Después de 2 años de trabajo, la versión primera del estándar, ACR-NEMA 3001985 (también llamado ACR-NEMA Versión 1.0) se distribuyó en 1985 en la reunión
anual del RSNA y publicada por NEMA. Como con muchas versiones primeras, se
encontraron errores y sugirieron mejoras. La comisión habı́a creado un grupo de trabajo (WG) VI para mejorar el estándar una vez se publicó. Este WG contestó muchas
preguntas de desarrolladores potenciales y comenzó trabajando sobre cambios para
mejorar el estándar. En 1988, ACRNEMA 300-1988 (o Versión 2.0 de ACR-NEMA)
r
GVA-ELAI-UPMPFC0075-2003
17
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
se publicó. Usó sustancialmente la misma especificación de hardware que la Versión
1.0, pero se agregó nuevos elementos de datos y se fijaron un número de errores e
inconsistencias.
El problema era que por 1988 muchos usuarios quisieron una interfase entre dispositivos y una red. Mientras esto podrı́a realizarse con la Versión 2.0, el estándar
careció de partes necesarias para la comunicación robusta de red. Por ejemplo, uno
podrı́a enviar a un dispositivo un mensaje que contenga información de cabecera y
una imagen, pero el dispositivo no sabrı́a necesariamente qué hacer con los datos. La
Versión 2.0 de ACR-NEMA no era diseñada para conectar equipamiento directamente
a una red, resolver estos problemas significaban cambios importantes al estándar. La
comisión habı́a adoptado la idea que las futuras versiones del Estándar de ACRNEMA tendrı́an compatibilidad con las versiones anteriores, y esto puso algunas
restricciones al WG VI.
En una decisión importante para el estándar, se decidió que el desarrollo de una
interfase para el apoyo de red requerirı́a demasiados parches sumados a la Versión
2.0. El proceso entero tuvo que ser rediseñado, y el método adoptado fue el de objeto
orientado a diseño.
Además, un examen completo de los tipos de servicios necesitados para comunicar
con redes diferentes mostró que definiendo un servicio básico permitirı́a que la capa
superior procesara las comunicaciones (la capa de aplicación) para hablar con un
número de protocolos diferentes de red. Estos protocolos se modelan como una serie
de capas, frecuentemente referida a como“stacks”. En la Versión existente 2.0 el“stac”
definido en una conexión punto a punto era uno. Dos de los otros se eligieron con
base en la popularidad y futura expansión: El Protocolo de Control de Transmisión /
Internet de Protocolo (TCP / IP)6 y la Organización Internacional de Estándares de
Interconexión de Sistemas7 (ISO-OSI). La figura 2.3 muestra un diagrama del modelo
de comunicación desarrollado. La filosofı́a básica de diseño era que una aplicación de
imagen médica determinada (fuera del alcance del estándar) podrı́a comunicar sobre
cualquier de los stacks de otro dispositivo que use la misma stack. Con la adherencia
al estándar, serı́a posible cambiar las comunicaciones de stacks sin tener que para
revisar los programas de computadora de la aplicación.
Después de tres de años de trabajo, WG VI, con valiosas sugerencias de la industria
y la academia, ha completado DICOM de ACR-NEMA (también llamado DICOM
3.0). Es un estándar de tamaño mayor que las versiones 1.0 o 2.0, pero también
soporta muchas caracterı́sticas de las versiones anteriores.
6
7
18
Transfer Control Protocol / Internet Protocol
International Standard Organization - Open Systems Interconnection
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Figura 2.3: Modelo de protocolo de comunicaciones DICOM
2.3.3.
Procesamiento Distribuido
Un simple modelo de un proceso distribuido servirá para explicar el mecanismo y
terminologı́a usada en el estándar DICOM. Figura 2.4.
Con un simple modelo de un proceso distribuido se puede explicar el mecanismo
y terminologı́a usada en el estándar DICOM.
Figura 2.4: Procesamiento distribuido
Un proceso distribuido está formado al menos por dos procesos que comparten
información y confiando en la operatividad de uno en el otro. Un número de procesos
distribuidos actuando juntos proporcionan servicios para sistemas en entornos como
departamentos de radiologı́a. Figura 2.5.
Antes de que los procesos puedan actuar juntos una serie de temas tienen que ser
r
GVA-ELAI-UPMPFC0075-2003
19
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Figura 2.5: Transmisión
tratados. Tienen que estar de acuerdo en el papel (rol) que cada uno desempeñará,
tener una visión equivalente de la información y seleccionar las operaciones que cada
parte realizará.
Primeramente, el papel de cada parte debe ser definido como cliente o como servidor. La parte que utiliza la operatividad de la otra, tiene el papel de cliente. La
parte contraria actuando sobre un modelo concertado tiene el papel de servidor. El
funcionamiento de ambas partes viene definida por la relación que comparten. La
relación define que parte y bajo que condición toma la iniciativa en el proceso. En
muchos casos los clientes provocan el proceso, pero a veces lo hace el servidor.
Además de los papeles que desempeñan, ambas partes tienen que estar de acuerdo en la información que intercambian. La información está definida por el contexto
del servicio que el proceso distribuido está realizando. Cada proceso individual tendrá una visión selectiva de esta información, pero la visión tiene que ser coherente en
la totalidad del contexto.
La operación define como debe ser procesada la información intercambiada en la
otra parte, tal como almacenar información, devolver un resultado, etc.
La combinación del contexto, relación, operaciones e información es la piedra fundamental del procesamiento distribuido y tiene que ser definida antes de que una
aplicación pueda ser realizada. Todos estas cuestiones son parte del dominio de la
aplicación(application domain) de los procesos distribuidos. Estos no se ocupan de
la forma en que la información es intercambiada actualmente, pero cuentan con los
servicios de menor nivel (p.e. TCP/IP) suministrados por el dominio del intercambio(exchange domain) para poder hacer frente al intercambio.
Ambas partes, cliente y servidor, tienen que ser capaces de emitir peticiones a los
servicios de menor nivel. Los servicios de menor nivel llevarán el intercambio y están
ocultos para el dominio de la aplicación del cliente o servidor. La parte que solicita
20
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
los servicios es el usuario del servicio (service user). El equivalente es el proveedor del
servicio (service provider). Ambas partes pueden tener distintas implementaciones,
pero comparten el mismo conocimiento sobre como se intercambian los datos (protocolo) y tienen el mismo interface lógico (formato de petición) entre sı́. Ambas partes
deben determinar como viene representada la información en el formato de bit/byte.
El proveedor del servicio debe determinar en que formato la información fue transferida y convertida a la representación esperada por el dominio de la aplicación. La
representación es conocida entre el usuario y el proveedor del servicio en cada parte.
Después del intercambio, la información presentada a los procesos utilizando la información es igual en ambas partes, independientemente de como fuera intercambiada.
El intercambio fı́sico entre los proveedores del servicio puede ser vı́a network o
media. Cada mecanismo tiene su propia forma de manejar el conocimiento de la
representación.
La Figura 2.6 representa los conceptos que acaban de ser estudiados.
Figura 2.6: Modelo de un proceso distribuido
2.3.4.
Conceptos generales de DICOM
DICOM es un estándar que cubre las cuestiones plantedas en la sección anterior.
Esta sección abordará los conceptos generales con respecto al mecanismo de inter-
r
GVA-ELAI-UPMPFC0075-2003
21
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
cambio actualmente usado.
Los objetos (pacientes, imágenes, reportes,etc.) y sus interrelaciones son descritos
mediante modelos de entidad-relación. El primer modelo fue definido para la radiologı́a. Otras disciplinas médicas han pedido su incorporación al estándar.
DICOM utiliza su propia terminologı́a para describir el contexto, relaciones,asociaciones,
etc. El primer paso es el mismo modelo que para el procesamiento distribuido con la
transformación de la figura 2.6 en la figura 2.7 aplicando los términos equivalentes de
DICOM.
Figura 2.7: Clases de Servicio de DICOM
Se consideró que la mejor manera de desarrollar las estructuras de datos era el
diseño orientado a objetos. Los objetos definidos en los modelos son llamadosentidades.
los atributos describen las caracterı́sticas de un objeto. Cuando se dan valores a los
atributos de un objeto, defiendo un objeto reas, existente, se habla de una instancia del
objeto. Los objetos de agrupan en clases, según su tipo. Las clases se comunican entre
sı́, mediante mensajes. DICOM define las clases de objetos y sus mensajse permitidos
en lo que es llamado SOP(Service-Object Pair). Cuando un equipo especifica que
es compatible con una clase SOP, es posible saber de forma no ambigua como se
entenderán sus datos, ya sea por el proveedor de los servicios de la clase : SCP(Service
Class Provider) o por el usuario de los servicios de la clase: el SCU (Service Class
22
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
User). Para realizar una asociación, lo primero es que SCU y SCP estén deacuerdo
en utilizar una clase SOP.
Clases de Servicio (Service Classes) y Clases SOP (SOP Classes)
La relación entre ambas partes es definida por la descripción de la Clase de Servicio. La Clase de Servicio describe explı́citamente los papeles que ambas partes desempeñan. Dependiendo de la Clase de Servicio el contexto del servicio está definido.
Con DICOM ambos papeles son llamados: Usuario de la Clase de Servicio o SCU
(Service Class User) (cliente) y Proveedor de la Clase de Servicio o SCP (Service
Class Provider) (servidor). No hay que confundir SCU y SCP con el usuario del
servicio y el proveedor del servicio del dominio del intercambio.
Parte de la Clase de Servicio es la descripción de la información y operaciones.
En DICOM estas están combinadas con la definición de la clase, llamada Clase de
Servicio de Par Objeto (Service Object Pair Class) o Clase SOP (SOP Class). En
cada definición de Clase SOP una única Definición de Objeto de Información (Information Object Definition) o IOD es combinado con uno o más servicios. Para cada
uno de estos servicios los detalles de los papeles de ambas partes que tienen que
desempeñar son invariables. Más de una Clase SOP puede existir en una Clase de
Servicio cuando más de un IOD está implicado. Una Clase de Servicio entiende la
relación de información definida en diferentes IODs.
Una Clase SOP identifica las capacidades del proceso distribuido especı́fico de
una Clase de Servicio. Cuando las partes están de acuerdo en utilizar una Clase
SOP, ambas partes deben asegurar que desempeñaran sus papeles como se describen,
utilizando el contexto de la Clase de Servicio incluida. Antes de que la información
se intercambie puede tener lugar la identificación de la Clase SOP, que es una parte
importante que tiene que ser realizada al principio. El mecanismo usado depende del
tipo de intercambio: “network” o “media”.
Utilizando la Clase de Servicio y otras definiciones derivadas, las partes en el
entorno de un proceso distribuido funcionan juntas mediante los servicios proporcionados por el dominio del intercambio.
Definiciones de Objeto de Información (Information Objects Definitions)
La parte de información de una Clase SOP es definida en los IODs. Un IOD es
una colección de partes de información relacionada, agrupadas en Entidades de Información (Information Entities) o atributos. Cada entidad contiene información sobre
un único objeto (mundo real) como un paciente, una imagen, etc. Dependiendo del
r
GVA-ELAI-UPMPFC0075-2003
23
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
contexto definido por la Clase de Servicio, un IOD consiste en una entidad de información única llamada IOD normalizado (normalized IOD) o una combinación de
entidades de información llamada IOD compuesto (composite IOD). Las Clases de
Servicio que llevan a cabo funciones de administración (en su mayor parte cuestiones
simples) utilizan IODs normalizados, aquellas que manejan el flujo de imágenes (estructura compleja de información) utilizan IODs compuestos. Cada Clase SOP es
definido con uno o más IODs que son combinados con uno o más servicios.
Figura 2.8: Relación entre los IODs y los atributos
La relación entre diferentes entidades de información (estructuración) y los IODs
compuestos es descrita en el modelo de información (information model) perteneciente
a la Clase de Servicio. Con IODs normalizados (solo una entidad de información) no
hay ninguna necesidad de estructuración. Las relaciones en otras piezas de información
están hechas aludiendo a esa información.
Las entidades de información consisten en atributos, describiendo una única parte
de información, p.e., el nombre de un paciente. Los atributos que tienen una relación
están agrupados en módulos de información de objetos o IOMs (Information Object
Modules). Los IOMs están definidos de tal manera que pueden ser usados en más de
un IOD. Estos IOMs también tienen la ventaja de que las descripciones semánticas
de los atributos descritos pueden ser agrupados juntos. La figura 2.8 representa una
visión general de estas relaciones.
Un ejemplo de una IOD compuesto, imagen IOD está representada en la Figura
2.9.
24
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Figura 2.9: Ejemplo de un IOD de imagen compuesto
Atributos
Los atributos son la entidad de información básica y tienen que ser descritos
en detalle.Figura 2.10. Las siguientes caracterı́sticas o campos de un atributo están
definidas en el estándar DICOM:
un único Nombre de Atributo (Attribute Name) (legible por el ser humano).
una única Etiqueta de Atributo (Attribute Tag) (legible por los sistemas de
información).
una Descripción de Atributo (Attribute Description) (semántica).
un Valor de Representación (Value Representation) (sintaxis).
un Valor de Multiplicidad (Value Multiplicity).
tipo de clasificación: 1, 1C, 2, 2C o 3 (usadas dependiendo del contexto de las
Clases SOP, Clases de Servicio, papel que desempeña, etc.).
El tipo de clase especifica el uso de los atributos especificados en las Clases SOP
y el papel del SCU o del SCP. Dependiendo de la situación, cada atributo es forzado
r
GVA-ELAI-UPMPFC0075-2003
25
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
a tener un valor (tipo 1) o forzado con o sin valor (tipo 2) o opcional (tipo 3).
Figura 2.10: Ejemplo de los atributos del módulo Paciente
Dentro de un IOD, los atributos agrupados o individuales pueden ser condicionados por la situación en la que el IOD está siendo usado. Por ejemplo, un análisis utilizando contraste puede almacenar información en un “módulo de Contrast/Bolus”.
Los atributos de este módulo están por consiguiente disponibles o no disponibles,
dependiendo del uso del contraste. Si se usa, el tipo de clase especificada para los
atributos debe ser obedecida (definida como tipo 1C y tipo 2C).
Elementos de Servicio (Service Elements)
Los Elementos de Servicio son las operaciones permitidas en los Objetos de Información (IODs) para una Clase SOP definida. El grupo de elementos de servicio
pertenece a la Clase SOP y es llamada Grupo de Servicio (Service Group).
El Grupo de Servicio de una Clase SOP es seleccionado de una lista fija de Elementos de Servicio de DICOM. Algunos Elementos de Servicio están proyectados para
usarse con IODs compuestos, otros para uso con IODs normalizados. Una tercera
categorı́a, medios de almacenamiento (storage media) relacionados con Elementos
de Servicio, manejando instancias de Clases SOP normalizadas o compuestas como
archivos. Una Clase SOP utiliza uno o más elementos de servicio.
El contexto descrito por la Clase de Servicio está limitado cuando se utilizan
IODs compuestos (p.e., transferir imagen). Elementos de Servicio semejantes tienen
un significado complejo, p.e., STORE, FIND, MOVE. No hay ninguna relación asumida entre los Elementos de Servicio individuales en una secuencia cuando se utilizan
Clases de Servicio compuestos. Si existe una relación, es fuera del alcance de la Clase
de Servicio y deberı́a estar definida en el proceso fluyente utilizando las Clases de
Servicio.
26
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
En contraste, las Clases de Servicio utilizando IODs normalizados tienen un contexto más amplio, como funciones directivas. Estas utilizan los Elementos de Servicio
primitivos para operaciones con piezas sencillas de información: GET, SET, ACTION,
etc. La Clase de Servicio define la relación de la secuencia de la peticiones primitivas.
Con Clases de Servicio normalizadas ambas partes están al tanto del procedimiento
de ambas partes, utilizando los Elementos de Servicio para controlarlos.
Cada Clase SOP utiliza uno o más Elementos de Servicio de cada uno de los grupos compuestos (C-XXXX) o de los grupos normalizados (N-XXXX). Los siguientes
Elementos de Servicio están disponibles: C-STORE, C-FIND, C-MOVE, C-GET, CCANCEL, C-ECHO, N-GET, N-SET, N-ACTION, N-CREATE, N-DELETE y N-EVENTREPORT. Las semánticas de los Elementos de Servicio dependen de la Clase de Servicio y de la Clase SOP en la cual están utilizados.
Los Elementos de Servicio relacionados con Media, M-WRITE, M-READ, M-DELETE,
M-INQUIRE-FILE-SET y M-INQUIRE-FILE definen funciones primitivas para el tratamiento con archivos.
Gracias a las Clases de Servivio (mensajes DICOM) hay una comunicación entre
ambas partes. Antes de poder lograr el intercambio de información entre dos Clases
SOP, debe establecerse entre ellas una Asociación (Association en DICOM), donde se
negocia para establecer las posibilidades de trabajo de cada parte. Una vez establecida
la asociación, si esta fue satisfactoria puede establecerse el intercambio de mensajes a
través de los DIMSE- DICOM Service Element- (DIMSE-C en este caso, que soporta
operaciones con Instancias Compuestas SOP).
Los mensajes entre dos aplicaciones DICOM están codificados y son enviados en
forma de Data Set que está compuesto de Command Elements y deben tener una
estructura como la que se muestra en la figura 2.11.
La norma establece que la estructura del mensaje y set de comandos sea por
defecto: - Tags en orden Creciente, - Little Endian, -VR Implı́cito.
La transferencia de mensajes entre aplicaciones DICOM se establece mediante el
flujo de Data y Command Elements ordenados según el Tag y codificados.
Si en el Data Set vienen ya implicitos los datos que quieren ser pasados de un
equipo a otro, éste se compone de Data Elements y su estructura es según la figura
2.12. Este es el modo en que se codifican los mensajes para transferir los estudios y
la información de un equipo a otro.
Tanto el Command Set como el Data Set son “cola” de Command Elements8 o
8
Elementos de Comandos DICOM (Store, Find, etc.)
r
GVA-ELAI-UPMPFC0075-2003
27
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Figura 2.11: Estructura del mensaje DICOM
Data Elements9 respectivamente. En ambos casos, la estructura del elemento es la
misma, difiriendo simplemente en el número de grupo y en algunos casos en el VR.
Tag: es un par ordenado de números de 16 bits codificados en hexadecimal.
El primero de ellos hace referencia al Grupo, mientras el segundo se refiere al
Elemento, y son leı́dos como enteros sin signo. Identifica los atributos, el par
(grupo,elemento). Están definidos en el Data Dictionary.
Value Representation (VR): es una cadena de dos caracteres que según la cual
se especifica el tipo de dato que se leerá en el Value Field. En la Parte6 de la
norma se especifica el tipo de dato (cadena de caracteres de hasta 16 bytes,
cadena de caracteres de 4 bytes, etc.) correspondiente a cada sigla (AE, AS,
etc.).
Value Length: Length: entero sin signo de 16 o 32 bits (según sea VR, Explı́cito
o Implı́cito). Contiene un número par que indica la extensión del campo Value
Field, donde se hallan contenidos los datos propiamente dichos.
Value Field: aquı́ se encuentra un número par de elementos conteniendo el/los
valor/es. Es el dato propiamente dicho, cuya ı́ndole está determinada por los
campos anteriores.
9
28
Codificación de datos (Fecha de Estudio, Modalidad de Estudio, etc.)
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Figura 2.12: Estructura del Data Element
Instancias SOP (SOP Instances)
El esqueleto de las definiciones citadas anteriormente toma forma cuando se utilizan en un proceso distribuido. Después del acuerdo que mantienen las Clases SOP
(e implı́citamente la Clase de Servicio), y como los papeles de la SCU y la SCP están
divididos, las instancias de la clase SOP pueden ser distribuidas entre las dos partes.
Los Atributos tienen que ser proporcionados con los valores correctos y almacenado
en la Instancia SOP como se especifica en la definición de los atributos.
Después de recopilar la información, esta será codificada a los formatos definidos
por DICOM, utilizando la Representación del la Etiqueta (Tag) y del Valor (Value)
para crear un DICOM data set, en el cual cada atributo es codificado en un data element. Este “data set” es manejado por el proveedor del servicio de intercambio, el cual
garantiza que la parte contraria recibe idéntico data set. Las diferencias en la representación del sistema especificado son tomadas en una cuenta durante el intercambio,
asegurando que los significados semánticos permanecen intactos.
El receptor del data set decodificará este para extraer la información que necesita
y actuar como acuerdo de la semántica de la Clase SOP.
Identificación
Como parte del proceso de creación de una Instancia SOP, una identificación es
generada como atributo de la SOP Instance. La identificación es pretendida para la
r
GVA-ELAI-UPMPFC0075-2003
29
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
utilización por los sistemas de información antes que por los humanos y tiene dos
caracterı́sticas: la identificación de la clase (class identification) y la identificación de
la instancia (instance identification).
Esta identificación tiene que ser usada en un entorno de muchos vendedores en
distintas partes del mundo. Para asegurar la unicidad de cada identificación en todo
el mundo, un mecanismo es utilizado para generar una cadena de caracteres, llamada
Identificador Único o UID (Unique Identifier), tal y como sigue:
<root>.<suffix>
La parte de root es proporcionada por una autoridad que garantice que nadie
más utilizará este root. Este número será asignado por estándares de organizaciones
y compañı́as tales como Philips u hospitales, que deberán asegurar que permanece
único a lo largo de sus propios sistemas. Utilizando un sistema de identificación único,
cada sistema tendrá un único root a lo largo de todo el mundo. El suffix tiene que ser
creado dinámicamente por el sistema en la creación de la instancia.
Un vez que una instancia es identificada por un UID, esta debe ser utilizada
consistentemente. Si se crean copias o la instance es reproducida sin ninguna modificación, deberá tener el mismo UID, de lo contrario dos piezas de idéntica información
coexistirı́an con diferentes identificaciones, lo que podrı́a conducir a confusión.
Relaciones
Además de la identificación de la Clase SOP y la Instancia SOP, los UIDs también
se utilizan para identificar una relación entre instancias. En una instancia compuesta
(composite instance) que contiene una secuencia de imágenes, la Entidad de Información (Information Entity) que contiene la información de la secuencia será común
para todas aquellas instancias. En este caso solo un UID es requerido, el atributo por
sı́ mismo identifica que tipo de entidad de información es identificada.
En el caso de instancias normalizadas (normalized instances), solo son posibles
referencias a instancias fuera de sı́ mismas, aquı́ la combinación de una identificación
de una clase y una instancia es requerida. Este es también el caso de imágenes que
están referidas a cada una, cuando tienen una relación segura.
Con el método de la unicidad de identificación de información utilizando UIDs,
es tan solo posible comparar si las instancias son iguales. El valor del UID no tiene
ningún significado, y no puede ser utilizado para clasificar, etc. Utilizando otro método, atributos más significativos tales como la fecha y la hora y los números de la
secuencia, la relación entre la información puede ser establecida.
30
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Representación del Valor (Value Representation)
Para cada atributo un Representación del Valor (VR) es definido. Una Representación del Valor describe como un atributo es codificado en un Data Element
(elemento de dato). El conocimiento de la Representación del Valor es compartido
por las partes en el intercambio de información, el proceso de codificación y decodificación tiene que tener cuidado en la selección del VR correcto para un atributo
(identificado por su etiqueta —tag—).
Dos formas de compartir esta información son posibles: compartir un diccionario
de datos que contiene todos los posibles atributos de intercambio o incluyendo la representación del valor como una parte del data element. El último método incrementa
los gastos de intercambio de información, pero es mucho más flexible comparado con
el uso de un diccionario de datos compartido. Especialmente en un entorno de muchos
proveedores, sincronizar el diccionario de datos es difı́cil.
Cuando la Representación del Valor es incluido, el mensaje es codificado con un
VR explı́cito (explicit VR). En el otro caso, la codificación tiene lugar con un VR
implı́cito (implicit VR).
Transfer Syntax
Antes de que la Data Set de una Instancia SOP pueda ser transferida, la forma
en la que el Data Set es codificado en una secuencia de bytes debe ser fija, ambos por
acuerdo cuando el intercambio network es usado, o almacenados juntos con los datos
de uno. La forma de codificar es especificada por el Transfer Syntax.
Tres caracterı́sticas tiene que ser definidas por la transfer syntax:
Como una Representación del Valor es especificada.
La ordenación de bytes de un número múltiple de bytes (palabras, palabras
largas): little endian o big endian.
En caso de encapsulación (compresión): el formato de compresión.
El manejo del “transfer syntax” es parte del proveedor del servicio. Sin embargo,
ambos procesos tienen que ser iniciados según el “transfer syntax”, aceptable para
ambas partes.
Análogamente a una identificación de Clase SOP, un ´´transfer syntax” es identificado por un UID.
r
GVA-ELAI-UPMPFC0075-2003
31
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Una visión general
Mirando la figura 2.13 se puede obtener una visión general del flujo de codificación
y decodificación. Los servicios proporcionados dentro del Dominio del Intercambio
tienen que garantizar que las Instancias SOP en ambas partes contienen la misma
información, independientemente de la representación y método de transferencia.
El proceso de codificación y decodificación tiene dos etapas:
Primero se transfiere la representación interna en el formato definido por DICOM
(Data Set) donde cada atributo es almacenado conforme al valor de representación definido para ese atributo.
La segunda etapa transfiere el data set en una corriente de bytes que pueden
ser manejados por las capas más bajas. Para la segunda etapa la ordenación de
bytes tiene que ser utilizada como acuerdo con el Transfer Syntax.
La aplicación que está utilizando la información debe conocer el significado (semántica) de la información dentro del objeto dato.
Figura 2.13: Visión general de la codificación y decodificación de las instacias SOP
32
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3.5.
2.3. ESTÁNDAR DICOM
Conceptos de DICOM Network
En la anterior sección se han discutido los conceptos de DICOM del dominio
de la aplicación. Cuando se utiliza un mecanismo “network” para el intercambio de
información, el dominio del intercambio debe contener funciones requeridas para la
comunicación: el dominio de la comunicación; ver figura 2.14.
Figura 2.14: DICOM y el intercambio “network”
Entidad de la Aplicación (Application Entity)
Una cuestión importante en las aplicaciones distribuidas en red es como las aplicaciones pueden contactar entre ellas. En DICOM Network, las partes se reconocen
mutuamente mediante las Entidades de la Aplicación. Una Entidad de la Aplicación
es aquella parte de un proceso que negocia con la comunicación. Ella contiene el
Usuario de Servicio del proceso, conteniendo funciones para organizar conexiones y
transferencia de información. Una Entidad de la Aplicación tiene un nombre, Tı́tulo
de la Aplicación (Application Title), que tiene que se utilizado cuando se establece la
comunicación.
r
GVA-ELAI-UPMPFC0075-2003
33
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Dirección de la Presentación (Presentation Address)
Los Tı́tulos de la Aplicación son nombres simbólicos para los procesos involucrados
en la comunicación. En un sistema de red real, la dirección de red tiene que ser
suministrada. A esto se le llama la Dirección de la Presentación. Se le llama ası́ porque
el usuario del servicio es la capa de Aplicación (OSI), el proveedor del servicio, la capa
de Presentación (OSI) (y niveles más bajos). La frontera entre ambos niveles es el
punto de acceso network donde los datos son transferidos desde la capa de aplicación
a las capas de network. Cada punto de acceso en una red tiene una única dirección.
El mapeo del Tı́tulo de la Aplicación a la Dirección de la Presentación no tiene
que ser único, porque la Dirección de la Presentación es utilizada para la iniciación
de la conexión, etc. De cualquier manera en el nivel de aplicación, el Tı́tulo de la
Aplicación es usado normalmente para identificar una aplicación como fuente o destino de información en un directorio o catálogo. Si esto no puede ser registrado sin
ambigüedades la operación de los sistemas puede llegar a ser un problema.
El formato de la Dirección de la Presentación depende del protocolo de red utilizado. Los DICOM Networks son realizados en muchos casos utilizando el protocolo
TCP/IP. En este caso la Dirección de la Presentación es mapeada a un TCP/IP socket. En caso de un protocolo OSI, debe utilizarse un OSI Presentation Service Address
Point (PSAP) válido.
Association Negotiation
La conexión para el intercambio de información entre dos Entidades de la Aplicación es llamada Asociación (Association). Para una Asociación unas cuestiones
de comunicación son fijados como el contexto en el cual la información puede tener
cambios. Este contexto, llamado Contexto de la Aplicación (Application Context),
es definido en el estándar DICOM y ambas partes deben estar de acuerdo con la
actuación conforme a la definición del contexto.
Un Contexto de la Aplicación es definido con un UID y durante la iniciación de
una asociación este UID es transferido a las partes. Por comparación del UID de un
Contexto de la Aplicación, la parte puede decidir si es capaz de manejar la petición
de una asociación. Él aceptará el establecimiento de la asociación o lo rechazará.
El Contexto de la Aplicación cubre la operatividad global para el intercambio
de información. Que tipo de información intercambia tendrá lugar a través de la
asociación que está definida por las Clases SOP y las Clases de Servicio de estas Clases
SOP. La parte iniciadora de la asociación propone a la Clase SOP que será utilizada,
el SCU / SCP para cada Clase SOP y la forma de representación de la información.
34
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Dependiendo de las capacidades de la otra parte, aceptará o rechazará cada Clase
SOP individual.
Después de este proceso de negociación ambas partes conocen mutuamente las
capacidades y limitaciones. La auténtica información distribuida puede tener lugar
conforme a las reglas de una Clase de Servicio y una Clase SOP definidas para estas
clases. Cuando una Asociación no es muy larga se requiere la Asociación que ha
terminado.
Presentation Context
Para cada Clase SOP negociada durante la iniciación de la Asociación tiene que
alcanzarse un acuerdo entre los procesos involucrados acerca del transfer syntax usado
entre los procesos. La parte iniciadora propone todos los transfer syntaxes, fijando
el Contexto de la Presentación para esta Clase SOP. Después de la negociación una
Presentation Context para cada Clase SOP aceptada es establecida.
Una Presentation Context es identificada por un número acordado entre las dos
partes. En el contexto de una aplicación puede existir un número de una Presentation
Context. El número de la Presentation Context identifica la SOP Class para la cual
el intercambio de información tiene lugar.
El Contexto de Presentación está compuesto por dos UIDs, uno es el Transfer
Syntax, necesario para la posterior transmisión del Data Set, y el otro el Abstract
Syntax, necesario para la correcta comunicación entre las dos partes de la asociación,
ya que éste determina qué operación va a ser realizada. Figura 2.15.
Figura 2.15: Ejemplos de Contextos de Presentación
Protocolos de Red
El actual Protocolo de Red tiene que cumplir con los servicios del estándar definidos
para el protocolo OSI. Ver figura 2.16.
r
GVA-ELAI-UPMPFC0075-2003
35
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Figura 2.16: Capas OSI
Para la capa de aplicación dos grupos de servicios tienen que estar disponibles
para una implementación DICOM: el protocolo de Control de Asociación (ACSE) y
el protocolo de Mensajes DICOM (DIMSE). ACSE es un estándar del protocolo OSI
y DIMSE pone en práctica los servicios DICOM.
El interfaz entre ACSE, DIMSE y la aplicación, es la Interfaz DICOM como la
descrita en el estándar DICOM. Esta especificación describe que parámetros son
requeridos para cada función del ACSE y peticiones DIMSE. El ACSE, DIMSE y
el interfaz DICOM son partes del Contexto de Aplicación.
El interfaz hacia la aplicación(API) no es especificado en el estándar, pero depende
de la implementación. En general este API proporciona funciones para conectarse con
otras aplicaciones, construir o tratar Instancias SOP y transferir estos a una aplicación
remota.
TCP/IP Protocol Stack
La combinación de TCP/IP y una extensión para los servicios de aplicación de OSI
es ampliamente usada para implementar DICOM a través de las redes. Como no hay
36
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
niveles más altos definidos por TCP/IP, la operatividad de la aplicación, presentación
y sesión de la capa es requerida por DICOM, como se describe en el estándar DICOM.
Esta operatividad es combinada en una capa: la DICOM Upper Layer o DUL.
La DUL utiliza el mismo interface que el protocolo TCP/IP con respecto del
protocolo OSI. En el nivel más bajo del DUL hay un interface para el nivel TCP.
La Asociación DICOM entre las Entidades de Aplicación es mapeada a una conexión
TCP. La Dirección de la Presentación es mapeada a un número de puerto TCP,
combinado con el número de IP o nombre del servidor (Host name). Esta combinación
del número de puerto TCP y el número de IP es llamada Dirección de Conexión
(Socket Address). En una red esta combinación es siempre única.
Una conexión TCP es definida por la combinación de una Dirección de Conexión
local y una remota. Manteniendo los números de IP únicos de la red y el número único
de puerto en el sistema, cada conexión TCP es única identificada por la combinación.
La administración de las conexiones se hace por una recurso llamado Interface de
Conexión (Socket Interface) que proporciona funciones para configurar las conexiones,
transferir cadenas de bits, etc.
El puerto TCP de la parte a la que se llama durante la inicialización de la conexión,
debe ser conocido. Esto puede ser por un acuerdo en el número de puerto entre las
dos aplicaciones, o por un número de puerto, llamado número de puerto notorio (well
known port number), reservado para las implementaciones de DICOM (número de
puerto 104).
2.3.6.
Clases de Servicio soportados
DICOM tiene definidas un número de Clases de Servicio. Pueden ser agrupadas
en un gran número de categorı́as. Esta lista de Clases de Servicio crecerá tal como
nuevas operatividades sean estandarizadas en el estándar DICOM.
Image Storage Service Classes
Esta primera categorı́a contiene las Clases de Servicio negociadas con los datos
de imagen. Los datos de imagen son siempre encapsulados en un IOD compuesto y
utilizando los servicios compuestos. Las Clases de Servicio de este grupo son:
Storage Service Class, que consiste en Clases SOP para cada modalidad de
tipo de imagen: Computed Radiography (CR), Computed Tomography (CT),
Magnetic Resonance (MR), etc. Esta Clase de Servicio especifica el intercambio
r
GVA-ELAI-UPMPFC0075-2003
37
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Figura 2.17: Conexión TCP
de los datos a través de la red. No especifica que tiene que hacerse con la imagen,
que tiene que ser gestionada por otras Clases de Servicio.
Query/Retrieve Service Class. Incluye las clases SOP FIND, MOVE y GET
para un número de modelos de peticiones. La FIND puede ser utilizada para
solicitar una colección de imágenes. La MOVE y GET pueden ser usadas para
iniciar la transferencia. La actual transferencia se realiza utilizando la Storage
Service Class.
Study Contents Notification, es utilizada para notificar una administración fácil
de una imagen sobre las imágenes creadas durante un estudio y podrı́an ser
utilizadas para iniciar la transferencia de los datos de imagen o para chequear
si todas las imágenes han sido completamente transferidas.
Management Service Classes
La administración orientada a las Clases de Servicio se realiza utilizando una
mezcla de IODs normalizados con Servicios normalizados y una Clase de Servicio
Query que maneja información en sentido opuesto. Esta segunda categorı́a consiste
en:
38
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Detached Patient Management maneja la información solicitada por la agenda
de visitas para una o más modalidades. La información demográfica del paciente
y los estudios de información son enviados desde los sistemas administrativos
(RIS) hasta la modalidad.
Detached Study Management recibe información de las series de imágenes creadas
de las modalidades y manda todos los datos adquiridos a un completo estudio
de imágenenes interdependientes y todos los otros tipos de información.
Detached Result Management es utilizada para estar al tanto de los informes e
impresiones del estudio.
Basic Worklist Management, es la única Service Class no normalizada. Complementa a la Detached Patient, Study y Result Management Service Class con una
fácil petición] para ser utilizada para obtener información sobre una única lista
de entidades de información. Esto permite una forma más flexible de adquirir
información comparada con las otras Clases de Servicio.
Print Management se utiliza para administrar el proceso de formateo e impresión de una colección de imágenes en una cinta.
Media Storage Service Class
En Media Storage Services class son definidos un set de servicios que permiten el
intercambio de datos usando Media Storage. Media es usado por dos razones:
Las imágenes son almacenadas en Media para el intercambio entre dos procesos sin la especificación sobre el tratamiento, solamente la transferencia de la
información.
Las imágenes son almacenadas para mostrarlas como Sesiones de Pelı́cula. El
proceso de recepción debe manejar la información de la Gestión de la Impresión
en Media, y mantener sobre ésta la información del estado del progreso del
trabajo de impresión.
El papel en el cual el proceso está activado en esta Clase de Servicio no está relacionado con el papel del compañero con la situación de red, pero con las operaciones
sobre los medios de comunicación. Tres papeles son definidos: el File-set Creator o
FSC, el File-set Reader o FSR y el File-set Updater o FSU, el nombre se refiere a la
operación permitida.
Los Elementos de Servicio usados en las Clases SOP de esta Clase de Servicio
especifica las operaciones en las instancias de las Clases SOP como un archivo o como
r
GVA-ELAI-UPMPFC0075-2003
39
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
una dirección completa de un archivo. Los IODs usados con estos servicios definen la
información para ser guardados en un archivo.
Esta Clase de Servicio detalla sólo la información de almacenaje en un archivo,
independientemente del contenido. La excepción es una Clase de Servicio especial
(Media Storage Directory Storage) la cual maneja información sobre el archivo y un
directorio (DICOMDIR).
Otras Clases SOP de Media Storage Service Class son identicas a las Clases SOP
usadas con el Network Storage Service Class para datos de imagen, Detached Patient
Management, Detached Study Management, Detached Result Management y Print
Management Service Classes. Las Clases SOP almacenadas en archivos pueden ser
usadas directamente por la Clase de Servicio de las Clases SOP correspondientes,
usando los servicios de Media Storage Service Class. Ver figura 2.18.
Figura 2.18: Definición de objeto compartido con Media Service Class
Los procesos de ambos lados deben estar de acuerdo en que información es intercambiada por los medios de comunicación especificando una lista de Clases SOP
y otras cuestiones. Como no existe ningún mecanismo de negociación de asociación,
debe haber un arreglo que se conforma a un Perfil De aplicación.
Verification Service Class
Finalmente, hay una Clase de Servicio que no se ajusta a ninguna de las categorı́as anteriores: la Verification Service Class. Esta Clase de Servicio es utilizada
para chequear si una asociación puede establecerse entre dos procesos e intercambiar
una instrucción sin ningún dato (C-ECHO), donde ningún IOD está involucrado. Esta
proyectado para propósitos de chequeo en nivel de conectividad.
40
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3.7.
2.3. ESTÁNDAR DICOM
Conectividad
Antes de que las dos implementaciones de DICOM puedan ser conectadas entre
sı́, algo de investigación es necesaria si la conexión es posible. Esto alcanza desde el
bajo nivel de conexión fı́sica hasta la implementación de la misma Clase de Servicio
en el nivel de aplicación.
El acercamiento a una conexión “network” es diferente comparado con un intercambio a través de “media”. Durante la negociación de la Asociación en un entorno
network un número de detalles pueden todavı́a ser establecidos. En el caso de utilizar
media no es posible y deberı́a ser dirigido de distinto modo.
DICOM solventa esta cuestión utilizando perfiles de sistema (system profiles) para
implementaciones y Perfiles de aplicación (application Profiles) en un entorno de
intercambio “media”.
Conformance Statement
Un Perfil de Sistema (System Profile) contiene una lista de las funciones soportadas y limitaciones o extensiones de estas funciones. Juntos forman un perfil que se
debe ajustar al perfil de la parte que tendrá que cooperar. Estos perfiles de sistema
son descritos en un documento que debe ser suplido con cada implementación de
DICOM: la Conformance Statement. Figura 2.19
Figura 2.19: Conformance Statement con Perfil de Sistema
En el nivel de aplicación una descripción funcional de la Application Entity, las
Clases SOP soportadas y el papel que ambos sistemas desempeñan son descritas.
r
GVA-ELAI-UPMPFC0075-2003
41
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Para la implementación de los protocolos de red puede ser referido a documentación
estándar apropiada, con constancia de las excepciones que restringen el uso en un entorno de red. Las posibilidades de una conexión fı́sica es también un tema que debe
ser dirigido.
Los objetos configurables de una implementación, tales como el Tı́tulo de la Aplicación (Application Title), la Dirección de la Presentación (Presentation Address) de
ambas implementaciones y partes, que son mencionadas juntas con información de
como puede ser configurado. Otros objetos configurables como el tamaño del protocol
data unit (PDU) debe ser listado.
Finalmente el soporte para otros caracteres fijados, además del estándar ASCII
(tales como extensiones para idiomas Europeos, Japonés, etc) descrito.
Comparando los Conformance Statements, puede ser verificada si la conectividad
a todos los niveles es posible. Si la implementación de la información por todas las
partes involucradas es igual, no se puede asegurar por verificación con la Conformance
Statement. Dependiendo de cómo de estricta pueda ser interpretada la semántica
de todos los atributos individuales, el nivel de interoperabilidad es más predecible.
Actualmente no hay ningún método para asegurar la interoperabilidad.
La Conformance Statements pueden añadir más información describiendo en más
detalle la información que manejan. Cuando está indicado que relaciones están disponibles
y que selecciones están hechas por la implementación comparada con el estándar, este
ayudará a incrementar la conectividad y la interoperatividad.
Perfiles de Aplicación (Application Profiles)
Para “media” un perfil de sistema detallado tiene poco sentido porque la correspondencia no tendrá lugar antes de que se conecten los sistemas, pero por el momento
el medio es llevado a otro sistema. En este caso ambos sistemas deben garantizar que
se ajustan a un formato genérico que habilita la aplicación que ambos implementan.
Este formato genérico es llamado Perfil de la Aplicación. Por ejemplo, un sistema
que genera datos de imagen en un medio debe hacerlo conforme a un Perfil de Aplicación confirmado. Un sistema utilizando esta imagen puede confiar en este Perfil de
Aplicación para resultar un éxito.
Dos aspectos son importantes: el formato del medio y la extensión de la información capturada en el medio. Un Perfil de Aplicación asegura estos dos aspectos y
proporciona un tipo de etiqueta que puede ser adjuntada al sistema involucrado y al
medio que contiene los datos. Figura 2.20
El aspecto fı́sico del medio alude al formato definido en el estándar DICOM.
42
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Figura 2.20: Conformance Statement con Perfil de Aplicación
La parte de información descrita por la Clase SOP es el segundo aspecto incluido
en el Perfil de la Aplicación.
2.3.8.
Estándar DICOM
El estándar DICOM está dividido en varias partes, cada una de ellas describiendo
una cuestión importante tal como las Clases de Servicio, los IODs, temas relacionados
con Network y Media, etc. En la figura 2.21 se ve una visión general de la relación
entre las diferentes partes.
Las partes de DICOM son 13: las 9 primeras son originales y las partes de la 10
a la 13 fueron propuestas mediante suplementos. La figura 2.21 muestra la relación
entre las partes del estándar. La figura no debe tomarse como jerarquı́a; la porción
de la izquierda representa las partes que definen la red y la comunicación punto por
punto. La porción derecha de la figura muestra las partes que soportan medios de
almacenamiento removibles. Las partes 1,2,3,5 y 6 son usadas en ambos ambientes.
En este apartado las partes de DICOM son abordadas en el mismo orden que los
temas planteados en los apartados anteriores. Puede ser usada como linea directiva
para empezar a leer las varias partes del estándar DICOM.
r
GVA-ELAI-UPMPFC0075-2003
43
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
La parte 1 da una introducción y una visión general del estándar DICOM y su
relación con otros sistemas de información hallados en el entorno clı́nico.
La parte 2 define la comformidad (compatibilidad) con DICOM. El certificado de
conformidad (Conformance Statement) debe ser hecho público por cada fabricante (la
mayorı́a están en Internet). Éste especificará exactamente cuales clases de servicios
SOP son soportadas por sus dispositivos. Esto guiará a los usuarios a seleccionar productos que trabajen juntos. Al comprar un equipo el usuario debiera saber cuáles son
las clases de servicios que necesita para su servicio médico. Esta labor es complicada
por lo que se recomienda a las instituciones de salud asesorarse por especialistas en
el estándar. Cada usuario debiera tener idealmente un perfil de conformidad (User
Conformance Profile) que especifique las clases que requiere.
Las Clases de Servicio y las Clases SOP incluidas en las Clases de Servicio están
definidas en la parte 4, basadas en los modelos de la parte 3. Los roles de las SCP y
SCU son definidos aquı́ y se especifica el comportamiento esperado para cada rol en
cada servicio. Esto permite a los implementafores y usuarios entender qué se espera
de un dispositivo que soporta una clase en particular. Para cada Clase de Servicio la
operatividad está delineada siguiendo la descripción de las Clases SOP individuales.
Para cada papel un proceso puede desempeñar los requisitos dados por los dos con
detalles del uso de los atributos si es aplicable. Dependiendo del tipo de Clase de
Servicio (compuesta o normalizada) la descripción es dando un pequeño contexto o
uno detallado. Ası́ mismo los temas que tienen que ser descritos por cada parte de la
Clase SOP en la Conformance Statement son listados. La parte 4 utiliza los IODs y
los Servicios definidos en las Partes 3, 7 y 10.
Los IODs utilizados por las Clases SOP son descritos en la Parte 3. Empieza con
la descripción del IOD completo, dividiéndolo en los grupos de IODs compuestos y
normalizados. De cada IOD se da una lista de “Information Object Modules”. La
última parte define los atributos individuales agrupados en detalle en los IOMs. Para
los IODs compuestos todos los detalles son listados en esta parte, para los IODs
normalizados el actual uso de los atributos depende del servicio aplicado y descrito
en la parte 4.
En la Parte 5 se describe la codificación de las Instancias SOP en un conjunto de
datos. Las reglas para las numerosas Representaciones de Valores (Value Representation) y “Transfer Syntaxes” son definidas.
Los Elementos de Servicio utilizados por las Clases SOP son divididos en dos
partes, Parte 7 para los Servicios Network y la construcción de secuencias de comandos
y Parte 10 para los Servicios Media. En estas partes la codificación del “network
message header” y “media file header” son definidos. El resultado es un mensaje o
archivo que puede ser manejado por el correspondiente mecanismo de intercambio.
44
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Figura 2.21: Relaciones entre las Partes del estándar DICOM.
Los dos grupos de menor nivel tratan con el intercambio fı́sico de datos. En la
Parte 8 las cuestiones de Protocolo de Red (Network Protocol) son descritas, la Parte
9 define la conexión punto-a-punto (point-to-point conexion) (raramente utilizada) y
la Parte 12 define las cuestiones del formato de Physical Media.
Todos los atributos y UIDs definidos por las varias partes del estándar DICOM son
listadas en el Diccionario de Datos (Data Dictionary) (Parte 6). Es el listado completo
de todos los elementos de datos junto con sus nombres numéricos (o etiqueta), sus
nombres de texto, cual es su representación (texto, número de coma flotante, etc.), si
ellos contienen uno o más ı́tems (la multiplicidad de valor), y qué los valores permitidos
están para esos elementos que pueden contener solo ciertos valores.
Las cuestiones de Conformance son descritas en la Parte 2 incluyendo la manera
en que un Conformance Statement tiene que ser configurado. Los Perfiles de la Aplicación utilizados para la Media exchange son discutidos en la Parte 12 junto con la
“Application Profile layout”.
La parte 8 define el soporte de red para cambiar Mensajes de DICOM. Actualmente, TCP/IP y protocolos ISO-OSI son soportados, pero la naturaleza del servicio
superior de capa definido en esta parte es tal que se debe posible expandir a otros
protocolos con facilidad relativa. Una vez fuera de la capa superior de DICOM, el
remanente del protocolo de comunicaciones (o TCP / IP u OSI) sigue los patrones
existentes.
r
GVA-ELAI-UPMPFC0075-2003
45
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
2.3.9.
Fernando Ballesteros Herranz
Instancias SOP de imágenes DICOM
En el capı́tulo precedente, se han explicado los conceptos DICOM sin describir en
detalle cómo se capturan las imágenes dentro de una instancia SOP. En este capı́tulo
se ve con más profundidad cómo se estructura la información. Se explicará la diferencia
entre los distintos tipos de imágenes, junto a la forma en que el proceso de creación
crea los datos de la imagen. Finalmente, se verá qué manera es la adecuada para usar
la información creada por un sistema.
Las clases SOP contienen una definición de objeto (IOD) y servicios para ser aplicados a ese objeto. En el manejo de los datos de las imágenes, como lo descrito en
DICOM, está sólo limitado por la transferencia (clase de almacenamiento SOP) y por
el medio de almacenamiento. En este capı́tulo, además de usar los términos almacenamiento de clase e instancia SOP, el término DICOM Image SOP Class/Instance,
se usa para referirse al proceso de los datos de la imagen.
DICOM no tiene forma de describir el tipo de manejo de datos de las imágenes;
el nombre de almacenamiento de clase SOP es poco claro y es confuso si se usa en
otros contextos.
2.3.10.
Modelo de información de las imágenes
El manejo electrónico de la información requiere un modelo para representar la
forma en que la información está estructurada. Esta estructura es necesaria para
tener instancias uniformes y para hacer posible la descripción de las relaciones entre
instancias de forma clara. Un modelo de información de imagen deriva de la forma
en que las imágenes se manejan en un departamento de radiologı́a. Las imágenes
recogidas de uno u otro aparato, son recopiladas en una carpeta perteneciente al
paciente correspondiente. Las imágenes son ordenadas en la carpeta conforme al tipo
de examen realizado (series de imágenes que están relacionadas).
Los usuarios de cada tipo de aparato tienen su propia terminologı́a para esta
ordenación, como escáner, rodaja, etc. Cuando los datos de las imágenes de diferentes
fuentes tienen que ser recogidas en un ambiente único, debe ser posible ordenar los
datos de las imágenes de diferentes fuentes. Esto es sólo posible cuando los datos
están estructurados de acuerdo al mismo modelo de información.
46
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Mapping Real World Examinations
El modelo de información de imagen DICOM está basado en suposiciones sobre
la forma en que la información de diferentes aparatos están relacionados. Ver figura
2.22. Los cuatro niveles de este modelo de información son paciente, estudio, serie e
imagen.
Figura 2.22: Modelo de información
Nivel de paciente
El nivel del paciente contiene la identificación y la información demográfica de
éste al cual el estudio le pertenece. Debido a que puede existir más de un estudio, el
nivel del paciente es el nivel más alto (cuando toda la información es recogida para
un solo paciente se lleva a una cuenta).
Sin embargo, es de práctica normal usar el nivel del estudio para recoger la información manejada por varios sistemas para un única respuesta a este estudio.
Nivel de estudio
El nivel de estudio es el nivel más importante en el modelo de información. Un
estudio es el resultado de una contestación a un cierto tipo de examen médico. Todas
las actividades en un departamento de radiologı́a se centran en el manejo correcto del
estudio. En un estudio, la información de identificación se guarda y puede contener
referencias a información relacionada al mismo estudio en un sistema de administración.
En general, una respuesta puede envolver procedimientos de diferentes máquinas.
Esto da a lugar a una serie de una o más imágenes, dependiendo del protocolo definido
por el examen realizado. Todos los datos son recogidos juntos en el mismo estudio
r
GVA-ELAI-UPMPFC0075-2003
47
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
principal. Un paciente puede tener muchos estudios como resultado de otros realizados
anteriormente.
Nivel de serie
Después del nivel de estudio todas las imágenes se recogen. El nivel de serie identifica el tipo de aparato que crea las imágenes, la fecha y el tiempo de creación de la
serie y los detalles del tipo de examen realizado y del equipo usado.
Realizar una lista de los términos usados en los diferentes aparatos tiene que ser
cuidadosamente considerado. Puede haber palabras que aparentemente signifiquen lo
mismo, pero se usan con diferencias en distintos contextos. Las series siempre son
una colección de imágenes que provienen de una único aparato. La forma en que
las imágenes están agrupadas en series depende del uso médico que se les va a dar.
Cómo las imágenes son adquiridas por una máquina es menos importante para ésta
agrupación. Sin embargo, varios atributos definirán el tipo de adquisición y se pueden
mostrar en la visualización. En algunos casos la relación entre las imágenes se define
mediante la forma en que la adquisición ha tenido lugar.
Cuando las adquisiciones en una secuencia tienen relación espacial o temporal, las
imágenes resultantes de esta adquisición pueden ser agrupadas en series. Una serie
nueva debe comenzar cuando la relación existente entre imágenes ya no existe.
Otro criterio para agrupar imágenes puede ser coger los datos de una única parte
del cuerpo hecho durante un estudio completo. Por ejemplo, cuando un aparato produce un número de imágenes del estómago de un paciente desde diferentes posiciones y momentos, las imágenes pueden ser agrupadas en una serie. Algunos sistemas producen más de una imagen al hacer una adquisición de datos. Por ejemplo,
algunos escáneres se hacen con un sistema CT, las imágenes reconstruidas desde
cada escaneamiento son recogidas en series y tienen relación espacial. El siguiente escaneamiento estará en una nueva serie, porque en muchos casos el proceso de escanear
se hace desde diferentes posiciones.
También, en una serie, una imagen de referencia puede ser incluida como una descripción de la posición espacial de las rodajas individuales. Ver figura 2.23. Diferentes
reconstrucciones puede ser guardada en diferentes series.
Para cada tipo de aparato médico hay reglas definiendo los contenidos que una
serie debe describir. Las reglas usadas por un sistema dado son parte de un perfil de
sistema en el estatuto de conformidad DICOM.
48
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Figura 2.23: Ejemplo de mapeado de una imagen CT
Nivel de imagen
El nivel más bajo del modelo de información es el nivel de imagen. Cada imagen
contiene la información de adquisición y posicionamiento al igual que los datos propios
de la imagen. Dependiendo del tipo de aparato, el nivel de imagen contiene datos para
una sola imagen, dos imágenes (sistema de dos planos) o una colección de imágenes
cogidas en un corto espacio de tiempo (multiframe images).
El uso de multiframes images guarda la información duplicada en niveles más altos,
pero es sólo posible cuando la relación entre los marcos (frames) pueden ser descritos
de una sola manera. Por ejemplo, los incrementos en los movimientos del sistema
y del tiempo son iguales para todas los marcos. Creando un multiframe images es
más complejo y gasta más recursos que creando una imagen única. La relación entre
marcos, la capacidad del aparato y la carga de datos producidos deberı́a ser usada
para determinar si se debe aplicar una serie de imágenes simples o un multi marco
de imágenes.
2.3.11.
Instancias imagen SOP
El modelo de información mostrado en la figura 2.22 es una simplificación del
modelo de información completo de imagen DICOM de la figura 2.23 Cada bloque
r
GVA-ELAI-UPMPFC0075-2003
49
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
en este diagrama representa una entidad de información (ver IODs) del IOD compuesto. Las relaciones indican los puntos cardinales para cada relación de la entidad
de información usada en una instancia SOP.
Cada instancia de imagen SOP tiene que contener la información estructurada de
acuerdo al modelo de información DICOM. Cada instancia de imagen SOP (simple
o multimarco) es una instancia compuesta SOP que contiene el árbol completo de
información del modelo de información. Todas las imágenes en una serie son de un
mismo paciente, estudio y serie; todas las series son del mismo paciente y estudio, etc.
En cada composición, toda la información relacionada con la imágenes está disponible.
Este formato hace más fácil el intercambio y el manejo (especialmente el almacenamiento) de la información pero incremente la carga de datos cuando se transfiere
un estudio completo.
En este caso las entidades de información del paciente y del estudio tienen múltiples instancias en la colección de las instancias SOP. En contraste, las instancias
normalizadas SOP (con entidades de información simples) usan referencias a otras
entidades de información, perteneciendo un protocolo más eficiente, pero requiriendo
un manejo más complejo.
2.3.12.
Relaciones e indentificación
Cuando se recoge un grupo de Image SOP Instances las cuales tienen relación entre
ellas, pero están creadas desde diferentes aparatos, es importante ser capaz de marcar
las entidades de información en diferentes niveles. Son importantes dos aspectos:
1. Todas las modalidades deben tener un mapa (código) consistente de cómo pasar
de unos datos de imagen a una instancia SOP.
2. Las entidades de información individuales deben contener la identificación suficiente de hacer un correcto marcado de las entidades de información equivalente
en otras instancias SOP.
Estructura de los datos de las imágenes
El primer aspecto requiere que los datos producidos por los aparatos sean ordenados en series que tengan una relación como la descrita en la sección nivel de serie.
En los niveles de serie e imagen, la secuencia de imágenes dentro de una secuencia
debe ser identificada en un aparato.
50
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Figura 2.24: Modelo de información de una imagen compuesta DICOM
Las entidades de información sobre el nivel de serie deberı́a contener información
perteneciente al estudio y al paciente que debe ser comparable con la información de
otros aparatos. La mayorı́a de esta información viene de fuentes externas como un
sistema de planificación. Puede ser suministrado al aparato por la interfaz de usuario
o mediante una conexión a un sistema de información.
Identificación
Si los datos de imagen tienen que ser almacenados en sistemas los cuales ordenan
los datos examinando el contenido de la información de la entidad, debe haber un
consentimiento y un acuerdo para indentificar la información de la entidad por todos
los sistemas (aparatos, sistemas de almacenamiento, estaciones de trabajo, etc.) los
cuales manejan la información.
Visualizar la información es más amplio que sólo ordenar imágenes. La identificación es también usada para acceder a los datos desde otros sistemas de información.
Los sistemas de información normalmente usan claves que no necesitan ser interpretadas por los seres humanos, pero tienen que ser únicos en el ambiente en el que son
usados.
El mecanismo DICOM que se ha definido para estas identificaciones son los UIDs.
Cada una de las entidades de información en el modelo de información tiene su propia
r
GVA-ELAI-UPMPFC0075-2003
51
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
UID, excepto para la entidad de información del paciente. La forma en que la información debe ser identificada se define por otros sistemas de información (fuera del
visor DICOM) que tratan con la administración paciente. En este caso se usa un
identificador ID para el paciente.
Identificación del estudio
Como el estudio de un examen médico realizado por un doctor es el centro de
todas las actividades en un departamento de radiologı́a, debe ser reflejada en todas
las piezas de información las cuales están relacionadas con el examen realizado.
Para DICOM esta información se identifica al nivel de estudio. En la mayorı́a de
los casos el atributo UID de la instancia del estudio (Study Instance UID) identifica la
entidad del estudio de información del estudio perteneciente al resultado del examen
del mundo real.
Cuando este UID se usa de una forma consistente por todos los sistemas involucrados, no es difı́cil relacionar todas las piezas de información con los datos de la imagen
en la instancia DICOM SOP. Sin embargo, esto requiere una unión entre todos los
sistemas involucrados para transferir la clave del sistema.
A parte de esta unión, los UIDs tienen que ser soportados por todos los otros
sistemas, no sólo los sistemas involucrados en el manejo de datos de imágenes. Un
sistema que genera los UIDs del estudio juega un mayor rol para distribuir el UID
a otros sistemas involucrados. Normalmente, esto deberı́a hacerse por un Sistema de
Información Radiológico (RIS) o por un Sistema de Información de Hospital (HIS),
que normalmente puede no siempre soportar el concepto UID.
Cuando el soporte para el UID de la instancia del estudio no está disponible,
no es posible usar este UID como unión a toda la otra información. Tiene que ser
reemplazada en esos casos por otras claves. RIS usa actualmente una o más claves
para acceder a su información almacenada, número de registro del estudio, etc. Esas
claves se imprimen en papel que pertenece al estudio. Esta información tiene que ser
incluida en la entidad de información del estudio y usada como reemplazo al UID del
estudio.
Usar el UID del estudio como unión con las partes relacionadas de la información es un aspecto importante para proporcionar un modelo de información DICOM
consistente, el cual puede ser expandido en otras partes de la información en un
departamento de radiologı́a.
Esta consistencia es muy difı́cil de mantener cuando el UID del estudio se reemplaza por un RIS o un método especı́fico de identificación.
52
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Otras identificaciones
A parte de las claves del sistema, los usuarios necesitan acceder a la información
y quieren usar identificadores que tengan sentido como el nombre del paciente, su dı́a
de nacimiento, fecha del estudio médico, etc.
Los aparatos médicos tienen que proporcionar una información lo más consistente
posible para permitir una identificación por parte de los humanos. La información de
identificación puede ser proporcionada por una única fuente cuando una unión entre
sistemas es posible.
Por ejemplo, el RIS da el nombre del paciente, su fecha de nacimiento, etc, como
parte de la información para realizar un examen médico. Este método previene el
error de máquina y permite una forma más eficiente de funcionamiento.
2.3.13.
Clasificación de los datos de imagen
El modelo de información define el modelo jerárquico de las entidades de información para dejar claro cómo la información dentro de diferentes instancias SOP pueden
ser agrupadas en diferentes niveles. En este sección la información de la instancia SOP
está clasificada de acuerdo a las funciones que tiene, pero independientemente de su
lugar dentro del modelo de la información. Desde luego, hay una fuerte relación entre
el proceso de modelado y el proceso de creación. La siguiente sección describe la forma
de producir los datos de la imagen.
En la figura 2.25 se muestra una descripción de la clasificación y la relación con
la arquitectura del sistema de un aparato médico. Las diferentes clases son creadas
en diferentes momentos en el tiempo cuando se realiza un examen médico. Cada
subsistema añade atributos al resultado final: la instancia de imagen SOP.
Información del paciente
Esta clase contiene información sobre el paciente al que se le realiza un estudio. En
un departamento de radiologı́a la información del paciente se sabe por otras fuentes,
como sistemas de información o formularios en papel. Sólo tiene que ser registrado
de una manera formal por un número de atributos como nombre del paciente, ID del
paciente, fecha de nacimiento, etc.
La información en esta clase es estable, excepto por la corrección de errores de
escritura y cambios de nombre en caso de enlaces matrimoniales, etc. El mantenimien-
r
GVA-ELAI-UPMPFC0075-2003
53
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Figura 2.25: Clasificación de la información de la imagen
to de esta información se hace por sistemas que actúan como fuentes para aparatos
médicos.
Uno o más atributos son clave para la información en otros sistemas de información. Otros atributos identifican al paciente como una persona o dan más detalles
sobre su condición. Un número de esos atributos son muy importantes para el proceso completo de identificación y conexión a otra información en un departamento de
radiologı́a.
Para permitir la identificación del paciente y la revisión de un estudio, el aparato
médico tiene que incluir esos atributos en las instancias SOP creadas.
Procesos en el hospital también tienen que enfrentarse con el manejo de la información en casos excepcionales. Por ejemplo, cuando un paciente desconocido es
examinado por emergencia, se deben realizar unos pasos para permitir que la información sea correctamente identificada cuando se conoce el nombre del paciente.
54
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Información del estudio
La información del estudio es una clase con una mezcla de información fuente. Por
un lado, la información será suministrada desde un sistema como un RIS (Sistema de
Información Radiológico) que identifica el estudio a través de más de un sistema. Por
otro lado, el aparato médico añadirá información sobre el paciente en el momento en
que el estudio se realiza. Información de otros sistemas incluyen una identificación
del estudio. Un UID de una instancia de un estudio es la forma más eficiente de
identificación, pero tiene desventajas. Un atributo alternativo, llamado número de
acceso, puede ser usado en un sistema RIS. En el caso de que no esté disponible un
UID de la instancia del estudio desde fuera de un aparato médico, éste tiene que
generar el UID de forma que garantice que es el único en el sistema.
Cuando las imágenes de un estudio se copian desde un almacenamiento local
para un destino remoto, es muy importante que se use el mismo UID de la instancia
del estudio. Esto previene la existencia de imágenes con diferentes identificaciones
provinientes un mismo estudio. Tales imágenes nunca pueden ser recogidas juntas sin
la intervención de un operador.
Otra información suministrada al aparato médico son los nombres de los médicos
solicitantes o la lectura de las imágenes y la información del paciente dinámica como
la edad, el peso, la ocupación, etc.
La información incluida localmente por el aparato médico identifica el estudio
proporcionando un valor para el atributo ID del estudio y la fecha y hora actual
del estudio. El ID del estudio es sólo relevante por el aparato usado para realizar el
examen médico.
Información de la serie
La clase de información de serie es la primera que es completamente generada por
el aparato médico. En esta clase el tipo de sistema, la localización y la identificación
del sistema es dada. La identificacián de las series consiste de un UID de la instancia
de la serie, que únicamente identifica la serie en los datos de la imagen y una serie
en la zona usada ID que puede ser usado para hacer una secuencia con series en un
estudio. Los ID de las series tienen sólo un significado para el aparato médico en
sı́ mismo, no hay una regla dada para este uso.
Con la información de las series, se suministran más detalles sobre la forma en
que las series son realizadas, la gente involucrada, la parte del cuerpo examinada, etc.
La parte de la información del equipo contiene información general sobre el sistema
usado por esta serie. Incluye información sobre la localización, la identificación del
r
GVA-ELAI-UPMPFC0075-2003
55
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
tipo y la serie, cuestiones de calibración, etc. Estos datos pueden ser compartidos
por series pertenecientes al mismo estudio y realizados mediante el mismo aparato
médico.
Se usa un marco de referencia para agrupar imágenes que tienen relación espacial
o temporal. Esto puede ser usado para dividir series en partes o a través de más de
una serie si se aplica la misma relación. Tal relación se identifica por un UID de marco
de referencia compartido entre las imágenes involucradas.
Información de la aplicación
Los atributos en esta clase dan información sobre la imagen contenida en la instancia SOP requerida para el diagnóstico y otras aplicaciones. Varios ejemplos, desde
un simple texto añadido como comentario, hasta detalles como el contraste, terapia
y dispositivos usados durante el reconocimiento médico.
Otro grupo describe la parte del cuerpo examinada usando valores codificados.
Los ajustes del valor de interés (VOI), en la mayorı́a de los casos llamado anchura
de ventana y centro de ventana (window width y window center), son miembros muy
importantes de esta clase. El VOI es la selección fuera de la gama completa de los
valores de pixel que son clı́nicamente significativos cuando se muestra o se imprime la
imagen. Sólo el rango especificado tiene que ser convertido a nivel de grises disponibles.
La información que dibuja lı́neas o agrega el texto a la imagen mostrada puede ser
en forma de matrices que tienen que ser agregadas a la muestra en un visualizador,
o ya aplicada a la matriz de pixel. Sumnistrando la superposición como una información separada de los datos de imagen, la imagen puede ser mostrada con o sin la
superposición, permitiendo que los datos de imagen puedan ser usados como entradas
para el tratamiento remoto.
Información adquirida
En esta clase de información se guardan los ajustes del equipo de adquisición. El
grado de información depende del tipo de aparato y puede tener un rango desde unos
pocos atributos para un sistema sencillo, a una estructura compleja. Contiene detalles
del sistema de adquisición como los valores usados de los rayos X por ejemplo.
Las imágenes resultantes de la misma adquisición pueden ser identificadas con un
número de adquisición. Este agrupamiento depende del sistema y puede ser parte
de series sencillas, pero una adquisición sencilla puede también resultar en múltiples series de imágenes, cada una con diferentes caracterı́sticas. La adquisición no
56
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
tiene relación con el modelo de información DICOM y no tiene un identificador UID
equivalente.
Información de la posición
Una clase importante es la información dada sobre el posicionamiento de la imagen
dentro del paciente.
Depende del tipo de aparato médico, de la forma en que se describe la matriz de
la imagen posicionada usando términos sencillos como anterior, posterior, derecha, en
frente, etc. Se debe tener cuidado para asegurar que haya proporcionada información
suficiente con la imagen para que no haya visualizaciones ambiguas (sobre todo en
cuestiones de derecha e izquierda).
En una serie que tiene relación espacial, como puede ser imágenes CT o MR, muchos más detalles se tienen que suministrar sobre la posición de las imágenes en el
espacio tridimensional del cuerpo del paciente. Esta información permite a sistemas
como planificadores de tratamiento de radioterapia usar el posicionamiento tridimensional para el procesamiento de los datos de las imágenes.
Otro uso de la información del posicionamiento es para sistemas de vasculación
para describir los movimientos dinámicos.
Información de los datos de las imágenes
Finalmente, los datos de las imágenes provenientes del sistema de adquisición y
procesados para producir imágenes visibles en formato digital. Esta clase describe
detalles sobre cómo los datos de los pı́xeles deben ser interpretados, como el tamaño
de la matriz de pı́xeles, el valor representativo de pı́xel y cómo estos están codificados.
Cuando los aparatos médicos son capaces de generar imágenes en color, tiene que
ser suministrada la información sobre cómo los datos son ordenados en diferentes
planos. A parte del formato de la información, esta clase contiene los datos de los
pı́xeles en un marco sencillo, en dos marcos para sistemas de dos planos o en multimarco. Cuando un multimarco se genera por un sistema de dos planos es posible
almacenar los marcos de los dos planos juntos. En este caso los marcos de los dos
planos se almacenan alternados (A-B-A-B-...). Para un multimarco las relaciones de
tiempo entre los marcos individuales se describen mediante otros atributos.
La imagen se identifica únicamente por el UID de la imagen. Como una instancia
SOP de una clase de imagen SOP siempre incluye una porción de la imagen, el
r
GVA-ELAI-UPMPFC0075-2003
57
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
UID de la imagen se usa también como UID de la instancia SOP. Este UID se usa
para identificar la instancia cuando se transfiere o se recupera desde un almacen de
imágenes o para identificar la entidad de la imagen usándola en un árbol jerárquico
de información.
2.3.14.
Extensión de la información
Para el almacenamiento de toda la información descrita en las clases de arriba
se definen atributos que se agrupan en IODs (Information Object Definitions) los
cuales dan una descripción genérica de las instancias SOP para cada tipo de aparato
médico. Los atributos que se usan actualmente deben ser descritos en el Estatuto de
Conformidad (perfil del sistema).
No siempre es posible guardar toda la información generada por un aparato en un
IOD estándar. En casos el equipo tiene nuevos campos los cuales necesitan información
adicional para alamacenarlos en un nuevo IOD. Se debe tener cuidado en que las partes
que usan esta información serán capaces de entender esta nueva información. Estos
detalles se tienen que publicar en el Estatuto de Conformidad. Si el uso se acepta, la
nueva información llega a formar parte del estándar.
La extensión puede no influenciar la semántica de la información guardada en
los atributos estándares. Tiene que ser un subconjunto apropiado, compatible con el
IOD del que deriva. En otros casos, el equipo de un vendedor único, puede añadir
información para ser usada sólo en la combinación de sistemas o sólo por el mismo
sistema que ha generado los datos. En esta situación, no existen detalles sobre la
información que tiene que ser publicada en el Estatuto de Conformidad. No hay
intención por otras partes de usar esta información adicional.
Para permitir la extensión de información, DICOM ha definido dos tipos de atributos: atributos estándar y privados.
Los primeros se usan para codificar los atributos descritos en el estándar IOD. Si
no hay extensiones o cambios en los IODs, la clase SOP es una clase SOP estándar.
Los segundos definen atributos o usan atributos estandarizados no pertenecientes
al IOD de una clase SOP especı́fica, no se pude seguir llamando clase estándar SOP
y depende del efecto que cambia a uno de los siguientes tipos:
Clase SOP extendida: cuando los atributos adicionales no cambian el uso de la
clase SOP. En este caso es un superconjunto, cuando se usa por sistemas los
cuales no son conscientes de las añadidos, se pueden ignorar y la imagen puede
ser manejada como se dice en la clase SOP estándar. Una clase SOP extendida
58
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
usa el mismo UID que la clase SOP estándar. Las diferencias entre las dos clases
se muestra en el Estatuto de Conformidad.
Clase SOP especializada: cuando las adiciones cumplen con el modelo de información, pero la clase ya no es un superconjunto. Como consecuencia, el UID de
la clase SOP estándar puede no ser usado; se debe usar un UID privado para
esta clase SOP. Los socios que manejan las instancias SOP conocen el UID privado y pueden manejar la información. Otros no pueden aceptar la clase SOP
durante la negociación de la asociación o, cuando se abre un archivo DICOM
desde un medio DICOM.
Clases SOP privadas: no siguen el modelo de información DICOM y se usan
en un contexto completamente privado. Usan mecanismos proporcionados por
DICOM para transferir la información. Las clases SOP privadas usan UIDs
privados para prevenir usos incorrectos de la información.
Si una de las tres clases SOP arriba mencionadas se definen con la intención de
llegar a ser parte del estándar DICOM, los detalles se publican en el Estatuto de
Conformidad. De otra forma, sólo se usan en un ambiente cerrado.
2.3.15.
Tipos de imágenes
DICOM define un número de tipos de clases de imágenes SOP, dependiendo del
aparato médico que crea los datos de las imágenes. Cada tipo tiene su propio IOD
para añadir información especı́fica del aparato a la instancia de la imagen SOP.
Todas las instancias de las imágenes SOP comparten un mı́nimo juego de información que permite a una aplicación visualizadora manejar las imágenes independientemente de su tipo.
Una clase de imagen SOP está disponible para encapsular las imágenes que no
están disponibles en el formato digital y sı́ capturadas en formato de pelı́cula o de
vı́deo.
Tipos genéricos de imágenes
Las instancias de las clases de las imágenes SOP tienen un conjunto básico de
atributos; ver figura 2.26. El conjunto mı́nimo de atributos requeridos para una instancia de imagen SOP consiste en el siguiente grupo de atributos:
r
GVA-ELAI-UPMPFC0075-2003
59
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Atributos identificadores: UID de clase SOP, UID de la instancia del estudio,
UID de la instancia de la serie y UID de la instancia de la imagen (= UID de
la instancia SOP).
Tipo de aparato.
Descripción de la matriz de pı́xeles: muestra por pı́xel, filas, columnas.
Interpretación del valor del pı́xel: interpretación fotométrica.
Codificación de los pı́xeles: bits asignados, bits almacenados, bit alto, representación de pixel, configuración plana.
Matriz de pı́xeles: datos de pı́xel.
Este mı́nimo conjunto permite mostrar los datos de pı́xel y proporciona la identificación en el nivel de sistema, para el caso de la instancia SOP para adherirla modelo
de la información. Añadiendo más información al menos para los tres primeros niveles del modelo de información, hace más entendible a la instancia SOP. Los atributos
que identifican la instancia SOP para seres humanos y permiten que la imagen sea
mostrada.
Figura 2.26: Juego básico de atributos de las instancias de imagen SOP
Añadiendo más información para al menos los tres primeros niveles del modelos de
la informacón, hace la instancia SOP más comprensible. Los atributos que identifican
60
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
la instancia SOP para los seres humanos y permiten que la imagen sea visualizada
con los correctos ajustes de ventana son:
Nivel de paciente: nombre, ID, dı́a de nacimiento, sexo.
Nivel de estudio: fecha del estudio, hora, nombre del médico, ID del estudio,
número de acceso.
Nivel de serie: número de serie, fabricante, nombre de la institución.
Nivel de imagen: número de imagen, tipo de imagen.
Ajustes de presentación: ancho de ventana, centro de ventana.
Los atributos listados arriba son en la mayorı́a de los casos atributos del tipo 2
(deben ser suministrados, pero pueden faltar) o del tipo 3 (opcionales).
Tipos de imágenes especiales
El formato genérico descrito arriba se usa en la definición de cada clase SOP,
pero depende del tipo de modalidad, esto se extiende con la información entregada
sobre la adquisición, etc. El número de imágenes especializadas está creciendo por
la aparición de nuevas modalidades. Normalmente, las modalidades siguientes tienen
una definición de la clase SOP de almacenamiento en el estándar DICOM:
Radiografı́a computada IOD (Computed Radiography IOD), usada por los sistemas radiográficos tradicionales que trabajan con fósforo que brilla al leerse
con sistemas como PCR.
Tomografı́a computada IOD (Computed Tomography IOD) para escáneres CT.
Para este tipo de aparatos el posicionamiento es importante, para montones de
imágenes, para crear vistas tridimensionales.
Resonancia magnética IOD (Magnetic Resonance IOD) para sistemas MR. A
parte de la misma información que para escáneres CT también se da información
adicional sobre el protocolo de adquisición.
Medicina nuclear IOD (Nuclear Medicine IOD) para cámaras usan isótopos
radiactivos. Contienen imágenes de especial formato para este tipo de aparatos.
Las imágenes son en multimarco formato.
Ultrasonidos IOD (Ultrasound IOD) para este tipo de equipos. Estos contienen
detalles sobre la posición y la adquisición de la imagen. Las imágenes pueden
ser en color y se puede usar el multimarco.
r
GVA-ELAI-UPMPFC0075-2003
61
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Angiografı́a con rayos-X IOD (X-Ray Angiographic IOD) para sistemas digitales cardiológico y basculares. Este formato puede capturar una cadena en
multimarco o imágenes simples.
Radiofluoroscopı́a de rayos-X IOD (X-Ray Radiofluoroscopic IOD) para sistemas como sistemas angiográficos.
Por cada uno de los IODs, se describe una lista de módulos en el estándar DICOM.
El uso de unos ciertos módulos a veces dependen de capacidades o condiciones de ciertos sistemas. Los módulos se seleccionan, o bien desde un grupo de módulos comunes
usados para todos los IODs de almacenamiento SOP, o bien desde módulos especı́ficos
para sólo un tipo de IOD.
Estos módulos contienen atributos especiales para ese tipo de IOD. Esos módulos,
y a veces atributos individuales, los redefinen y extienden para el IOD genérico. En
el estándar DICOM los IOD, IOM y los atributos se listan.
Imagen Secundaria de la Captura
La Clase SOP Secondary Capture es una especial Clase SOP de imagen. Es utilizado para el almacenamiento de imágenes en formato diferente al de DICOM, dentro
de un ambiente de DICOM convirtiéndolas al formato de DICOM. De esta manera la
informaciónde la imagen en formato diferente al de DICOM se puede combinar con la
información de la imagen de los sistemas DICOM que pertenecen al mismo estudio.
Esta Clase SOP incluye imágenes capturadas de equipos de pelı́cula digital, capturas de pantallas, etc. El Secondary Capture IOD no contiene ningún detalle sobre
la modalidad y la adquisición de los datos de la imagen. Da solamente los detalles
sobre cómo los datos de la imagen fueron capturados.
El IOD permite que la imagen sea manejada como cualquier otra modalidad. En
un número de casos contiene solamente los valores del nivel de gris de una captura de
pantalla que pueda verse. Por ejemplo, una imagen hecha con una captura de pantalla
contiene solamente los niveles grises en la matriz del pixel (como una fotografı́a).
Pero, en otros casos, contiene una matriz verdadera del pixel que necesite un valor
de pixel a la conversión de gris, permitiendo la manipulación de la representación. Esto
permite utilizar la Clase SOP Secundary Capture para almacenar datos de la imagen
en modalidades para las cuales no hay IOD estándar disponible. Esto requiere el retiro
de toda la información relacionada modalidad de la adquisición, de la colocación y
otros. Solamente el paciente, el estudio, la serie, el recubrimiento, y otra información
adicional que esté disponible.
62
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
El formato permite la posibilidad de salvar una descarga de pantalla en una modalidad. Este método tiene la desventaja que la matriz de la imagen, en la mayorı́a de
los casos, no es cuadrada y contiene la información del paciente y la otra información
que es duplicada por las cualidades estándares. Cuando está exhibido sin medidas
especiales, mostrará la imagen con un formato reducido (en la mayorı́a de los otros
casos la zona de visualización de la imagen es cuadrada) y mostrará la información
del paciente dos veces.
2.3.16.
Procesando imagen
Una tuberı́a del procesamiento de una imagen describe los pasos del proceso que
traducen la información adquirida (por X-Ray, SR., ultrasonidos, equipo, etc.) a una
imagen presentada en un vı́deo o muestra una pelı́cula. Algunos de los pasos del proceso dependen del sistema de la adquisición, otros mejoran la presentación, o utilizan
una serie de información adquirida para crear las imágenes derivadas (substracción,
imágenes tridimensionales, etc.). Los siguientes pasos del proceso se han distinguido:
Pasos en el proceso de la adquisición que incluyen la conversión a los datos
digitales, correciones, reconstrucciones, etc. Estos pasos están en la mayorı́a de
los casos realizados por el sistema de la adquisición.
Pasos intermedios del proceso para realzar la presentación o crear la derivaron
de imágenes.
Pasos del proceso de la presentación dando por resultado una imagen que es
mostrada o impresa.
Un número de los pasos de proceso son realizados por el sistema de la adquisición.
Otros pasos de proceso se pueden ejecutar en un sistema distribuido. En este caso
una transferencia de la información es necesaria. Esto requiere una definición de la
información y un protocolo entre del ambos sistemas. Dos tipos de intercambio de
información pueden ser definidos:
Datos procesados de la imagen que necesita solamente la conversión apropiada
a los niveles grises para mostrarla.
Los datos de la imagen convenientes para la transformación posterior van junto
con los parámetros del proceso. Este grupo puede estar partido en:
• usar datos procesados de la imagen o
r
GVA-ELAI-UPMPFC0075-2003
63
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
• Datos “crudos”(Raw) de la imagen que no es conveniente para la exhibición
sin los pasos intermedios del proceso.
Los diversos tipos de pasos del proceso y de los datos transferidos de la imagen se
muestran en el cuadro 2.27.
Figura 2.27: Pasos del proceso y tipos de datos de la imagen
Datos Raw de la imagen
El intercambio de la información de la imagen en la tuberı́a del proceso de la
imagen que contiene datos “crudos” (Raw) de la imagen necesitan cuidado adicional.
El proceso adicional es requerido para la correcta presentación de la imagen.
El proceso para este tipo de imágenes incluye funciones tales como substracción
digital, ciertos dominios de filtración de frecuencia o combinar partes de imágenes a
una sola imagen más grande.
Para este tipo de proceso los datos de la imagen tienen que estar acompañados
con la información de los pasos del proceso para que puedan ser invertidos, procesando parámetros e indirectamente para los pasos que se realizarán, la adquisición
adicional y colocado de la información, etc. Las Instancias SOP usadas para este tipo
de imagenes, no se piensan para el uso general, ası́ que una Clase SOP especializada
o privada es necesaria. La información se divulga solamente a las partes implicadas.
Datos procesados de la imagen
La representación correcta es un factor importante en la prevención de la interpretación incorrecta de una imagen cuando se muestra en diversos sistemas, con
diversos métodos y una variedad de entornos. La conversión gris de la escala debe
cuidarse de todo el comportamiento no linear del dispositivo de exhibición, del entorno
y del ojo humano; véase la figura 2.28.
64
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Figura 2.28: Muestreo
El resultado de los pasos del proceso de la presentación de una imagen es correcta
según lo interpretado por el usuario del sistema de visualización.
La entrada de este proceso de presentación requiere que los pasos del proceso que
preceden creen valores del pixel de tal manera que todos los valores del pixel tienen
un valor significativo unos con respecto a otros. Estos valores dependen del tipo de
sistema o/y del uso de los datos de la imagen.
En el caso de sistemas de la Rayos X los valores absolutos de los pixeles no son
significativos, sólo el valor relativo se utiliza para la conversión a los niveles grises.
Para imágenes CT y MR los valores del pixel son un factor importante para el uso
clı́nico y se deben presentar junto con la imagen mostrada. Los pasos del proceso
deben tener cuidado con los valores proporcionados de pixel en la correcta escala.
Conversión y selección de los valores del pixel
En un número de situaciones los valores del pixel provistos por los pasos precedentes (adquisición e intermedio del proceso) tienen que ser utilizados para la transformación posterior. Esto requiere a veces otra relación entre los valores de pixel según
lo esperado por los pasos del proceso de la presentación. Por ejemplo la relación entre
los valores de pixel estan en una escala logarı́tmica y no proporcional a las medidas
fı́sicas. Antes de que la conversión a los niveles grises pueda ocurrir un paso del proceso debe ocurrir, basado en los valores provistos junto con los valores del pixel; véase
el cuadro 2.29.
Según algunos usos clı́nicos la exhibición de la información adquirida tiene que ser
r
GVA-ELAI-UPMPFC0075-2003
65
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Figura 2.29: Datos de pixel con la conversión de los valores del pixel
ajustada a un subconjunto de la gama completa de los valores del pixel. El resultado
es la exhibición de los valores del pixel relevante usnado la escala de nivel de grises.
Este subconjunto se llama una ventana, y se puede especificar por su valor de centro
y el tamaño de la ventana.
Las conversiones y las selecciones antedichas dependen del tipo de de sistemas y
el uso de los datos de la imagen. Algunos sistemas aplican ya estos ajustes a los datos
de la imagen antes de la transferencia. Otros sistemas transfieren los datos originales
de la imagen con una descripción de las funciones que se aplicarán por el sistema de la
visión. En el primer caso que no hay reajuste posible, es conveniente para el sistema,
produciendo siempre las imágenes para un solo tipo de uso.
Pasos de la Presentación
Los pasos de la presentación convierten los valores del pixel a una imagen exhibida
en la pantalla o pelı́cula de video. Estos pasos tienen en cuenta los siguientes puntos:
Los valores del pixel no pueden tener ninguna relación o valor semántico correcto
(no linear, no escalado, etc.).
Una gama de los valores del pixel debe ser presentada.
La representación del valor del pixel en la pantalla o la pelı́cula de video debe
ser perceptualmente correcta.
Para una descripción del proceso de la presentación véase la figura 2.30.
Las primeras dos funciones dependen del contenido de la información de la imagen
y tienen que ser almacenadas en la Clase SOP. La función pasada es dependiente del
66
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Figura 2.30: Pasos del proceso de la presentación de una imagen
dispositivo. El resultado de las primeras dos funciones debe dar lugar a una gama
de los valores del nivel de gris que se aseguran de que el resultado de la corrección
dependiente del dispositivo sea igual en diversos sistemas. Estas dos o tres funciones
tienen que ser aplicadas a los datos del pixel en un paso de proceso para prevenir la
pérdida de calidad de la imagen debido a la acumulación de errores de redondeo en
cada función.
Requisitos para el procesado de la imagen
La conclusión de la sección anterior conduce al requisito de que los datos procesados de la imagen intercambiados entre los sistemas deben contener la suficiente
información para dar lugar a imágenes equivalentes cuando están utilizados en diversos sistemas cada uno con su propia corrección del dispositivo. Esta información debe
ser estructurada de una manera tal que permita que una puesta en práctica combine
todas las funciones necesarias en un paso.
En DICOM hay actualmente dos maneras de describir las funciones:
para una función linear es necesario dar factores (y = ax + b),
para la conversión no linear el mecanismo de una LUT está disponible: para
cada gama de los valores de la entrada se almacena un valor de la salida. Un
ejemplo para una conversión no linear es las curvas redondeadas lisas para la
tapa y el fondo de una ventana; véase la figura 2.33
La última manera de describir una conversión no linear tiene una desventaja importante. Introduce cambios precipitados en el valor de la salida cuando la entrada
r
GVA-ELAI-UPMPFC0075-2003
67
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
valora pasos en un lı́mite de la gama. Si una secuencia de estas tablas del look-up
(LUT) se está utilizando, baja la calidad de la actual imagen. También no permite
que la composición de las funciones sea realizada en un paso (prevenir la pérdida de
la calidad de la actual imagen). La carencia de las posibilidades para especificar una
función no lineal en forma de un fórmula matemática es una desventaja importante
de las definiciones actuales de DICOM.
Imágenes Procesadas DICOM
Para las imágenes transferidas con DICOM, se definen un número de módulos que
contienen la información para el paso de la presentación descrita arriba:
Módulo del pixel de la imagen que contiene los valores de la muestra del pixel, almacenado en una cadena de los datos del pixel, con las cualidades que
describen la codificación y el formato de la matriz del pixel.
Modalidad LUT (MOD LUT) con una descripción de la función para la conversión. Figura 2.30.
Valor de interés LUT (VOI LUT) con una descripción de la función de seleccionar una ventana en la gama de los valores del pixel. Figura 2.30.
Sobreponga móduloslos cuales agregan la información gráfica para ser mostrar
que sobrepone la imagen exhibida.
Dependiendo del requerimiento del procesado del módulo MOD LUT, el módulo
VOI LUT o ambos pueden estar presentes al lado del módulo del pixel de la imagen.
Un VOI LUT es muy probable estar presente para poder mostrar correctamente las
imágenes par ciertas aplicaciones clı́nicas.
La información puede contener lı́neas y cı́rculos para mostrar el campo de interés,
o una bitmap con cadenas de caracteres para anotar la información en la imagen
mostrada. Esta información se provee como entidad separada. Cuando esta información se agrega a los datos del pixel se tienen muchas limitaciones con el uso de los
datos de la imagen. En este caso el valor de algunos de los pixeles se cambia al valor
del recubrimiento.
Paso de decodificar
El proceso de descodificación de la matriz del pixel desde las cadenas del Cell
Pixel, es utilizando dos grupos de cualidades del Image Pixel Module. Vea la figura
2.31
68
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Figura 2.31: Decodificación de los Datos de Pixel
Bits Allocated, Bits Stored, y High Bit para decodificar el Pixel Sample Values
desde Pixel Data Stream, y
Filas, columnas, muestras por pixel y configuración planar para pedir las muestras del pixel en la matriz de la imagen.
Una sola muestra del valor del pixel se contiene en una célula de pixel (Cell Pixel).
Además del valor de la muestra, otro pixel de información puede ser almacenado en el
espacio no ocupado por la célula del pixel. La secuencia de los valores del Sample Pixel
se almacenan en la matriz del pixel con la dimensión en la columna, fila, muestras
por atributos del pixel. Cuando se utiliza más de un plano, la configuración planar
describe cómo los valores de la muestra se ordenan en la secuencia de datos del pixel.
Los atributos del Pixel Representation contiene el formato de datos de los valores
de la muestra del pixel: enteros con signo o sin signo.
Paso de Normalización
Ocurre después de decodificar la conversión de los valores del pixel significativo,
para un cierto tipo de Clase SOP de la imagen (Image SOP Class). El resultado es
una gama normalizada de los valores del pixel convenientes para la conversión a los
niveles grises y según qué espera para ese tipo de modalidad y de su uso clı́nico.
Por ejemplo, para los Rayos X, la intensidad es proporcional a los valores de pixel,
r
GVA-ELAI-UPMPFC0075-2003
69
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
para los sistemas CT los valores de la muestra del pixel se convierten a la escala de
Hounsfield, etc.
En caso de que solamente una escala pueda ser utilizada, dos atributos son necesarios describir la función:Rescale Slope y Rescale Intercept; ver la figura 2.32
Figura 2.32: Modalidad dependiendo de la escala y la conversión
Cuando una conversión no linear tiene que ser aplicada se utiliza el mecanismo de
la tabla del “look-up”.
Paso de conversión a escala de grises
En la mayorı́a de los casos la gama completa de los valores normalizados de la
muestra del pixel tiene que ser reducido a una gama secundaria que contenga la valiosa
información para el uso de la imagen. En su conversión, ésta tiene que ser convertida a
la representación del nivel gris. Para algunos usos más entonces una gama secundaria
se selecciona. En ese caso, las ventanas separadas tienen que trazar diversas gamas
de niveles grises.
La ventana es descrita por dos atributos. Los dos atributos permiten solamente una
conversión linear del rango seleccionado, la conversión no linear se pueden alcanzar
por medio de una tabla “look-up”. Cuando no se utiliza ninguna tabla, las ventanas
son descritas por el valor de centro del pixel (centro de la ventana) y el tamaño de la
ventana (anchura de la ventana); ver figura 2.33.
70
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
Figura 2.33: Conversión a escala de grises
Paso de Recubrimiento
Uno o más módulos separados especifican donde los bitmap del recubrimiento se
deben colocar en la matriz de la imagen. Opcionalmente, el color de los contornos
puede ser especificado. Los bitmap que pertenecen a estas imágenes se pueden incluir
en la secuencia de datos del pixel o en matrices separadas del pixel.
En las posiciones correspondientes en la matriz del pixel, tienen que ser fijados los
valores para el contorno del recubrimiento antes de enviar la imagen del nivel gris al
paso siguiente.
Paso de la corrección del dispositivo
Los valores convertidos de la muestra del pixel tienen que ser corregidos para
alcanzar una comprensión correcta de la imagen. Las correcciones son el dispositivo y
el entorno dependiente y tienen que ser determinadas por el calibrado del dispositivo
e incorporando el resultado de la calibración como función de la corrección que se
aplicará a los valores del nivel gris.
Para prevenir la pérdida de calidad debido a la ejecución de las dos o tres funciones
(véase la figura 2.30) por separado, todas las funciones tienen que ser combinadas en
una tabla “look-up” que convierta los valores almacenados del pixel directamente
en una representación perceptualmente correcta. Esto, sin embargo, funcionará solamente cuando todas las funciones se describen y no se almacenan matemáticamente
en tablas “look-up”.
r
GVA-ELAI-UPMPFC0075-2003
71
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
2.3.17.
Fernando Ballesteros Herranz
Aplicación de los Datos de las Imagenes
Las Clases SOP de la imagen están en general generadas en modalidades. El
resultado se muestra en la impresión de la pelı́cula. Los sistemas del almacenaje
protegen las imágenes mientras tanto, o archivan estas imágenes para la referencia
ulteriormente.
En el intercambio de datos entre los sistemas, cada sistema puede tener diversas vistas de la información, aunque toda la información de la Image SOP Instance
esté transferida entre cada sistema implicado. Incluso cuando un sistema en una cadena no está utilizando la información, otro sistema que está utilizando la información,
está confiando en pasar la información completa de la cadena entera, véase la figura
2.34.
Figura 2.34: Ciclo de vida de la información de una Image SOP Instance
Sistemas de almacenamiento de imágenes
Los sistemas de almacenamiento de imágenes usan un número de atributos identificatorios para almacenar las instancias de imagen SOP.
En primer lugar, estos atributos se usan para recoger todos los datos de las
imágenes pertenecientes al mismo estudio. La instancia UID del estudio (Study Instance UID) es el atributo clave. Pero cuando éste no se usa consistentemente, se
tienen que usar otros atributos como el ID del paciente, número de acceso, etc.
En segundo lugar, unos atributos pueden ser usados por sistemas que quieren encontrar instancias de imagen SOP en el sistema de almacenamiento. La clave principal
72
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
en este caso es la instancia UID del estudio y la instancia UID de la serie. Son posibles
también búsquedas basadas en el nombre del paciente, fecha del estudio, etc.
Para el uso de sistemas de almacenamiento un valor muy significativo para estos
tipos de atributos se tiene que suministrar por los creadores de la instancia de la
imagen SOP. Los atributos que contiene los parámetros de adquisición y los datos de
la imagen se almacenan pero no tienen significado para un sistema de almacenamiento.
Estaciones de revisión
Una estación de revisión es básicamente usada para visualizar las imágenes hechas
en uno o varios aparatos. Recoge o busca las instancias de imagen SOP, en un sistema
de almacenamiento, perteneciente a un cierto estudio. Mostrará la imágen junto a la
información del paciente, ajustes de adquisicóon, información del diagnóstico, etc.
Los ajustes para el proceso de presentación, como los seleccionados en el aparato de
captura, son muy importantes. Cuando los pasos de presentación se procesan de forma
correcta, los resultados mostrados deberı́an ser iguales a los originales mostrados por
el aparato médico de captura de la imagen.
Para información adicional de otros sistemas, se usan atributos identificadores
como la instancia UID del estudio.
Estaciones de procesamiento de imágenes
Las estaciones de trabajo capaces de procesar los datos de las imágenes tienen requerimientos adicionales. Se necesitan los parámetros de adquisición y posicionamiento para la realización de pasos adicionales de procesamiento. Dependiendo del tipo
de procesamiento la entrada es un conjunto de imágenes procesadas o no procesadas.
En este caso, en la relación entre las imágenes, es importante ordenar los datos de las
imágenes de forma correcta para el procesamiento.
Los resultados de este procesamiento son nuevos datos de pı́xeles que son almacenados en una nueva instancia de imagen SOP que tiene su propio ciclo de vida, en la
mayorı́a de los casos, relaciones con los datos originales usados por la imagen.
r
GVA-ELAI-UPMPFC0075-2003
73
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
Reutilización de datos
Una categorı́a final de las aplicaciones es el sistema que ha creado la instancia de
imagen SOP. En este caso los datos antiguos de la imagen pueden ser usados cuando
hay una nueva visita del mismo paciente con el mismo tipo de examien. Los datos
de adquisición y el posicionamiento pueden ser reutilizados, o la imagen puede ser
visualizada como una referencia para el nuevo examen.
Categorı́as de aplicación
Como lo mostrado arriba, las exigencias de los sistemas individuales en el ciclo
de vida de una una instancia de imagen SOP son diferentes. Cuando un sistema
produce los datos de la imagen, debe estar alerta de que todos los sistemas que están
intentando ser parte del ciclo de vida deben recibir suficiente información. El estatuto
de conformidad (conformance statement) debe describir, para cada tipo de sistema,
la información adecuada y qué procesamiento no puede ser aplicado.
Para ayudar a la selección de estos tipos de sistemas, los requerimientos pueden
ser divididos en categorı́as de aplicación. Una categorı́a alta numerada incluye la
categorı́a baja numerada. Se definen las siguientes categorı́as:
1. Categorı́a de almacenamiento: sólo identifica los atributos requeridos.
2. Categorı́a de visualización: sólo se requieren los atributos para una correcta
presentación.
3. Procesamiento simple - medidas de volumen y distancia: requiere algunos atributos más que describan qué información está en la imagen.
4. Procesamiento complejo - sustracción de imagen y MRP: requiere información
especı́fica sobre el posicionamiento y relaciones.
2.3.18.
El futuro de DICOM
El alcance del problema de comunicación de imágenes médicas es tan extenso,
que aún hay mucho por hacer. Quizá primero es la demostración de que DICOM
trabaja como una especificación y un patrón. En los últimos 2 años, el RSNA ha
ayudado a este papel. Con un contrato a Mallinckrodt una Institución de Radiologı́a
para desarrollar el software, el RSNA, miembros de NEMA, y ACR han trabajado
sobre demostraciones de DICOM. Mallinckrodt provee los nódulos centrales de prueba
74
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
2.3. ESTÁNDAR DICOM
(CTNS) que trabajan como servidores para retener imágenes y administrar la red.
Los fabricantes conectan a estos CTNS para usar su implementación del Estándar
de DICOM, y usando el servicio clases, o envı́os, recibe, inquiere, o “imprimen” las
imágenes (imprimir sobre la pelı́cula que requiere un procesamiento mojado no es
factible en el área de diagnóstico a causa de los requisitos de tuberı́a). Los fabricantes
pueden escoger también enviar imágenes, o recibir imágenes de un fabricante diferente.
Algunos fabricantes pueden cumplir también una conexión al equipamiento en el área
Técnica de documentos de prueba, y algunos pueden mostrar la implementación de
la interfase HIS/RIS con apoyo del servicio de clases (el servicio de dirección clases).
Mediante un número importante de esfuerzos independientes de implementación, la
calidad del patrón en suplementario hace efectiva la interoperatibilidad, que ya se ha
demostrado. El alcance de la imagen médica se extiende más allá de las imágenes
radiológicas. Endoscopistas, patólogos, dentistas, y dermatólogos (por nombrar sólo
cuatro justo áreas de especialidad) todas trabajan con imágenes como parte de su
práctica.
Recientemente, los representantes de las sociedades profesionales de estos grupos
han contado con un grupo de trabajo especial de ACR-NEMA para comenzar planificando, como ellos podrı́an aprovechar del Trabajo de DICOM. El enfoque de DICOM
a objetos orientados a diseño hace este proceso relativamente directo. Los miembros
de las sociedades profesionales pueden proveer la experiencia sobre la construcción
apropiada de objetos de información, y los grupos de ACR-NEMA pueden entonces
ayudar a implementarlos en el estándar de DICOM.
La mayorı́a del nuevo equipamiento cardı́aco de los laboratorios producen imágenes
digitales, pero como con CT o MR, los fabricantes usan distintos formatos y medios
de almacenaje. El convencional 35 mm de pelı́cula evita este problema pero no es una
solución eficaz en función de los costos cuando las imágenes están en forma digital
para comenzar.
El almacenado de la información sobre alguna forma de medio removible. Esta es
necesaria a causa de la naturaleza no de red los laboratorios cardiacos y angiográficos,
y a causa de la necesidad de proveer de imágenes de cine a otros especialistas que
pueden un equipo solo. Se ha producido la parte 10 de DICOM que describe el Medio
de Almacenaje y el Formato de Archivos. Esta parte son unos conjunto de definiciones
de medios independiente. El formato de archivo describe como poner un conjunto de
datos de DICOM en un archivo junto con un directorio para indicar el contenido de
tales archivos. El formato de archivo incluye un área llamado Preámbulo de Archivo
que es visto primero por el dispositivo que lee el archivo.
Cada aplicación que necesita grabar archivos en un medio puede requerir medios
diferentes. Por ejemplo, la cardiologı́a necesita un medio de alta capacidad con acceso
rápido para pelı́cula de cine de 35 mm. Los especialistas de ultrasonidos no cardiacos,
sin embargo, probablemente no necesitarı́an tan alta capacidad, aunque ellos necesiten
r
GVA-ELAI-UPMPFC0075-2003
75
CAPÍTULO 2. EL ESTADO DE LA TÉCNICA
Fernando Ballesteros Herranz
capacidad de cine. Por esto, las partes 11 y 12 de DICOM definirán el Patrón de
intercambio de Medios a todos la a los niveles. Cada aplicación tendrá un perfil
de aplicación que será un corte vertical a través de todas las capas de DICOM.
De hecho, especificará para una aplicación determinada, las clases SOP, sintaxis de
transferencia, estructura de directorios, archivo básico senice, formato de medios, y el
formato de medio necesitado. Estos perfiles son necesarios en parte porque, aunque la
comunicación es sobre conexiones de red, la comunicación fuera de lı́nea por medios
inhibe el proceso de negociación.
Sin una duda, DICOM es de los más ambiciosos proyectos en imagen médica
emprendido por la industria y sociedades profesionales. Es un patrón complejo a
causa del tamaño de su contenido, pero es implementable y útil. El estándar ofrece
un balance correcto entre el objetivo pragmático de apoyo de rápida implementación
en productos actuales y una fundación modular sólida que asegura una capacidad
para evolucionar y responder a futuras necesidades. La cantidad de trabajo ya hecha
sobre DICOM es una parte de la razón del interés desde otras especialidades que usan
imágenes. Mediante el uso de la experiencia disponible en sociedades profesionales,
han podido definirse objetos informativos y los servicios. Estos pueden hacer uso de
la estructura de DICOM para la implementación.
DICOM se desarrolló con la idea de extensión y la expansión, que ya sucede. A
pesar de esto, no es la intención de los desarrolladores de DICOM dirigir toda la
informática médica. El énfasis, anotado en el nombre, está la imagen médica. Una
de las metas de los desarrolladores de DICOM es que otros deberı́an aprovechar el
trabajo ya hecho y los conceptos probados.
2.4.
Conclusiones
El estándar es un sistema de gestión de estudios e informes médicos sobre pacientes
muy útil para la organización de estos. Permite el poder realizar estudios de pacientes
que estén a largas distancias y poder intercambiar datos de estudios médicos entre
hospitales, clı́nicas, centros de investigación,. . .
Para estudiar el estándar a fondo hay que leer varias veces los conceptos, incluso
ası́ pueden haber dudas sobre ciertos temas que trata DICOM.
DICOM a medida que pasa el tiempo se va afianzando más en el campo de la
medicina digital, ya que es el mejor soporte para el intercambio de imágenes digitales
por la red.
76
r
GVA-ELAI-UPMPFC0075-2003
Capı́tulo 3
Librerı́as DCMTK de Offis
[KURA]
3.1.
Introducción
La tecnologı́a de la información y la comunicación poco a poco está llegando a ser
omnipresente en el cuidado de la salud. Los requerimientos para un rápido acceso a
los datos médicos en el momento necesario sólo se puede conseguir mediante los standards. El standard de DICOM facilita el intercambio y el procesamiento de imágenes
biomédicas de forma digital. Los aparatos de adquisición de imágenes, archivos de
imágenes y las estaciones de trabajo de diferentes vendedores, pueden estar conectadas en una infraestructura común e integradas con otros sistemas de información
(HIS/RIS). Nuevas oportunidades se alzan, no sólo dentro del hospital,si no también para el intercambio de información entre diferentes clı́nicas y entre hospitales y
centros de investigación.
3.2.
Estandarización de la Comunicación de Imagenes Médicas
Las tecnologı́as de información y comunicación de las imágenes médicas está cada
vez más presente en los dominios administrativos de los hospitales. La velocidad de los
avances en soportes tecnológicos están opuestos al requerimiento de una disponibilidad a largo plazo de datos médicos. El salvaguardar las inversiones para un número
apropiado de años es también un requisito indispensable dado el aumento de los costes
77
CAPÍTULO 3. LIBRERÍAS DCMTK DE OFFIS
Fernando Ballesteros Herranz
del sector de la medicina.
Estos requisitos pueden ser resueltos solamente con estándares. Desde que el sector
de medicina está distribuido y estructurado, la estandardización de interfaces desde
niveles bajos a niveles técnicos es de gran importancia, también para el desarrollo de
nuevos servicios, como por ejemplo la telemedicina.
Las siguientes organizaciones internacionales están desarrollando el estándar para
la medicina informática:
1. El Comité DICOM
El Comité DICOM ha publicado el estándar DICOM, que ha llegado a ser el
más importante estándar de las imágenes médicas.
2. Comité Europeo de Normalización
El Comité Técnico CEN/TC251 “Informática de la salud” es un Comité Europeo para la estandarización de modelos de información desarrollados por los
sistemas de información médica, estándar para el conocimiento de representaciones y terminologias, y para la seguridad y portección de las imágenes y procesamiento de señales en medicina.
3. Organización internacional para la estandarización
El Comité ISO ISO/TC215 “Informática de la salud” fue fundada en 1998 con
un alcance similar al de CEN/TC252, pero no limitado a Europa sólo. En este
Comité, los modelos para los sistemas de información médica, ası́ como los
estándares para el conocimiento de la representación, terminologı́a, seguridad
en medicina serán desarrollados, basado en parte en los estándares de CEN.
3.3.
Descripción de DICOM según Offis
La adquisición de imágenes por aparatos, datos de imágenes, estaciones de trabajo, etc. de diferentes vendedores se pueden conectar en una infraestructura común
integrada con otros sistemas de información.
DICOM facilita el intercambio y procesamiento de imágenes médicas en forma
digital, ası́ la información puede ser intercambiada entre hospitales, clı́nicas,. . .
DICOM es un estándar para una interoperatividad entre aparatos y aplicaciones,
es más que un sistema de intercambio de imágenes médicas:
Transmisión de imagenes, servicios de red.
78
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
3.3. DESCRIPCIÓN DE DICOM SEGÚN OFFIS
Formatos para el almacenamiento en intercambios.
Requiere conformidad entre aparatos y aplicaciones.
Estructuras de datos, formatos para las imágenes médicas digitales con sus datos
relacionados.
3.3.1.
Estructura de los datos en el estándar DICOM
Un archivo (objeto) DICOM consiste en una lista de datos-elementos (atributos),
que contienen imágenes relacionadas con información:
Paciente: nombre, sexo, fecha de nacimiento,. . .
Medio y procedimiento en la adquisición de la imágen: parámetros de aparatos,
calibración,. . .
Imágen: resolución,. . .
3.3.2.
Servicios de Red
Estos servicios de red están basados en el concepto de Cliente/Servidor. Antes de
que dos aplicaciones DICOM puedan intercambiar información, éstos deben establecer
la conexión y estar deacuerdo en los siguientes parámetros:
Quién es el cliente y quién es el servidor.
Qué servicios DICOM son usados.
En qué formato son transmitidos los datos (compresión-descompresión).
3.3.3.
Intercambio de medios de comunicación
Además de la comunicación de imágenes médicas sobre la red, el intercambio
de medios de comunicación se ha hecho hueco en DICOM que fue integrado en el
estándar en 1996. Los campos de aplicación son por ejemplo el almacenaje de pelı́culas
de angiografı́as en la cardiologı́a o el almacenaje de imágenes de ultrasonido. Para
asegurarse de que los medios de comunicación de almacenaje DICOM son realmente
intercambiables, el estándar define los llamados “perfiles de aplicación” que define:
r
GVA-ELAI-UPMPFC0075-2003
79
CAPÍTULO 3. LIBRERÍAS DCMTK DE OFFIS
Fernando Ballesteros Herranz
que modalidades de imágenes pueden estar presentes en el medio
que formatos de codificación y compresión pueden ser usados
que medio de almacenaje es usado
Cada medio DICOM contiene un llamado “DICOM directorio” además de los
archivos de imagen. Este directorio contiene la información más importante (el nombre
paciente, la modalidad, identificadores únicos, etc.) para todas las imágenes en el
medio. Esto permite hojear o buscar rápidamente a través de todas las imágenes del
medio sin tener que leer el archivo imagen completo.
3.3.4.
Declaración de Conformidad
DICOM requiere que una “Declaración de Conformidad” (Conformance Statement) sea escrita para cada dispositivo o aplicación desarrollada con DICOM. El
formato y el contenido de esta declaración son definidos en el estándar. Esto explica
que servicios DICOM y opciones son soportados, que extensiones y particularidades
han sido puestas en práctica por el vendedor, y como el dispositivo se comunica con
otros sistemas DICOM. En la teorı́a, comparando dos declaraciones de conformidad
permite determinar si dos dispositivos DICOM son capaces de comunicarse el uno
con otro. En la práctica, sin embargo, las declaraciones de conformidad son sólo comprensibles para expertos y son con frecuencia inadecuados.
DICOM ha llegado a ser un indispensable componente para la integración de
sistemas de imágenes digitales en medicina. DICOM ofrece soluciones para una multitud de comunicaciones relacinados con las aplicaciones. La palabra “DICOM” por
si misma no garantiza una integración “de enchufar y listo” de todos los sistemas de
información de un hospital. Esto requiere una combinación cuidadosa de todas las
soluciones parciales ofrecidas por DICOM.
3.4.
Librerı́as DCMTK
[ANDRE] [BATE] [CEBAL99] [CEBAL00] [KRUG]
DCMTK es una colección de librerı́as y aplicaciones que implementan partes del
estándar DICOM. DCMTK incluye el software necesario para el examen, la construcción y la conversión de archivos de imágen DICOM, manejando los medios de
comunicación, enviando y reciviendo imágenes sobre la conexión network, ası́ como la demostración de almacenaje de imágenes y bases de datos. Estas librerias
80
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
3.4. LIBRERÍAS DCMTK
son un completo código fuente y han sido escritas en una mezcla de ANSI C y
C++. El Toolkit del DCMTK es un software libre y se puede descargar de la página
(http://dicom.offis.de/dcmtk.php.en).
DCMTK ha sido usado en numerosas demostraciones DICOM como proovedor
central, vendedor independiente, almacenaje de imagen y servidores worklist. Es usado
por hospitales y empresas en todo el mundo para una amplia variedad de propósitos
desde ser una herramienta para pruebas de productos, a ser un componente básico
para proyectos de investigación, prototipos y productos comerciales.
El software DCMTK puede ser compilado bajo el Windows NT o una amplia gama
de sistemas operativos Unix que incluyen Linux, Solaris, OSF/1, IRIX, FreeBSD y
MacOS X. Todo lo necesario para la configuración y los makefiles son sumnirados. La
página oficial de Offis es www.offis.de
3.4.1.
Instalación de librerı́as
El archivo necesario para la instalación del Toolkit de Offis, depende del sistema operativo que estemos utilizando, si es Windows el archivo a descargar es
dcmtk351.zip, y si es un sistema UNIX es dcmtk351.tar.gz. La instalación descrita
está basada en el sistema Windows, bajo el entorno Visual C++.
Para realizar la instalación de DCMTK hay que seguir unos pasos:
1. Se descomprime el archivo dcmtk351.zip, previamente descargado de la página
www.offis.de
2. Se abre el proyecto dcmtk.dsp, que se encuentra en X:\. . . \Toolkit\source\dcmtk
y se compila y linka con el Visual C++ 6, lo que genera los archivos .obj y las librerı́as (.lib) en la carpeta “OpenSSL” que hay en cada carpeta de las funciones
existentes en este Toolkit, las cuales pueden ser utilizadas en otros proyectos
incluyendolas en ellos.
3. Para poder generar los ejecutables de cada función, hay que incluir los ficheros de
cabezeras (.h) al Visual C++ 6. Aquı́ pinchando en Tools->Options->Directories>Include files, se pueden incluir todos .h del Toolkit, tan solo poniendo el Path
en el que se encuentran, por ejemplo: C:\Archivos de programa\Microsoft Visual Studio\My Proyect\dcmtk351\dcmtk\dcmnet\include.
4. También es necesario dar el path donde se encuentran los .lib, que se hace
pinchando en Tools->Options->Directories->Library files, y se incluye el path.
De esta forma se incluyen los .lib y .h de forma permanente en el visual.
r
GVA-ELAI-UPMPFC0075-2003
81
CAPÍTULO 3. LIBRERÍAS DCMTK DE OFFIS
Fernando Ballesteros Herranz
5. Para incluir las librerı́as en los proyectos hacer click en Proyect->Settings->Link,
y escribir la librerı́a a incluir (por ejemplo: dcmnet.lib) antes de /nologo. De esta
forma si queremos generar el ejecutable de un fuente lo compilamos y linkamos.
Este Toolkit tiene diferentes funciones basadas en el estándar Dicom. Las funciones
son agrupadas en carpetas dependiendo de la función que desempeñen. Vease la figura
3.1.
Config: Incluye los ficheros .h necesarios para la configuración del toolkit.
Dcmdata: Contiene funciones para el tratamiento de los datos de los archivos
Dicom y Data Sets.
Dcmimage: Fuciones para el tratamiento de los datos de los pixel de una imagen.
Sólo para imágenes Dicom sin comprimir.
Dcmimgle: Sirven para el tratamiento de la luminosidad de las imágenes.
Dcmjpeg: Son funciones para la compresión/descompresión de imágenes DICOM
a JPEG.
Dcmnet: Funciones para el transporte de los archivos Dicom a través de la Red.
Dcmpstat: Funciones para el tratamiento de escalas de grises y estados de presentación
Dcmsing: Para la creación o supresión de una firma digital para un archivo
Dicom y su verificación.
Dcmsr: Para la conversión de documentos Dicom SR (Structured Reporting) a
HTML, XML .
Dcmtls: Para la transmisión segura de archivos Dicom por la Red.
Imagectn: Para el registro de archivos en una base de datos.
Wlistctn: Para implementar un SCP como una Base de Datos.
Nos centraremos en las funciones para el transporte de archivos y la compresión
a Jpeg.
82
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
3.4. LIBRERÍAS DCMTK
Figura 3.1: Librerı́as DCMTK
3.4.2.
Dcmnet
Esta carpeta tiene las funciones para la conexión entre varias máquinas para crear
una asociación entre ellas y poder transmitir los datos de los objetos DICOM.
Echoscu: Esta aplicación implementa un Service Class User (SCU) para la verificación SOP Class. Envı́a un mensage Dicom C-ECHO a un Service Class
Provider (SCP) y espera una respuesta.
Findscu: Esta aplicación implementa un Service Class Query/Rerieve (petición/recuperación) y un Service Class Basic Worklist Management. Sólo soporta
el mensage Dicom C-FIND, que envı́a una petición al SCP y espera respuesta.
Movescu: Esta aplicación implementa un SCP para el Service Class Query/Retrieve
y un SCU para el Storage Service Class. Para usar la funcionalidad Retrieve
(Recuperación) usa el mensage Dicom C-MOVE que envı́a una petición al SCP y
espera respuesta. El SCP aceptará la asociación para recibir imágenes enviadas
como resultado de la petición C-MOVE. El término MOVE es poco apropiado,
ya que lo que hace es una copia de la imagen, la imagen nunca se borra del SCP.
Storescp: Implementa un Service Class Provider (SCP) para el Storage Service Class. Se pone a la escucha sobre un especı́fico puerto TCP/IP, para las
peticiones de asociación que puedan llegar de un Storage SCU y puede recibir
imágenes según el Storage Service Class.
Storescu: Implementa un Service Class User (SCU) para el Storage Service
r
GVA-ELAI-UPMPFC0075-2003
83
CAPÍTULO 3. LIBRERÍAS DCMTK DE OFFIS
Fernando Ballesteros Herranz
Class. Se usa para transmitir imágenes Dicom. Envı́a un mensage C-STORE a
un Storage SCP y espera respuesta.
Aplicación para ver la conectividad entre dos máquinas
Esta aplicación es realizada sobre dos máquinas, una será Galileo que actuará de
SCP y otra será Gauss que será el SCU. Pondremos la opción -v la cual nos dirá en
todo momento que asociación se está realizando, dando detalles sobre ella.
Paso 1o : Se realiza una aplicación Dicom Storage/Verification Service Class Provider.
Un puerto se pone a la escucha (el puerto 104 es el más utilizado en Dicom) para la
llegada de asociaciones.
Galileo:\ storescp -v 104
Paso 2o : La siguiente instrucción es para comenzar una aplicación Dicom Verification Service Class User. Esto intenta construir una asociación Dicom con una aplicación que corra sobre Galileo, conectándolos por el puerto 104. Gauss enviará una
petición C-ECHO y estará a la espera de una respuesta C-ECHO de Galileo. Esto es
sólo para verificar que hay conexión entre las dos máquinas.
Gauss:\ echoscu -v Galileo 104
Paso3o : Se envı́a una imagen Dicom a Galileo (SCP), volviendo a intentar realizar
una asociación Dicom con una aplicación que corra sobre Galileo. Es enviada una
petición C-STORE que contiene una imagen Dicom “craneo.dcm” y se espera una
respuesta C-STORE de Galileo.
Gauss:\ storescu -v Galileo 104 craneo.dcm
La imagen es guardada en el lugar de trabajo donde se esté realizando la escucha
del puerto 104. Por ejemplo si se hace en un fichero C:\Dicom, la imagen es guardada
en ese fichero. El nombre que tiene la nueva imagen copiada en Gauss, es a priori su
UID, que es único entre todas las imáges DICOM quetiene la máquina.
84
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
3.4.3.
3.4. LIBRERÍAS DCMTK
Dcmjpeg
Esta carpeta tiene las funciones para la compresión con y sin pérdidas de imágenes
jpeg.
Dcmcjpeg: Realiza la compresión de una imagen DICOM a una imagen JPEG.
Dcmdjpeg: Descomprime la imagen DICOM comprimida como JPEG.
Dcmj2pnm: Lee una imagen DICOM y convierte los datos de los pixel según
las opciones del procesamiento de imágenes seleccionadas, PPM/PGM, BMP,
TIFF o JPEG.
Dcmmkdir: Crea un archivo DICOMDIR de los archivos DICOM especificados
según la aplicación Media de almacenaje.
3.4.4.
DicomScope
El DicomScope es un programa desarrollado en C++ con un GUI en Java, utiliza
las funciones DICOM dadas por las librerı́as DCMTK. Permite visualizar, imprimir,
almacenar, transmitir y recibir estudios, imágenes, estados de presentación1 e informes
estructurados2 . Los informes estructurados (SR) consisten en informes completos de
diagnóstico y resultados de un examen en particular.
La aplicación tiene cuatro partes principales:
Browser (Navegador de estudios): El cual es la base de datos local de la aplicación donde se encuentran los estudios (imágenes, structured reports,...) de la
aplicación.
Viewer: Para tratar y mostrar imágenes Dicom, imágenes de escalas de grises,
estados de presentación e informes estructurados.
Print: Administra e incluye los estudios para su impresión.
Process log: Muestra los procesos que se han llevado a cabo en la transmisión
de archivos Dicom.
1
2
Presentation states
Structured Reports
r
GVA-ELAI-UPMPFC0075-2003
85
CAPÍTULO 3. LIBRERÍAS DCMTK DE OFFIS
Fernando Ballesteros Herranz
Instalación
Es necesario para la instalación un sistema compatible con Java y Windows 32
bits, para esto ha y que descargar de internet la Máquina Virtual de Java. Antes de la
instalación del DicomScope es necesaria la instalación de Java 2 SDK o JRE(Java 2
Runtime Environment), para conseguir esto, se puede bajar de la página www.offis.de.
Una vez realizada esta tarea tan solo hay que ejecutar Setup y seguir las instrucciones
dadas.
Browser
Es la base de datos del DicomScope donde se almacenan los estudios Dicom. Tiene
una estructura de árbol en la que cada estudio es una rama, y puede tener varias ramas
a su vez, puede tener imágenes, informes estructurados, imágenes de escalas de grises
y estados de presentación.
Figura 3.2: Base de Datos
Los nuevos estudios recibidos por Red o almacenados en la aplicación, se diferencian de los otros porque aparece un sı́mbolo de“New” a su izquierda, una vez
visualizados éstos, perderán el sı́mbolo. Figura 3.2
Para enviar estudios a otra máquina, se elige el estudio que se quiere enviar y se
presiona la tecla send, entonces se abre una ventana en la que hay que se elige la
forma de enviar los estudios. Hay tres formas:
86
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
3.4. LIBRERÍAS DCMTK
1. Transmisión insegura, sin protección de los datos en tránsito.
2. Transmisión TLS3 , en la que se utilizan certificados para la transmisión de
datos.
3. Transmisión TLS y encriptación.
Para poder configurar a que máquinas son enviados los estudios y que puerto
se utiliza para la asociación, se hace mediante el archivo “DICOMscope.cfg” que se
encuentra en X:\. . . \DICOMscope351, escribiendo a que hostname quiere ser enviado
y el port.
Este archivo DICOMscope.cfg, es un archivo de configuración, en el que se puede
configurar todo lo relacionado con el DicomScope como la impresora que se va a usar,
la certificación, nombre de usuario,. . . pero lo más importante es la configuración de
la transmisión de datos por la red. Con ello se puede variar el tı́tulo de la asociación
para la conexión entre máquinas, el hostname al que se van a enviar los objetos
Dicom, el puerto a utilizar en la comunicación, si se utiliza el soporte TLS para una
comunicación segura, etc.
Una cuestión importante en los archivos de configuración es que las lı́neas que
empiezan por # son comentarios y éstas no son consideradas para la configuración de
la aplicación. Vease figura 3.3
Figura 3.3: Archivo de configuración de DicomScope
La configuración realizada para la transmisión de datos de Gauss a Galileo es
como sigue a continuación:
3
Transport Layer Security
r
GVA-ELAI-UPMPFC0075-2003
87
CAPÍTULO 3. LIBRERÍAS DCMTK DE OFFIS
Fernando Ballesteros Herranz
GAUSS
Type = Storage
Aetitle = Storage
Hostname = Galileo
MaxPDU = 32768
Port = 10004
ImplicitOnly = false
DisableNewVRs = false
Figura 3.4: Viewer
GALILEO
Type = Storage
Aetitle = Storage
Hostname = Gauss
MaxPDU = 32768
Port = 10004
ImplicitOnly = false
DisableNewVRs = false
BitPreservingMode = false
Viewer
Todas las instancias Dicom que se carguan, pasan a verse en el Viewer. Es una herramienta para tratar las imágenes Dicom y cambiar y editar informes estructurados,
88
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
3.4. LIBRERÍAS DCMTK
incluso para verificarlos y crear firmas digitales. Ver figura 3.4
Print
Pueden ser enviadas imágenes Dicom a imprimir desde el Browser o la imagen
que se visualiza en el Viewer. Esto lleva la imagen al Print en el que se visualiza la
imagen que se va a imprimir. Figura 3.5
Figura 3.5: Print
Process Log
Se pueden ver los procesos se producen en la transmisión de archivos Dicom. Al
iniciar el DicomScope se ve que hay dos procesos que están realizándose. Figura 3.6
Uno es para que el DicomScope sirva como receptor de instancias Dicom con
transmisión insegura, sin utilizar TLS. Este proceso utiliza la orden C-STORESCP,
con esto recibe y guarda en la base de datos los archivos Dicom mandados a
este equipo, utilizando el puerto 10004.
El otro proceso recibe las instancias Dicom utilizando TLS, de esta forma la
transmisión de datos es segura. También utiliza la orden C-STORESCP y el
puerto elegido es el 10007.
r
GVA-ELAI-UPMPFC0075-2003
89
CAPÍTULO 3. LIBRERÍAS DCMTK DE OFFIS
Fernando Ballesteros Herranz
Figura 3.6: Process Log
3.5.
Conclusiones
Las librerı́as desarrolladas por Offis, implementan un gran número de funciones
del estándar DICOM. Son unas librerı́as utilizadas por un gran número de personas
que están desarrollando aplicaciones con el estándar.
La gran ventaja de estas librerı́as es que son un producto “freeware”, es decir, que
son un producto gratuito.
Estas librerı́as están desarrolladas enteramente en C/C++ y no es código fácil el
que implementan, por esto es muy difı́cil trabajar con estas librerı́as ya que hay que
añadirle que se trabaja basandose en DICOM que es un estándar que hay que leer
varias veces para poder entenderlo completamente.
Son muy útiles para gente experta en C++ y Dicom, pero de lo contrario si se
intenta trabajar con estas librerı́as sin reunir uno de los dos requisitos puede llegar a
ser muy pesado.
90
r
GVA-ELAI-UPMPFC0075-2003
Capı́tulo 4
Programación en JAVA
[BOBA00] [BOBA01] [LEMA] [PAJ] [JDK]
4.1.
Introducción
Java surgió en 1991 cuando un grupo de ingenieros de Sun Microsystems trataron
de diseñar un nuevo lenguaje de programación destinado a electrodomésticos. Debido
a la existencia de distintos tipos de CPUs y a los continuos cambios, era importante
conseguir una herramienta independiente del tipo de CPU utilizada. Se ejecuta sobre
una “máquina hipotética o virtual” denominada Java Virtual Machine (JVM)1 . Es
la JVM quien interpreta el código neutro convirtiéndolo a código particular de la
CPU utilizada. Cualquier aplicación que se desarrolle “cuelga” (o se apoya, según
como se quiera ver) en un gran número de clases preexistentes (el API o Application
Programming Interface de Java).
La ejecución de programas en Java tiene muchas posibilidades: ejecución como
aplicación independiente (Stand-alone Application), ejecución como applet, ejecución
como servlet, etc.. Un applet es una aplicación especial que se ejecuta dentro de un
navegador o browser (por ejemplo Netscape Navigator o Internet Explorer) al cargar
una página HTML desde un servidor Web. El applet se descarga desde el servidor y
no requiere instalación en el ordenador donde se encuentra el browser. Un servlet es
una aplicación sin interface gráfica que se ejecuta en un servidor de Internet.
Java permite fácilmente el desarrollo tanto de arquitecturas cliente-servidor como
de aplicaciones distribuidas, consistentes en crear aplicaciones capaces de conectarse
a otros ordenadores y ejecutar tareas en varios ordenadores simultáneamente.
1
Máquina Virtual de Java
91
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
Figura 4.1: Evolución de Java
En definitiva Java es un lenguaje de programación orientado a objetos, interpretado, independiente de la arquitectura y portable, fuertemente tipado, con gestión
automática de la memoria (recogida de basura), con gestión de excepciones y concurrencia (multihilo) y principalmente con las caracterı́sticas de encapsulación, herencia
y polimorfismo.
El lenguaje Java es un lenguaje sencillo extendido mediante una serie de bibliotecas
o packages (paquetes), entre ellos los más comunes son:
Package lang: clase con funcionaliddes básicas. E/S, excepciones, hilos.
Package util: Utilidades (números aleatorios, vectores).
Package net: Conectividad y trabajo con redes.
Package applet: Desarrollo de aplicaciones ejecutables en navegadores.
Package awt y swing: Desarrollo de interfaces gráficas de usuario.
4.2.
Instalación de la JVM
Hay dos instalaciones posibles de la JVM, o bien la instalación del JRE2 , la cual
sirve para que se puedan ejecutar las apliaciones desarrolladas en Java pero no posee
2
92
Java Runtime Environment
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.2. INSTALACIÓN DE LA JVM
Figura 4.2: Bibliotecas de clases de Java
compilador para los ficheros fuente, o bien la instalación del SDK que si tiene compilador para desarrollar aplicaciones.
Para el desarrollo de aplicaciones en Java, la instalación debe comprender el SDK
que es un software libre y puede ser descargado de http://java.sun.com. Al instalar
el SDK, se crea una carpeta en el directorio raı́z (j2sdk1.4.1_03)3 , y dentro de esta
hay otra llamada “bin” que es la que contiene el compilador.
El siguiente paso es dar el PATH al compilador y crear un CLASSPATH que
contenga las librerı́as que vaya a utilizar el compilador. Los pasos a seguir difieren
dependiendo del sistema operativo que se utilize.
Los pasos a seguir en un sistema Windows de red (NT,2000,XP):
1. Pinchar en Inicio->Configuración->Panel de Control->Sistema, ir a la pestaña
Avanzado y click en Variables de Entorno.
2. En variables del sistema ir a la variable Path y escribir seguido a lo que haya el
camino a seguir hasta la carpeta bin del SDK:
C:\J2SDK1.4.1_03\BIN;
3. Para crear el Classpath, en variables del sistema dar a “Nueva. . . ” y escribir en
nombre de variable:
CLASSPATH
y en valor de variable el camino hasta la carpeta lib donde está dt.jar que son
las clases del JDK:
C:\j2sdk1.4.1_03\lib\dt.jar;.;
3
Para la versión 1.4.1
r
GVA-ELAI-UPMPFC0075-2003
93
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
el valor de ;.; es para poder compilar cualquier fichero fuente desde cualquier
directorio y no deba ser desde el directorio donde está el compilador.
Los pasos a seguir en un sistema Windows´9X o MSDOS:
1. Abrir el fichero Autoexec.bat que se encuentra en el directorio Raı́z del sistema,
pinchando en él con el botón derecho del ratón y dejando pulsada la tecla Shift,
de esta forma sale el menú contextual con la opción “Abrir con. . . ”, se pincha
esta opción y se elige un editor de texto (por ejemplo el WordPad).
2. Una vez abierto en la lı́nea de SET PATH hay que incluir la carpeta del compilador:
SET PATH = . . . ;C:\J2SDK1.4.1-_03\Bin; %PATH %
3. Crear el CLASSPATH y dar le localización de las librerı́as del JDK, para ello
escribir debajo del PATH:
SET CLASSPATH = C:\j2sdk1.4.1_03\lib\dt.jar;.; %CLASSPATH %
4.3.
El compilador de Java
Es una herramienta del JDK o SDK4 , el JRE no compila. Realiza un análisis
del sintaxis del código escrito en los ficheros fuente de Java (con extensión *.java). Si no encuentra errores en el código genera los ficheros compilados (con extensión *.class).En el JDK de Sun dicho compilador se llama javac.exe. Java.exe es el
intérprete para sistemas PC/Windows. Appletviewer.exe es un visualizador de applets.
Una vez compilado no deberı́a ser necesaria ninguna modificación por el hecho
de cambiar de procesador o de ejecutarlo en otra máquina. La clave consistió en
desarrollar un código “neutro” el cual estuviera preparado para ser ejecutado sobre
la JVM.
Para realizar una aplicación con el compilador del SDK, se debe escribir el código
en Java en un editor de texto cualquiera como puede ser el “Bloc de Notas”. Una vez
escrito debe ser guardado el fichero con extensión .java, por ejemplo nombre.java. La
compilación debe realizarse con un “shell” de comandos, como el del MSDOS. Para
realizar la compilación escribir:
4
94
JDK para las antiguas versiones y SDK para las nuevas versiones
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.4. VARIABLES Y TIPOS DE DATOS
X:\. . . \javac nombre.java
Con la compilación se genera un archivo .class, en este caso serı́a nombre.class.
Después ya se puede ejecutar o interpretar, para esto escribir en el Shell:
X:\. . . \java nombre
Todo ello se realiza en el directorio donde se encuentre el fichero fuente .java. Ver
figura 4.3
Figura 4.3: Compilación y ejecución
Java Sun ha realizado un API para la ayuda y consulta de las clases que se
pueden utilizar con el SDK. Esta ayuda es de importancia vital para el buen uso y
comprensión de java. Ver http://java.sun.com
4.4.
4.4.1.
Variables y tipos de datos
Comentarios
Permiten documentar el código haciéndolo más legible a los progamadores.
//Comentario de una sola lı́nea
/* Comentario que
aparece en varias lı́neas*/
r
GVA-ELAI-UPMPFC0075-2003
95
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
4.4.2.
Fernando Ballesteros Herranz
Identificadores
Los identificadores se utilizan como nombres de clase, método y variable. Un identificador puede ser cualquier sentencia descriptiva de letras en mayúscula o minúscula,
números y los sı́mbolos (_) y ($). Java diferencia entre mayúsculas y minúsculas, lo
que significa que “VALOR” es un identificador diferente de “Valor”.
4.4.3.
Palabras clave reservadas
Las palabras clave reservadas son identificadores especiales que el lenguaje Java
se ha reservado para controlar cómo está definido su programa. Se utilizan para identificar los tipos, modificadores y mecanismos para control de secuencia incorporados.
Estas palabras clave sólo se pueden utilizar para su propósito original y no se pueden
utilizar como identificadores de nombres de variable, clase o método.Véase la lista 4.4
Figura 4.4: Palabras clave de Java
4.4.4.
Variables
La variable es la unidad básica de almacenamiento en un programa en Java. Una
variable se define mediante la combinación de un identificador, un tipo y un ámbito.
La forma básica de una declaración de variable es:
tipo identificador [ = valor ] [, identificador [ = valor ] ... ] ;
El tipo puede ser: byte, short, int, long, char, float, double, boolean o el nombre
de una clase o interfaz.
96
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.4. VARIABLES Y TIPOS DE DATOS
Los bloques de sentencias compuestas en Java se delimitan con dos llaves . Las
variables de Java sólo son válidas desde el punto donde están declaradas hasta el final
de la sentencia compuesta que la engloba. Se pueden anidar estas sentencias compuestas y cada una puede contener su propio conjunto de declaraciones de variables
locales. Sin embargo, no se puede declarar una variable con el mismo nombre que una
de un ámbito superior.
Tipos
Enteros que son todos los tipos numéricos de Java son valores con signo. Esta
ausencia de signo reduce el número de tipos de entero a cuatro:
• byte es un tipo de 8 bits con signo. Su rango comprende desde -128 a 127.Su
declaración puede ser:
byte b;
byte c = 0x55;
• short es un tipo de 16 bits con signo. Su rango comprende desde -32768 a
32767. Declaración:
short s;
short t = 0x55aa;
• int es un tipo de 32 bits con signo. Su rango comprende desde -2.147.483.648
a 2.147.483.647. Es el tipo más utilizado habitualmente para almacenar
valores enteros simples.
int n;
int m = 10;
• long es un tipo de 64 bits con signo. Hay algunas ocasiones en las que
un tipo int no es lo suficientemente grande como para guardar un valor
deseado.
long j;
Los números en coma flotante, también conocidos como números reales en otros
lenguajes, se utilizan cuando se calculan funciones que requieren precisión fraccionaria. Hay dos clases de tipos en coma flotante, float y double:
• float utiliza 32 bits para almacenar un valor.
float a;
float b = 10.5;
• double utiliza 64 bits para almacenar un valor.
double p;
Lógico o booleano, utiliza 1 bit, y sólo puede tener dos valores TRUE o FALSE
r
GVA-ELAI-UPMPFC0075-2003
97
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
boolean p;
Caracteres, dado que Java utiliza Unicode para representar los caracteres de
una cadena, el tipo char es de 16 bits sin signo.
char a = ’h’;
Conversiones
Hay situaciones en las cuales se tiene un valor de un tipo dado y se desea almacenar
ese valor en una variable de un tipo diferente. En algunos tipos es posible almacenar
simplemente el valor sin una conversión de tipos; lo que se denomina conversión
automática. Esto sólo es posible en Java si el compilador reconoce que la variable
destino tiene la suficiente precisión para contener el valor origen, como almacenar un
valor byte en una variable int. A esto se le llama ensanchamiento o promoción, dado
que el tipo más pequeño se ensancha o promociona al tipo compatible más grande. Si
por el contrario, se desea asignar un valor de variable int a una variable byte se necesita
realizar una conversión de tipos explı́cita. A esto se le llama estrechamiento, dado que
se estrecha explı́citamente el valor para que quepa en el destino. La conversión de un
tipo se realiza poniendo delante un nombre de tipo entre paréntesis.
int a = 100;
byte b = (byte) a;
4.4.5.
Matrices o vectores
Las matrices son un tipo especial que agrupa un conjunto de variables del mismo
tipo. Si se desea crear una matriz de doce enteros, se crea un tipo especial, que es
una “matriz de int”.
int days[];
Para las matrices, hay un valor especial llamado null, que representa una matriz sin
ningún valor. Se debe utilizar un operador especial, “new” (nuevo), para asignar el
espacio de una matriz. Para utilizar el operador “new” se debe promocionar un tipo
y un número entero no negativo de elementos a asignar.
days = new int[12];
98
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.5.
4.5. OPERADORES
Operadores
Los operadores de Java son caracteres especiales que le dicen al compilador que
se desea realizar una operación sobre algunos operandos.
4.5.1.
Operadores aritméticos
Los operadores aritméticos se utilizan para operaciones matemáticas, exactamente
de la misma manera en la que están definidos en álgebra. Los operandos deben ser
tipo numérico. No se pueden utilizar estos operadores con tipos “boolean”, pero se
pueden utilizar con tipos “char”, dado que el tipo “char” en Java es un subconjunto
de “int”.
Suma: +
Resta: Multiplicación: *
División: /
Resto: %
Operadores aritméticos unitarios
Preincremento: ++x
Postincremento: x++
Predecremento: - -x
Postdecremento: x- -
4.5.2.
Operadores de asignación
normal: x = y
adicción: x+=y ó x=x+y
resta: x-=y ó x=x-y
multiplicación: x*=y ó x=x*y
división: x/=y ó x=x/y
r
GVA-ELAI-UPMPFC0075-2003
99
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
4.5.3.
Fernando Ballesteros Herranz
Operadores a nivel de bit
Los tipos numéricos enteros, long, int, short, char y byte tienen un conjunto adicional de operadores que pueden modificar e inspeccionar los bits que componen sus
valores.
El operador NOT unario, ~, invierte todos los bits de su operando.
El operador AND, &, combina los bits de manera que se obtiene un 1 si ambos
operandos son 1, obteniendo 0 en cualquier otro caso.
00101010 42
& 00001111 15
= 00001010 10
El operador OR, |, combina los bits de manera que se obtiene un 1 si cualquiera
de los operandos es un 1.
00101010 42
| 00001111 15
= 00101111 47
El operador XOR, ^, combina los bits de manera que se obtiene un 1 si cualquiera
de los operandos es un 1, pero no ambos, y cero en caso contrario.
El operador desplazamiento a la izquierda, ((, mueve hacia la izquierda todos los
bits del operando de la izquierda un número de posiciones de bit especificado
en el operando de la derecha. Al realizarse el desplazamiento se pierden por el
extremo izquierdo del operando el número de bits desplazados y se rellena el
operando con ceros por la derecha el mismo número de bits.
))
El operador desplazamiento a la derecha, )), mueve hacia la derecha todos los
bits del operando de la izquierda un número de posiciones de bit especificado
por el operando de la derecha.
4.5.4.
Operadores relacionales
Para comparar dos valores, Java tiene el siguiente conjunto de operadores relaciónales
que describen igualdad y ordenamiento. Ver figura 4.5
100
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.6. CONTROL DEL FLUJO
Figura 4.5: Operaderes relacionales
4.5.5.
Operadores lógicos booleanos
Todos los operadores lógicos booleanos combinan dos valores boolean para dar
como resultado un valor boolean. Ver 4.6
Figura 4.6: Operaderes lógicos booleanos
4.6.
Control del flujo
El control del flujo es la manera que tiene un lenguaje de programación de provocar
que el flujo de la ejecución avance y se ramifique en función de los cambios de estado
de los datos.
4.6.1.
Instrucción condicional if-else
La construcción “if-else” provoca que la ejecución atraviese un conjunto de estados
boolean que determinan que se ejecuten distintos fragmentos de código.
r
GVA-ELAI-UPMPFC0075-2003
101
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
if ( expresión-booleana ) sentencia1; [ else sentencia2; ]}
La cláusula else es opcional. Cada una de las sentencias puede ser una sentencia
compuesta encerrada entre llaves, { }. Una expresión-booleana es cualquier expresión que devuelve un valor boolean. Podrı́a ser una variable simple declarada como
boolean.
boolean datosdisponibles;
if (datosdisponibles)
ProcesarDatos();
else
esperarAMasDatos();
4.6.2.
Instrucción condicional switch
La sentencia switch proporciona una forma limpia de dirigir la ejecución a partes
diferentes del código en base al valor de una variable o expresión. Esta es la forma
general de la sentencia switch:
switch ( expresión ){
case valor1:
instrucciones;
break;
case valor2:
instrucciones;
break;
default:
}
El valor de expresión se compara con cada uno de los valores literales de las sentencias case. Si coincide con alguno, se ejecuta el código que sigue a la sentencia case.
Si no coincide con ninguno de ellos, entonces se ejecuta la sentencia default (por defecto). La sentencia default es opcional. La sentencia break, comentada anteriormente,
hace, en este caso, que la ejecución salte al final del switch. Si no se pone el break, la
ejecución continuará en el siguiente case. . La sentencia “break” de Java está diseñada
para cubrir aquellos casos en los que saltar arbitrariamente a una porción de código
es una constucción valiosa y legı́tima para el control del flujo. El término break se
refiere al acto de salirse de un bloque de código. Le dice al intérprete que retome la
ejecución pasado el final del bloque.
102
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.6.3.
4.6. CONTROL DEL FLUJO
Bucles
Un bucle es lo que llamamos ejecutar repetidamente el mismo bloque de código
hasta que cumpla una condición de terminación. Hay cuatro partes en cualquier bucle,
inicialización, cuerpo, iteración y terminación . La inicialización es el código que
establece las condiciones iniciales de un bucle. El cuerpo es la sentencia que queremos
repetir. La iteración es el código que queremos ejecutar después de cuerpo, pero antes
de entrar de nuevo en el bucle. Se utiliza a menudo para incrementar o decrementar
contadores e ı́ndices. La terminación es la expresión booleana que comprueba cada
vez a lo largo de un bucle para ver si ha llegado el momento de parar de iterar. Java
tiene tres construcciones para bucles: while, do-while y for.
Bucle while
Ejecuta una sentencia repetidamente mientras una expresión booleana sea verdadera. Esta es su forma general:
[ inicialización; ]
while ( terminación ) {
cuerpo;
[ iteración; ]
}
Las partes inicialización e iteración son opcionales, y mientras la expresión terminación devuelva un valor “true”, la sentencia cuerpo continuará ejecutándose.
Bucle do-while
La contrucción “do-while” se utiliza cuando se desea ejecutar el cuerpo de un
bucle while al menos una vez, incluso si la expresión booleana tiene el valor false la
primera vez. Es decir si se desea evaluar la expresión de terminación al final del bucle
en vez de al principio como en el while.
[ inicialización; ]
do { cuerpo; [ iteración; ] } while ( terminación );
r
GVA-ELAI-UPMPFC0075-2003
103
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
Bucle for
La sentencia “for” es una forma compacta de expresar un bucle.
for ( inicalización; terminación; iteración ) cuerpo;
Si las condiciones iniciales no provocan que la terminación devuelva true la primera
vez, entonces la sentencia cuerpo e iteración no se ejecutarán nunca. Ejemplo de un
bucle for:
for (int i = 1; i <= 10; i++)
System.out.println(‘‘i = ’’ + i);
4.6.4.
Otras instrucciones
return
Java utiliza una forma de subrutina llamada método para implementar una interfaz de procedimiento a las clases de objetos. En cualquier momento dentro de un
método, se puede utilizar la sentencia “return” para que la ejecución salte y vuelva al
punto donde se llamó al método. Se utiliza para acarbar los métodos. Si es un método
void, la sentencia serı́a:
return;
continue
Del mismo modo que se desea salir prematuramente de un bucle (con “break”),
se podrı́a desear continuar en el bucle, pero dejar de procesar el resto de código en
esta interación en concreto. La sentencia continue de Java salta del cuerpo de bucle,
pero permaneciendo en el bucle.
for (int i = 0; i < 10; i++){
System.out.print(i + ‘‘ ’’);
if (i % 2 == 0)
continue;
System.out.println(‘‘ ’’);
}
104
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.7.
4.7. CLASES
Clases
El elemento básico de la programación orientada a objetos en Java es un clase.
Una clase define la forma y el comportamiento de un objeto. Cualquier concepto que
desee representar en su programa en Java está encapsulado en una clase. Para crear
una clase sólo se necesita un archivo fuente que contenga la palabra clave class seguida
de un identificador legal y un par de llaves para el cuerpo.
class punto{
}
Las clases de Java tı́picas incluirán variables y métodos de instancia. Los programas
en Java completos constan por lo general de varias clases de Java de distintos archivos
fuente. Una clase define la estructura de un objeto y su interfaz funcional, conocida
como métodos. Cuando se ejecuta un programa en Java, el sistema utiliza definiciones
de clase para crear instancias de las clases, que son objetos reales. La forma general
de una clase se muestra a continuación.
class nombre_de_clase extends nombre_de_superclase {
type variable_de_instancia1;
type variable_de_instancia2;
type variable_de_instanciaN;
type nombre_de_método1 (lista_de_parámetros) {
cuerpo_del_método;
}
type nombre_de_método2 (lista_de_parámetros) {
cuerpo_del_método;
}
type nombre_de_métodoN (lista_de_parámetros) {
cuerpo_del_método;
}
}
Aquı́, nombre_de_clase y nombre_de_superclase son identificadores. La palabra
clave “extends” se utiliza para indicar que nombre_de_clase será una subclase de
nombre_de_superclase. Hay una clase incorporada, llamada “Object” (objeto), que
está en la raı́z de la jerarquı́a de clases de Java. Si se desea realizar una subclase de
Object directamente, se puede omitir la cláusula extends.
r
GVA-ELAI-UPMPFC0075-2003
105
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
4.7.1.
Fernando Ballesteros Herranz
Referencias a objetos
Cada nueva clase que se crea añade otro tipo que se puede utilizar igual que los
tipos simples. Por lo tanto, cuando se declara una nueva variable, se puede utilizar un
nombre de clase como tipo. A estas variables se las conoce como referencias a objeto.
A cada instancia se le puede llamar también objeto. Cuando se declara que el
tipo de una variable es una clase, tiene como valor por omisión el “null”, que es una
referencia al tipo “Object”, y, por lo tanto, es compatible en tipo con todas las otras
clases. El objeto “null” no tiene valor; es distinto del entero 0, igual que el “false” de
boolean. Este ejemplo declara una variable p cuyo tipo es de la clase Point.
Point p; //Aquı́ la variable p tiene un valor null.
4.7.2.
Variables de una instancia
Los datos se encapsulan dentro de una clase declarando las variables dentro de las
llaves de apertura y cierre de la declaración de la clase. A las variables que se declaran
en este ámbito y fuera del ámbito de un método concreto se las conoce como variables
de instancia. Este ejemplo declara una clase de nombre Point, con dos variables de
instancia enteras llamadas x e y.
class Point {
int x, y;
}
4.7.3.
Operador new
El operador new crea una única instancia de una clase y devuelve una referencia a
ese objeto. Aquı́ se crea una nueva instancia de Point y se almacena en una variable
p.
Point p = new Point();
Aquı́ p referencia a una instancia de Point, pero realmente no lo contiene. Se
pueden crear múltiples referencias al mismo objeto.
106
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.7. CLASES
Point p = new Point();
Point p2 = p;
4.7.4.
Operador(.)
El operador punto se utiliza para acceder a las variables de instancia y los métodos
contenidos en un objeto. Esta es la forma general de acceder a las variables de instancia
utilizando el operador punto.
p.x = 10;
p.y = 20;
System.out.println("x = " + p.x + " y = " + p.y);
4.7.5.
Declaración de métodos
Los métodos son subrutinas unidas a una definición de una clase especı́fica. Se
declaran dentro de una definición de clase al mismo nivel que las variables de instancia.
Se debe llamar a los métodos en el contexto de una instancia concreta de esa clase.
En la declaración de los métodos se define que devuelve un valor de un tipo
concreto y que tiene un conjunto de parámetros de entrada.
tipo nombre_de_método ( lista_formal_de_parámetros ) {
cuerpo_del_método;
}
Se podrı́a crear un método en la clase Point que inicialice las variables de instancia
de la forma siguiente:
clase Point {
int x, y;
void init(int x, int y) {
this.x = x;
this.y = y;
}
}
r
GVA-ELAI-UPMPFC0075-2003
107
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
El método main()
Dado que no hay funciones globales en Java, se debı́a idear alguna manera de
iniciar un programa, de ahı́ el sentido del método main, a partir de este método
es donde empiezan los programas. Esto es un concepto perdido en la creación de
interfaces gráficas. El método main es simplemente un lugar de inicio para que el
intérprete comience. Un programa complejo tendrá docenas de clases, y sólo una de
ellas necesitará tener un método main.
4.7.6.
Llamada a métodos
Se llama a los métodos dentro de una instancia de un clase utilizando el operador
punto (.). La forma general de una llamada:
referencia_a_objeto . nombre_de_método ( lista_de_parámetros );
En este caso, se puede llamar al método “init” sobre cualquier objeto Point.
Point p = new Point();
p.init (10, 20);
4.7.7.
Constructores
Las clases pueden implementar un método especial llamado constructor. Un constructor es un método que inicializa un objeto inmediatamente después de su creación.
Tienen exactamente el mismo nombre de la clase en la que residen; de hecho no se
puede tener ningún otro método que comparta su nombre con su clase. Una vez
definido, se llama automáticamente al constructor después de crear el objeto, antes
de que termine el operador new.
class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
108
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.7. CLASES
class PointCreate {
public static void main (String args[]) {
Point p = new Point(10, 20);
System.out.println("x = " + p.x + " y = " + p.y);
}
}
4.7.8.
Sobrecarga de métodos
Es posible y a menudo deseable crear más de un método con el mismo nombre,
pero con listas de parámetros distintas. A esto se le llama sobrecarga de método. Se
sobrecarga un método siempre que se crea un método en una clase que ya tiene un
método con el mismo nombre.
class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
Point() {
x = -1;
y = -1;
}
}
class PointCreateAlt {
public static void main (String args[]) {
Point p = new Point();
System.out.println("x = " + p.x + " y = " + p.y);
}
}
Este ejemplo crea un objeto Point que llama al segundo constructor sin parámetros
en vez de al primero.
4.7.9.
Operador this
Éste es un operador que utilizan las clases para hacerse referencias a sı́ mismas. De
esta forma un objeto siempre puede tener referencias a sus variables. Muy utilizado
en los constructores.
r
GVA-ELAI-UPMPFC0075-2003
109
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
Point() {
this(-1, -1);
}
}
4.7.10.
Herencia
La herencia es un concepto que relaciona clases una encima de otra de un manera jerárquica. Esto permite que los descendientes de una clase hereden todas las
variables y métodos de sus ascendientes, además de crear los suyos propios. A estos
descendientes se les llama subclases. Al padre inmediato de una clase se le llama su
superclase.
class Point3D extends Point {
int z;
Point3D(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
Point3D() {
this(-1, -1, -1);
}
}
La palabra clave extends se utiliza para indicar que se desea crear una subclase
de Point. No se necesita declarar las variables x e y en Point3D porque se habı́an
heredado de Point. Todas las variables x, y, z están en el mismo ámbito desde la
perspectiva de una instancia de Point3D.
super
Hay una variable especial en Java llamada “super”, que se refiere directamente a
los constructores de la superclase. Este ejemplo define una nueva versión de Point3D
110
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.7. CLASES
que utiliza el constructor super para inicializar x e y.
class Point3D extends Point {
int z;
Point3D(int x, int y, int z) {
super(x, y);
// aquı́ se llama al constructor Point(x, y)
this.z = z;
}
}
final
Todos los métodos y las variables de instancia se pueden sobrescribir por defecto.
Si se desea declarar que ya no se quiere permitir que las subclases sobrescriban las
variables o métodos, éstos se pueden declarar como final. El modificador de tipo final
implica que todas las referencias futuras a este elemento se basarán en esta definición.
Se puede utilizar final como modificador en declaraciones de método cuando se desea
no permitir que las subclases sobrescriban un método concreto.
static
A veces se desea crear un método que se utilize fuera del contexto de cualquier
instancia. Todo lo que se tiene que hacer es declarar estos métodos como “static”
(estático). Los métodos estáticos sólo pueden llamar a otros métodos static directamente, y no se pueden referir a this o super de ninguna manera. Las variables también
se pueden declarar como static, pero debe ser consciente que es equivalente a declararlas como variables globales, que son accesibles desde cualquier fragmento de código.
Se puede declarar un bloque static que se ejecuta una sola vez si se necesitan realizar
cálculos para inializar las variables static.
abstract
Las clases abstractas son aquellas cuya descripción es incompleta. Se definen utilizando la palabra reservada abstract. No proporcionan la implementación de todos
sus métodos. Los métodos no implementados se declaran como abstract. Una clase
con un método abstracto tiene que declararse como abstract. Una clase abstracta no
puede instanciarse, es decir, no pueden crearse objetos de esa clase.
r
GVA-ELAI-UPMPFC0075-2003
111
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
4.8.
4.8.1.
Fernando Ballesteros Herranz
Paquetes e interfaces
Paquetes
Los paquetes permiten agrupar una colección de clases e interfces funcionalmente
relacionadas asignándole un nombre.
Sentencia package
Lo primero que se permite en un archivo Java es una sentencia package, que le dice
al compilador en qué paquete se deberı́an definir las clases incluidas. Si se omite la
sentencia package, las clase terminan en el paquete por defecto, que no tiene nombre.
El compilador Java utiliza directorios de sistema de archivos para almacenar paquetes.
Si se declara que una clase está en dentro de un paquete llamado MiPaquete, entonces
el archivo fuente de esa clase se debe almacenar en un directorio llamado MiPaquete.
package nombrePaquete; //fichero como parte de un paquete
Sentencia import
Lo siguiente que se pone después de una sentencia package y antes de las definiciones de clase en un archivo fuente en Java puede ser una lista de sentencias import.
Todas las clases interesantes están almacenadas en algún paquete con nombre. Para
no tener que introducir el largo nombre de trayecto de paquete para cada clase, Java
incluye la sentencia import para que se puedan ver ciertas clases o paquetes enteros.
La forma general de la sentencia import:
import paquete1.[ paquete2 ].( nombre_clase | * );
paquete1 es el nombre de un paquete de alto nivel, paquete2 es el nombre de
un paquete opcional contenido en el paquete exterior separado por un punto (.). No
hay ningún lı́mite práctico a la profundidad de la jerarquı́a de paquetes. Finalmente,
nombre_clase explı́cito o un asterisco (*) que indica que el compilador Java deberı́a
buscar este paquete completo.
import java.util.Date;
import java.io.*;
112
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.8.2.
4.8. PAQUETES E INTERFACES
Protección de accesos
Hay cuatro niveles de protección en función de los atributos de acceso y de la
organización en paquetes y son publico, paquete, protegido y privado. Los atributos de
acceso son:
Si no se indica nada un miembro es accesible desde todo el paquete.
private: acceso sólo desde dentro de una clase.
public: acceso desde cualquier lugar
protected: acceso en la clase, las subclases (en cualquier paquete) y desde las
clases del mismo paquete.
El control de acceso se aplica tanto a atributos como a métodos.
4.8.3.
Interfaces
Las interfaces son como las clases, pero sin variables de instancia y con métodos
declarados sin cuerpo. Las clases pueden inplementar varias interfaces. Para implementar una interfaz, todo lo que necesita una clase es una implementación del conjunto completo de métodos de la interfaz. Las interfaces están en una jerarquı́a distinta
de la de las clases, por lo que es posible que varias clases que no tengan la más mı́nima relación en cuanto a la jerarquı́a de clases implementen la misma interfaz. Por
defecto todos sus métodos son públicos y abstractos, y sus atributos son públicos y
constantes. Los métodos que se declaran no tienen sentencias de cuerpo. Un ejemplo
de una interfaz es:
interface Callback {
void callback(int param);
}
Una clase puede implementar varias interfaces, con la sentencia implements:
class NombredeClase implements Interfaz1 [,Interfaz2,...]{
//declaración de métodos y atributos de la clase
}
r
GVA-ELAI-UPMPFC0075-2003
113
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
4.9.
Fernando Ballesteros Herranz
Gestión de cadenas
Una cadena es una secuencia de caracteres. Las cadenas son una parte fundamental
de la mayorı́a de los programas, ası́ pues Java tiene varias caracterı́sticas incorporadas
que facilitan la manipulación de cadenas.
Java tiene una clase incorporada en el paquete “java.lang” que encapsula las estructuras de datos de una cadena. Esta clase, llamada String es la representación
como objeto de una matriz de caracteres que no se puede cambiar.
4.9.1.
Constructores
Como con todas las otros clases, se pueden crear instancias de String con el operador new.
String s = new String();
Este ejemplo crea una instancia de String sin caracteres en ella. Para crear un
String inicializado con caracteres hay que pasarle una matriz de char al constructor.
char chars[] = { ’a’,’b’,’c’};
String s = new String(chars); // s es la cadena "abc"
La mejor forma en Java de inicializar un String es:
String s = "mejor";
4.9.2.
Métodos de String
length
La clase String además tiene sus propios métodos, uno de los más habituales es
length, que devuelve el número de caracteres de una cadena.
String s = "abc";
System.out.println(s.length()); // imprime 3
114
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.9. GESTIÓN DE CADENAS
Concatenación
El único operador que utiliza Java es + , y en los objetos String. El + actúa como
operador de concatenación en este caso en concreto para mejorar la legibilidad, por
ser operación muy común.
String s = "El tiene " + edad + " a~
nos";
Comparación de cadenas
Si se desean comparar dos cadenas para ver si son iguales, puede utilizar el método equals() de String. Devuelve “true” si las cadenas de caracteres comparadas son
iguales.
String coger= "dicom";
String hol= "dicom";
boolean compara = coger.equals(hol);//devuelve true
El método “equals” y el operador “= =” hacen dos pruebas completamente diferentes para la igualdad. Mientras que el método equals compara los caracteres contenidos en una String, el operador = = compara dos referencias de objeto para ver si
se refieren a la misma instancia.
Extracción de caracteres
Para extraer un único carácter de una cadena, se puede referir a un carácter
indexado mediante el método charAt:
"abc".charAt(1) // devolverá ’b’
La primera posición de una cadena es la posición 0.
4.9.3.
Conversión a String
Todos los objetos tienen el método toString() heredado de Object, de esta forma
cualquier objeto puede ser convertido en cadena. Ejemplo de int a String.
r
GVA-ELAI-UPMPFC0075-2003
115
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
int entero = 5;
String cadena = new Integer(entero).toString();
4.10.
Gestión de excepciones
Una excepción es una condición anormal que surge en una secuencia de código
durante la ejecución. La gestión de excepciones de Java lleva la gestión del error
en tiempo de ejecución al mundo orientado a objetos. Una excepción de Java es un
objeto que describe una condición excepcional que se ha producido en un fragmento
de código.
Los objetos de excepción los crea automáticamente el intérprete de Java como
respuesta a alguna condición excepcional. Como ejemplo tomamos una división por
cero. Cuando el intérprete de Java intenta ejecutar la división, observa que el denominador es cero y construye un nuevo objeto de excepción para que se detenga este
código y se trate esta condición de error. Una vez detenido el flujo del código en el
operador de división, se buscará en la pila de llamadas actual cualquier gestor de
excepciones (pila que contiene un registro de las llamadas a método). Un gestor de
excepciones es algo establecido para tratar inmediatamente la condición excepcional.
Si no codificamos un gestor de excepciones, se ejecutara el gestor en tiempo de ejecución por defecto. El gestor por defecto imprime el valor String de la excepción y el
trazado de la pila del lugar donde se produjo la excepción.
Figura 4.7: Propagación de excepciones
116
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.10.1.
4.10. GESTIÓN DE EXCEPCIONES
try y catch
Es más practico manejar y gestionar las excepciones. Se puede utilizar la palabra
clave try para especificar un bloque de código que se deberı́a proteger frente a todas
las excepciones. A continuación inmediatamente del bloque try, se debe incluir la
cláusula catch que especifica el tipo de excepción que se desea captar y en este bloque
se define como se trata la excepción.
class Exc {
public static void main(String args[]) {
try {
int d = 0;
int a = 42;
} catch (ArithmeticException e) {
System.out.println("división por cero");
}
}
}
ArithmeticException es una subclase especial de Exception, que describe más
especı́ficamente el tipo de error que se ha producido. El ámbito de la cláusula catch
está restringido a las sentencias especificadas por la sentencia try precedente.
En algunos casos, la misma secuencia de código puede activar más de una condición
excepcional. Se pueden tener varias cláusulas catch en una fila. Se inspecciona cada
uno de estos tipos de excepción en el orden en que están y el primero que coincida se
ejecuta.
4.10.2.
throw
La sentencia throw se utiliza para lanzar explı́citamente una excepción. El flujo de
la ejecución se detiene inmediatamente después de la sentencia throw, y no se llega a
la sentencia siguiente. Se inspecciona el bloque try que la engloba más cercano para
ver si tiene una cláusula catch cuyo tipo coincida con el de la instancia Throwable. Si
la encuentra, el control se transfiere a esa sentencia. Si no, se inspecciona el siguiente
bloque try que la engloba, y ası́ sucesivamente, hasta que le gestor de excepción más
externo detiene el programa e imprime el trazado de la pila hasta la sentencia throw.
r
GVA-ELAI-UPMPFC0075-2003
117
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
4.10.3.
Fernando Ballesteros Herranz
finally
Es el bloque de código que se ejecuta siempre haya o no excepción. Se puede
utilizar la palabra clave finally par identificar dicho bloque de código. Incluso aunque
so coincida ninguna de las cláusulas catch, se ejecutará el bloque finally antes del
código que está después del final del bloque try completo.
4.10.4.
Gestión incompleta de las excepciones
Si un método no gestiona o captura todas las excepciones que se pueden generar,
debe ser especificado mediante throws:
import java.io.*;
public class PruebaExcepciones {
public static char leer() throws IOException {
return (char) System.in.read();
}
public static void main(String args[]) {
try {
char car=leer();
System.out.println("Caracter: "+car);
} catch (IOException e) {
System.out.println("Error de entrada de datos");
}
}
}
4.11.
Hilos
La programación multihilo es un paradigma conceptual de la programación en el
cual se dividen los programs en dos o más procesos que se pueden ejecutar en paralelo.
En un momento dado pueden haber datos de entrada de usuario a los que responder,
animaciones y visualizaciones de interfaz de usuario, también cálculos grandes que
podrı́an tardar varios segundos en terminar, y nuestros programas tendrán que tratar
con estos temas sin provocar retrasos desagradables al usuario.
Lo interesante de todos estos procesos en paralelo es que la mayor parte de ellos
realmente no necesitan los recursos completos de la computadora durante su vida
operativa. El problema en los entornos de hilo único tradicionales es que se tiene que
118
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.11. HILOS
esperar a que se terminen cada una de estas tareas antes de proseguir con la siguiente.
Aunque la CPU esté libre la mayor parte del tiempo, tiene que colocar las tareas en
la cola ordenadamente.
Los sistemas multihilo aprovechan la circunstancia de que la mayorı́a de los hilos
computacionales invierten la mayor parte del tiempo esperando a que un recurso quede
disponible, o bien esperando a que se cumpla alguna condición de temporización. Se
puede describir todas las tareas como hilos de control independientes, conmutando de
manera automática entre una tarea que esté lista para pasar a un modo de espera, y
otra que sı́ tenga algo que hacer, consiguoendo realizar una cantidad mayor de trabajo
en el mismo intervalo de tiempo.
Prioridades de hilo
El intérprete de Java utiliza prioridades para determinar cómo debe comportarse
cada hilo con respecto a los demás. Las prioridades de hilo son valores entre 1 y 10
que indican la prioridad relativa de un hilo con respecto a los demás.
Sincronización
Ya que los hilos permiten y potencian el comportamiento ası́ncrono de los programas, debe existir alguna manera de forzar el sincronismo allı́ donde sea necesario.
Java incorpora una versión rebuscada de un modelo clásico para la sincronización,
el monitor. La mayor parte de los sistemas multihilo implementan los monitores a
modo de objetos, pero Java proporciona una solución más elegante: no existe la clase
monitor, cada objeto lleva asociado su propio monitor implı́cito, en el que puede entrar sin más que hacer una llamada a los métodos synchronized del objeto. Una vez
que el hilo está dentro del método synchronized, ningún otro hilo puede efectuar una
llamada a otro método synchronized sobre el mismo objeto.
Una vez que el programa se ha dividido en sus partes lógicas, a modo de hilo, es
preciso definir exactamente como se comunicarán entre si dichos hilos. Java utiliza
los métodos wait y notify para el intercambio de información entre hilos.
4.11.1.
Thread
En Java los hilos se representa mediante una clase. La clase Thread encapsula
todo el control necesario sobre los hilos. Hay que tomar la precaución de distinguir
claramente un objeto Thread de un hilo en ejecución. Un objeto Thread se define
r
GVA-ELAI-UPMPFC0075-2003
119
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
como el panel de control o proxy de un hilo en ejecución. En el objeto Thread hay
métodos que controlan si el hilo se está ejecutando, está durmiendo, en suspenso o
detenido. La clase Thread es la única manera de controlar el comportamiento de los
hilos. En la siguiente instrucción se muestra como acceder al hilo en ejecución actual:
Thread t = Thread.currentThread();//el hilo actual se almacena t
4.11.2.
Runnable
Si se tener más de un hilo necesitamos crear otra instancia de Thread. Cuando
se construye una nueva instancia de Thread, es necesario decir qué código ejecutar
en el nuevo hilo de control. Se puede comenzar un hilo sobre cualquier objeto que
implemente la interfaz Runnable.
Runnable es una interfaz simple que abstrae la noción de que se desea que algún
código se “ejecute” ası́ncronamente. Para implementar Runnable, a una clase le basta
con implementar un solo método llamado run. Este es un ejemplo que crea un nuevo
hilo.
class ThreadDemo implements Runnable {
ThreadDemo() {
Thread ct = Thread.currentThread();
Thread t = new Thread(this, "demo Thread");
System.out.println("hilo actual: " + ct);
System.out.println("Hilo creado: " + t);
t.start();
try {
Thread.sleep(3000);
} catch (interrupteExecption e) {
System.out.println("Interrumpido");
}
System.out.println("saliendo del hilo main");
}
public void run() {
try {
for (int y = 5; y > 0; y--) {
System.out.println(" " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("hijo interrumpido");
120
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.11. HILOS
}
System.out.println("saliendo del hilo hijo");
}
public static void main (String args [])
new ThreadDemo();
}
{
}
El hilo main crea un nuevo objeto Thread, con new Thread (this, “Demo Thread”),
pasa this como primer argumento para indicar que el nuevo hilo llame al método run
sobre este objeto. A continuación se llama a start, lo que inicia el hilo “t” en la
ejecución a partir del método run. En estos momentos hay dos hlos en ejecución,
uno “ct” que continúa con el programa principal, lo que le lleva al primer try, y el
segundo salta desde start() al método run(). Después, el hilo main se duerme durante
3000 milisegundos antes de imprimir un mensaje y después termina. Demo Thread
todavı́a está contando desde cinco cuando sucede esto. Se continúa ejecutando hasta
que termina con el bucle de run. Esta es la salida después de cinco segundos:
C:\> java ThreadDemo
Hilo actual: Thread[main, 5, main]
Hilo creado: Thread[demo Thread, 5, main]
5
4
3
saliendo del hilo main
2
1
saliendo del hilo hijo
4.11.3.
Prioridades de los hilos
El planificador de hilos hace uso de las prioridades de los mismos para decidir
cuándo debe dejar a cada hilo que se ejecute, de manera que los hilos con mayor prioridad deben ejecutarse más a menudo que lo de menor prioridad. Cuando
está ejecutándose un hilo de baja prioridad, y otro de mayor prioridad se despierta
de su sueño, o de la espera por un operación de E/S, debe dejarse que se ejecute de
manera inmediata, desalojando al hilo de menor prioridad. Cuando los hilos son de
igual prioridad deben desalojarse los unos a los otros, cada cierto tiempo, utilizando
el algoritmo circular round-robin para gestionar el acceso al la CPU.
r
GVA-ELAI-UPMPFC0075-2003
121
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
4.11.4.
Fernando Ballesteros Herranz
Sincronización
Cuando dos o más hilos necesitan acceder de manera simultánea a un recurso de
datos compartido necesitan asegurarse de que sólo uno de ellos accede al mismo cada
vez. Java proporciona un soporte único, el monitor, es un objeto que se utiliza como
cerrojo exclusivo. Solo uno de los hilos puede ser el propietario de un monitor en
un instante dado. Los restantes hilos que estuviesen intentando acceder al monitor
bloqueado quedan en suspenso hasta que el hilo propietario salga del monitor.
Todos los objetos de Java disponen de un monitor propio implı́citamente asociado
a ellos. La manera de acceder a un objeto monitor es llamando a un método marcado
con la palabra clave synchronized. Durante todo el tiempo en que un hilo permanezca
en un método sincronizado, los demás hilos que intenten llamar a un método sincronizado sobre la misma instancia tendrán que esperar. Para salir del monitor y
permitir el control del objeto al siguiente hilo en espera, el propietario del monitor
sólo tiene que volver del método
Sentencia synchronized
Si se utiliza una clase que no fue diseñada para accesos multihilo y, por ello,
se dispone de métodos no sincronizados que manipulan el estado interno,se puede
envolver la llamada al método en un bloque sincronizado. El formato general de la
sentencia sincronizada es el siguiente:
synchronized(objeto) sentencia;
En el ejemplo, objeto es cualquier referencia al objeto, y sentencia suele ser un
bloque que incluye una llamada al método de objeto, que solo tendrá lugar una vez
que el hilo haya entrado con éxito en el monitor de objeto.
4.11.5.
Comunicación entre hilos
Java proporciona un mecanismo elegante de comunicación entre procesos, a través
de los métodos wait, notify y notifyAll. Estos métodos se implementan como métodos
de final en Object, de manera que todas las clases disponen de ellos. Cualquiera de
los tres métodos sólo puede ser llamado desde dentro de un método synchronized.
wait: le indica al hilo en curso que abandone el monitor y se vaya a dormir hasta
que otro hilo entre en el mismo monitor y llame a notify.
122
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.11. HILOS
notify: despierta al primer hilo que realizó una llamada a wait sobre el mismo
objeto.
notifyAll_: despierta todos los hilos que realizaron una llamada a wait sobre el
mismo objeto. El hilo con mayor prioridad de los despertados es el primero en
ejecutarse.
4.11.6.
Métodos
Métodos de clase
Estos son los métodos estáticos que deben llamarse de manera directa en la clase
Thread.
currentThread: el método estático devuelve el objeto Thread que representa al
hilo que se ejecuta actualmente.
yield: este método hace que el intérprete cambie de contexto entre el hilo actual
y el siguiente hilo ejecutable disponible. Es una manera de asegurar que los hilos
de menor prioridad no sufran inanición.
Sleep(int n): el método sleep provoca que el intérprete ponga al hilo en curso
a dormir durante n milisegundos. Una vez transcurridos los n milisegundos,
dicho hilo volverá a estar disponible para su ejecución. Los relojes asociados a
la mayor parte de los intérpretes Java nos serán capaces de obtener precisiones
mayores de 10 milisegundos.
Métodos de instancia
Estos son los métodos que deben llamarse desde instancias u objetos de la clase
Thread.
start: indica al intérprete de Java que cree un contexto de hilo del sistema
y comience a ejecutarlo. A continuación, el método run objeto de este hilo
será llamado en el nuevo contexto del hilo. Debe tomarse la precaución de no
llamar al método start más de una vez sobre un objeto hilo dado.
run: constituye el cuerpo de un hilo en ejecución. Este es el único método de
la interfaz Runnable. Es llamado por el método start después de que el hilo
apropiado del sistema se haya inicializado. Siempre que el método run devuelva
el control, el hilo actual se detendrá.
r
GVA-ELAI-UPMPFC0075-2003
123
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
stop: provoca que el hilo se detenga de manera inmediata. A menudo constituye
una manera brusca de detener un hilo, especialmente si este método se ejecuta
sobre el hilo en curso. En tal caso, la lı́nea inmediatamente posterior a la llamada
al método stop no llega a ejecutarse jamás, pues el contexto del hilo muere antes
de que stop devuelva el control.
suspend: es distinto de stop. suspend toma el hilo y provoca que se detenga su
ejecución sin destruir el hilo de sistema subyacente, ni el estado del hilo anteriormente en ejecución. Si la ejecución de un hilo se suspende, puede llamarse a
resume sobre el mismo hilo para lograr que vuelva a ejecutarse de nuevo.
resume: se utiliza para revivir un hilo suspendido.
setPriority(int p): asigna al hilo la prioridad indicada por el valor entero pasado
como parámetro.
getPriority: devuelve la prioridad del hilo en curso, que es un valor entre 1 y 10.
setName(String nombre): identifica al hilo con un nombre mnemónico. De esta
manera se facilita la depuración de programas multihilo.
getName: devuelve el valor actual, de tipo cadena, asignado como nombre al
hilo mediante setName.
4.12.
Utilidades
La biblioteca de clases de Java contiene un conjunto de clases de utilidades utilizadas en todos los paquetes principales de Java. Estas clases están almacenadas en
los paquetes java.lang y java.util. Se utilizan para almacenar conjuntos de objetos,
realizar la interfaz con funciones del sistema de bajo nivel, funciones matemática,
generación de números aleatorios y manipulación de fecha/hora.
4.12.1.
Envolturas
Number
La clase abstracta Number representa una interfaz a todos los tipos escalares
estándar: long, int, float y double. Number tiene métodos de acceso que devuelven el
valor posiblemente redondeado del objeto de cada uno de los objetos simples:
doubleValue() devuelve un double.
124
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.12. UTILIDADES
floatValue() devuelve un float.
intValue() devuelve un int.
longValue() devuelve un long.
Double y Float
Double y Float son subclases de Number. Ambas clases tienen dos constructores
para inicializarlas con valores double y float, o, lo que es muy práctico, se pueden
inicializar con una representación tipo String del valor:
Double d1 = new Double(3.14159);
Double d2 = new Double("314159E-5");
Integer y Long
La clase Integer es una envoltura alrededor de int, short y byte. Long es una
envoltura alrededor del tipo long. Además de los métodos heredados de Number
tienen otros muy útiles:
parseInt(String) convierte la variable String en el valor int que representa.
parseInt(String, base) hace lo mismo que el método anterior, pero especifica una
base distinta de la décima.
toString(int) convierte el int que se pasa al método en su representación como
cadena.
toString(int, base) igual al anterior, pero puedo cambiar de base.
Character
Character es una envoltura simple alrededor de un char. Tiene varios métodos
útiles static, que se pueden utilizar para probar varias condiciones de un carácter:
isLowerCase(char ch) devolverá true si el carácter es una letra minúscula.
isUpperCase(char ch) lo mismo pero para letras mayúsculas.
r
GVA-ELAI-UPMPFC0075-2003
125
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
isDigit(char ch) e isSpace(char ch) devuelven true para caracteres numéricos y
espacios en blanco respectivamente.
toLowerCase(char ch) y toUpperCase(char ch) convierten entre mayúscula y
minúscula y viceversa.
Boolean
Boolean es un envoltorio muy fino alrededor de valores boolean, que solo es útil
para situaciones de paso por referencia.
4.12.2.
Enumeraciones
Java tiene matrices para almacenar grupos de datos de tipo similar, que son muy
útiles para modelos simples de acceso a datos. Sin embargo, las enumeraciones ofrecen
una manera más completa y orientada a objetos para almacenar conjuntos de datos
de tipo similar. Las enumeraciones tienen su propia asignación de memoria y posibilidad de una nueva asignación para ampliarlas. Tienen interfaces de método para su
iteración y recorrido. Se pueden indexar mediante algo más complejo y útil que los
simples enteros.
Interfaz de enumeración
Enumeracion es una interfaz simple que permite enumerar todos los elementos de
cualquier conjunto de objetos. Especifica dos métodos. El primero, un método boolean
llamado hasMoreElements, devuelve true cuando todavı́a quedan más elementos que
extraer. El segundo, nextElement devuelve una referencia a objeto genérica cuyo tipo
hay que convertir al tipo de clase de la cual el objeto es una instancia.
Vector
Un Vector es una matriz ampliable de referencias a objeto. Internamente, un
Vector implementa una estrategia de crecimiento para minimizar la reasignación y el
espacio desperdiciado. Los objetos se pueden almacenar al final de un Vector utilizando el método addElement o en un ı́ndice dado mediante el método insertElement. Se
puede almacenar una matriz en un Vector utilizando el método copyInto. Una vez se
ha almacenado un conjunto de objetos en un Vector, se puede utilizar para buscar un
126
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.12. UTILIDADES
elemento en concreto utilizando los métodos contains, indexOf, o lastIndexOf. También se puede extraer un objeto de una posición especı́fica de un Vector utilizando los
métodos elementAt, firstElement y lastElement.
4.12.3.
Runtime
La clave Runtime encapsula el proceso del intérprete de Java que se ejecuta. No se
puede crear una instancia de Runtime; sin embargo, se puede obtener una referencia
al objeto Runtime que se está ejecutando actualmente llamando la método estático
Runtime.getRuntime. Una vez tenga el descriptor del proceso en ejecución, puede
llamar a varios métodos que controlan el estado y comportamiento de la máquina
virtual de Java.
Runtime rt = Runtime.getRuntime();
rt.exec("c:\\CntVirRel.exe");
Mediante Runtime se puede ejecutar cualquier aplicación, mediante el método
exec().
4.12.4.
System
La clase System contiene un conjunto curiosos de funciones y variables globales.
La entrada y salida estándar del interprete de Java se almacena en las variables in y
out.
System.out.println("Este es un ejemplo");
Con el método println() se saca por pantalla los argumentos introducidos.
4.12.5.
Date
La clase Date se utiliza para presentar una fecha y una hora. Se pueden manipular
el dı́a, mes, año, dı́a de la semana, horas, minutos y segundos. Hay varios constructores
para objetos Date. El más simple, Date(), inicializa el objeto con la fecha y hora
actual. Hay tres constructores más que ofrecen niveles de especificidad mayores para
la precisión que se desea para la hora:
r
GVA-ELAI-UPMPFC0075-2003
127
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
Date(año, mes, dı́a) establecerá la hora a las 00:00:00 del dı́a especificado.
Date(año, mes, dı́a, horas, minutos) fijará la fecha y hora, dejando los segundos
a 0.
Date(año, mes, dı́a, horas, minutos, segundos) establecerá la hora exacta.
4.13.
Entrada/Salida
La mayorı́a de los programas no pueden alcanzar sus metas sin acceder a datos
externos. Estos datos se recuperan a partir de un origen de entrada. Los resultados
de un programa se envı́an a un destino de salida. La noción genérica de una fuente
de entrada puede representar muchos tipos de entrada distintos: desde un archivo de
disco, un teclado o un conector (socket) de red. Estas abstracciones son una manera
limpia de tratar la E/S sin necesitar que todo el código comprenda la diferencia entre
un teclado y una red.
Java llama flujo a esta abstracción y la implementa con varias clases del paquete
java.io. El flujo de E/S representa todos los orı́genes y destinos de los datos detrás de
una interfaz uniforme. La entrada está encapsulada en la clase InputStream y la salida
en la clase OutputStream. Estas dos clases abstractas son las que todos los objetos
deberı́an referenciar cuando tratan la E/S en general. Sus métodos más importantes
son read() y write(int b); son métodos abstractos que definen la función básica de
lectura/escritura de un byte.
Figura 4.8: Flujos estándar
4.13.1.
File
Un File es el único objeto del paquete de E/S que referencia a un archivo de
disco real. La clase File no especifica cómo se recupera o almacena la información en
los archivos; sólo describe las propiedades de un objeto archivo. Los archivos son un
origen y un destino primario de los datos dentro de la mayorı́a de los programas.
Los objetos archivo se pueden crear utilizando uno de los tres constructores
disponibles. El ejemplo siguiente crea tres archivo: f1, f2 y f3. El primer objeto File
se construye utilizando un trayecto de directorio como único argumento. El segundo
128
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.13. ENTRADA/SALIDA
se crea utilizando dos argumentos, el trayecto y el nombre de archivo. El tercero se
crea utilizando el trayecto de archivo asignado a f1 y un nombre de archivo; f3 refiere
al mismo archivo que f2.
File f1 = new File("/");
File f2 = new File("/","autoexec.bat");
File f3 = new File(f1, "autoexec.bat");
Directorios
Un directorio es un File que contiene una lista de otros archivos y directorios.
Cuando se crea un Objeto File y es un directorio, el método isDirectory devolverá true.
En este caso, se puede llamar al método list sobre ese objeto para extraer la lista de
los otros archivos y directorios que contiene. Si se llama al método list sobre un
objeto File que no sea un directorio se provoca una NullPointerException en tiempo
de ejecución.
import java.io.File;
class Dirlist {
public static void main(String args[]) {
String dirname = "/java";
File f1 = new File(dirname);
if (f1.isDirectory()) {
System.out.println("Directorio de " + dirname);
String s[] = f1.list();
for (int y = 0; i < s.length; y++) {
System.out.println(s[i] + " es un directorio");
}
} else {
System.out.println(dirname + " no es un directorio");
}
}
}
La ejecución de este programa lista el contenido del directorio /java del PC.
FilenameFilter
A menudo se desea limitar el número de archivos devueltos por el método list
para que se incluyan únicamente aquellos archivos que cumplan un cierto patrón
r
GVA-ELAI-UPMPFC0075-2003
129
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
de nombre de archivo. Con este fin, el paquete java.io incluye una interfaz llamada
FilenameFilter. Un objeto que implemente FilenameFilter tiene un único método,
accept, al que se llama una vez por cada archivo de una lista. El método accept
devuelve el valor true si se debiera incluir el archivo en la lista. El ejemplo siguiente
amplı́a el programa anterior restringiendo la visibilidad de los nombres de archivo
devueltos por el método list. La restricción se aplica a archivos con nombres que
terminan con la extensión de archivo que se pasa como parámetro cuando se construye
le objeto:
import java.io.*;
public class OnlyExt implements FilenameFilter {
String ext;
public OnlyExt(String ext) {
this.ext = "." + ext;
}
public boolean accept (File dir, String name) {
return name.endsWith(ext);
}
}
4.13.2.
InputStream
InputStream es una clase abstracta que define el modelo de Java para el flujo de
entrada. Todos los métodos de esta clase lanzarán una IOException si se producen
condiciones de error. Este es un breve resumen de los métodos de InputStream:
read() devuelve una representación como entero del siguiente byte de entrada
disponible.
read(byte[]) intenta leer hasta b.length bytes situándolos en b y devuelve el
número real de bytes que se leyeron con éxito.
read(byte b[], int off, int len) intenta leer hasta len bytes situándolos en b comenzando en b[off], y devuelve el número de bytes que se leyeron con éxito.
skip(long n) omite n bytes de la entrada, y devuelve el número de bytes que se
han omitido.
available() devuelve el número de bytes de entrada disponibles actualmente para
su lectura.
close() cierra el origen de entrada. Los intentos de lectura posteriores generarán
una IOException.
130
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.13. ENTRADA/SALIDA
mark(int limitelectura) coloca una marca en el punto actual del flujo de entrada
que seguirá siendo válida hasta que se lean limitelectura bytes.
reset() devuelve el puntero de entrada ala marca establecida previamente.
markSupported() devuelve true si se admiten mark/reset en este flujo.
4.13.3.
OutputStream
Igual que InputStream, OutputStream es una clase abstracta que define el flujo
de salida. Todos los métodos de esta clase devuelven un valor void y lanzan una
IOException en caso de error. Esta es una lista de los métodos de OutputStream:
write(int b) escribe un único byte en un flujo de salida. Observar que el parámetro
en un int, lo que permite que se llame a write con expresiones sin tener que convertir su tipo a byte.
write(byte b[]) escribe una matriz completa de bytes en un flujo de salida.
write(byte b[], int off, int len) escribe len bytes de la matriz b, comenzando a
partir de b[off].
flush() inicializa el estado de la salida de manera que se limpian todos los buffers.
close() cierra el flujo de salida. Los intentos de escritura posteriores generarán
una IOException.
4.13.4.
Flujo de archivo
FileInputStream
La clase FileInputStream utiliza archivos de datos reales como base del flujo de
entrada. El ejemplo siguiente crea dos FileInputStreams que están utilizando el mismo
archivo de disco real.
InputStream f0 = new FileInputStream("/autoexec.bat");
File f = new file("/autoexec.bat");
InputStream f1 = new FileInputStream(f);
r
GVA-ELAI-UPMPFC0075-2003
131
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
FileOutputStream
FileOutputStream comparte el mismo estilo de constructores que FileInputStream.
Sin embargo, la creación de FileOutputStream no depende de que el archivo ya exista. FiliOutputStream creará el archivo antes de abrirlo como salida cuando se crea
el objeto. Si se intenta abrir un archivo de sólo lectura como punto final de un FiliOutputStream, se lanzará una IOException.
ByteArrayInputStream
ByteArrayInputStream (flujo de entrada de matriz de bytes) es una implementación
de un flujo de entrada que utiliza una matriz de bytes como origen. Esta clase tiene
dos constructores, y ambos necesita una matriz de bytes que proporcione el origen de
los datos.
ByteArrayOutputStream
ByteArrayOutputStream tiene dos constructores. En la primera forma, se crea un
buffer de 32 bytes. En la segunda, se crea un buffer con un tamaño igual al argumento
en bytes, que en este ejemplo es 1024 bytes:
OutputStream out0 = new ByteArrayOutputStream();
OutputStream out1 = new ByteArrayOutputStream(1024);
4.13.5.
Flujos filtrados
Los flujos filtrados amplı́an los flujos básicos, proporcionando una sincronización.
En un sistema de E/S multihilo, se pueden producir resultados inesperados cuando
se permite que múltiples hilos operen sobre el mismo flujo. Aunque es posible tener
hilos múltiples en Java leyendo o escribiendo en el mismo flujo, hay una buena razón
para permitir que sólo un hilo tenga acceso directo a un flujo de E/S único. Todos
los constructores y métodos proporcionados en esta clase son idénticos a los mencionados anteriormente para InputStream y OutputStream, a excepción de que están
sincronizados.
132
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.13. ENTRADA/SALIDA
BufferedOutputStream
La salida a BufferedOutputStream es idéntica a cualquier OutputStream con la
excepción de que se añade un método de entrada con buffer, la salida con buffer no
proporciona ninguna funcionalidad adicional. En Java, los buffers para la salida están
ahı́ para incrementar el rendimiento.
4.13.6.
SequenceInputStream
La clase SequenceInputStream (flujo de entrada secuencial) admite la utilidad
original de concatenar múltiples InputStreams en uno sólo. La construcción de un
Sequence es diferente de cualquier otro InputStream. Un constructor SequenceInputStream utiliza como argumento un par de InputStreams o una Enumeration de
InputStreams:
SequenceInputStream(Enumeration e);
SequenceInputStream(InputStream s0, InputStream s1);
PrintStream
La clase PrintStream proporciona todas las utilidades de formato que hemos estado utilizando desde el principio del libro de los descriptores de archivo de System.
Pensabas que se introducı́a “System.out.println” sin pensar demasiado en las clases
que proporcionaban el formato de la salida que se presentaba. PrintStream tiene
dos constructores, PrintStream(OutputStream sal) y PrintStream(OutputStream sal,
boolean auto), donde auto controla si java vacı́a el flujo de salida cuando vaya a la
salida un carácter de lı́nea nueva “\n”.
Los objetos PrintStream de Java admiten los métodos print y println para todos los tipos, incluyendo Object. Si un argumento no se un tipo simple, los métodos
PrintStream llaman al método toString del objeto y a continuación imprimen el resultado.
4.13.7.
Ejemplo
Este primer ejemplo se muestra una forma cómoda y eficaz para la lectura ficheros
que en este caso se leen los datos del fichero LeeFichero.java y se imprimen por la
consola.
r
GVA-ELAI-UPMPFC0075-2003
133
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
import java.io.*;
public class LeeFichero {
public static void main(String[] argumentos) {
final int TAMANIO_BUFFER = 64;
byte buffer[] = new byte[TAMANIO_BUFFER];
int NumBytes;
try {
FileInputStream FicheroOrigen = new FileInputStream
("LeeFichero.java");
try {
do {
NumBytes = FicheroOrigen.read(buffer);
System.out.print(new String(buffer,0,NumBytes));
} while (NumBytes == TAMANIO_BUFFER);
FicheroOrigen.close();
} catch (IOException e){
System.out.println("Error leyendo los datos o
cerrando el fichero");
}
} catch (FileNotFoundException e) {
System.out.println("Fichero no encontrado");
}
}
}
En este ejemplo todo lo que se escriba en la consola se va introduciendo en un
archivo de salida que se llama “Salida.txt”.
import java.io.*;
public class EscribeFichero {
public static void main(String[] argumentos) {
final int TAMANIO_BUFFER = 64;
byte buffer[] = new byte[TAMANIO_BUFFER];
134
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.14. TRABAJO EN RED
int NumBytes;
try {
FileOutputStream FicheroDestino = new FileOutputStream
("Salida.txt");
try {
do {
NumBytes = System.in.read(buffer);
FicheroDestino.write(buffer,0,NumBytes);
} while (buffer[0] != Character.LINE_SEPARATOR);
FicheroDestino.close();
} catch (IOException e){
System.out.println("Error escribiendo los datos
o cerrando el fichero");
}
} catch (FileNotFoundException e) {
System.out.println("Fichero no encontrado");
}
}
}
4.14.
Trabajo en Red
Este capı́tulo cubre el paquete java.net. La integración de Java con la red se
ha hecho legendaria, gracias en gran parte a esta biblioteca de clases. Java admite el
protocolo de TCP/IP de Internet ampliando la interfaz de E/S de flujo ya establecida,
presentada en el capı́tulo anterior, y añadiendo las caracterı́sticas que se necesitan
para crear objetos de E/S a través de la red. Java admite las familias de protocolo
TCP y UDP. TCP se utiliza para E/S fiable de tipo secuencial a través de la red.
UDP admite un modelo más rápido, punto a punto y orientado a datagrama.
Un aspecto que hay que tener en cuenta cuando se programan comunicaciones con
TCP es la eficiencia que se consigue. Cuando se va a traspasar una gran cantidad de
información (por ejemplo, un fichero video), si no necesitamos tiempo real, TCP es un
protocolo adecuado, puesto que el tiempo necesario para establecer la comunicación
es desprediable respecto al utilizado para la transmitir los datos. En el otro extremo,
si necesitamos una gran cantidad de cominicaciones cortas en las que la fiabilidad no
r
GVA-ELAI-UPMPFC0075-2003
135
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
es muy importante , TCP no es un protocolo adecuado;serı́a mucho mejor UDP.
4.14.1.
InetAddress
Independientemente de si se realiza una llamada telefónica, se envı́a un correo
electrónico o se establece una conexión a través de Internet, las direcciones son fundamentales. Java admite los nombres de Internet a través de la clase InetAddress.
Las direcciones de Internet, reducidas a su nivel más bajo, están formadas por un
identificador de nodo de 32 bits y un selector de puerto de ese nodo de 32 bits. En Internet el direccionamiento lo gestionan servidores de nombres que traducen nombres
habituales y fáciles de recordar a sus correspondientes direcciones de 32 bits.
La clase InetAddress no tiene constructores visibles. Para crear un objeto InetAddress, se tiene que utilizar uno de los métodos de fábrica disponibles. Estos métodos
son simplemente métodos estáticos que devuelven una instancia de la clase en la que
residen. En este caso, InetAddress tiene tres métodos, getLocalHost, getByName y
getAllByName, que se pueden utilizar para crear instancias de InetAddress.
InetAddress ip = InetAddress.getLocalHost();
La clase InetAddress también tiene unos cuantos métodos no estáticos, que se
pueden utilizar sobre los objetos devueltos por los métodos que se acaban de mencionar:
getHostName() devuelve una cadena que representa el nombre de nodo asociado
con el objeto InetAddress.
getAddress() devuelve una matriz de bytes de cuatro elementos que representa
la dirección en Internet del objeto en el “orden de red”.
toString() devuelve una cadena que contiene el nombre del nodo y la dirección
IP.
4.14.2.
Datagramas
Los datagramas son bloques de información del tipo “lanzar y olvidar” que se
transfieren a través de la red. Para la mayorı́a de los programas de la red, el utilizar
un flujo TCP/IP en vez de un datagrama UPD es más sencillo y hay menos posibilidades de tener problemas. Sin embargo, cuando se requiere un rendimiento óptimo, y
136
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.14. TRABAJO EN RED
está justificado el tiempo adicional que supone el realizar la verificación de los datos,
los datagramas son un mecanismo realmente útil.
Cuando se ha lanzado un datagrama hacia su destino, no hay ninguna seguridad
de que llegue o incluso de que haya alguien allı́ para cogerlo. Igualmente, cuando se
recibe un datagrama, no es seguro que no se haya dañado por el camino o que el que
lo haya enviado esté todavı́a ahı́ para recibir una respuesta.
DatagramPacket
Se pueden crear los DatagramPackets utilizando dos constructores. El primero
utiliza solamente un buffer de bytes y una longitud. Ese utiliza para recibir datos a
través de un DatagramSocket. El segundo añade una especificación de dirección de
destino y un puerto, que es utilizada por un DatagramSocket para determinar dónde
se enviarán los datos del paquete. Considerar que estas dos formas equivalen a crear
un “un buzón de entrada” en el primer caso, y a rellenar y poner una dirección en un
sobre en el segundo. Estos son los prototipos de los dos constructores:
DatagramPacket(byte ibuf[], int ilong);
DatagramPacket(byte ibuf[], int ilong, InetAddress idir,
int ipuerto);
Hay varios métodos de acceder al estado interno de un DatagramPacket. Permiten
un acceso completo a la dirección de destino y número de puerto de un paquete,
además de a sus datos y su longitud. A continuación se presenta un resumen de cada
uno de ellos:
getAddress() devuelve la InetAddress de destino. Se utiliza habitualmente para
envı́os.
getPort() devuelve el número entero de puerto de destino. Se utiliza para envı́os.
getData() devuelve la matriz de bytes de los datos contenidos en el datagrama.
Se utiliza para recuperar los datos del datagrama después de haberlo recibido.
getLength() devuelve la longitud de los datos válidos contenidos en la matriz
de bytes que se devolverı́an con el método getData. Habitualmente no coincide
con la longitud de la matriz de bytes.
r
GVA-ELAI-UPMPFC0075-2003
137
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
4.14.3.
Fernando Ballesteros Herranz
Conectores
Socket cliente
Los conectores (sockets), o los conectores TCP/IP en concreto, se utilizan para
implementar conexiones basadas en flujo, punto a punto, bidireccionales y fiables entre
nodos de Internet. Se puede utilizar un conector para conectar el sistema de E/S de
Java a otros programas que pueden residir en la máquina local o en cualquier otra
máquina de Internet. La clase Socket, a diferencia de DatagramSocket, implementa
una conexión continua muy fiable entre el cliente y el servidor.
Al crear un objeto conector también se establece la conexión entre direcciones de
Internet. No hay métodos ni constructores que muestren explı́citamente los detalles
del establecimiento de la conexión del cliente. Se puedan utilizar dos constructores
para crear conectores:
Socket(String nodo, int puerto) crea un conector que conecta el nodo local con
el nodo y puerto nombrados.
Socket(InetAddress dirección, int puerto) crea un conector utilizando un objeto
InetAddress ya existente y un puerto.
En un conector se puede examinar en cualquier momento la información de dirección y puerto asociada con él utilizando los métodos siguientes:
getInetAddress() devuelve la InetAddress asociada con el objeto Socket.
getPort() devuelve el puerto remoto al que está conectado este objeto Socket.
getLocalPort() devuelve el puerto local al que está conectado este objeto Socket.
Cuando se ha creado el objeto Socket, también puede ser examinado para acceder
a los flujos de entrada y salida asociados con él. Todos estos métodos pueden lanzar
una IOException si se han invalidado los conectores debido a una pérdida de conexión
en la red. Estos flujos se utilizan exactamente igual que los flujos de E/S que hemos
visto en el capı́tulo anterior para enviar y recibir datos:
getInputStream() devuelve el InputStream asociado con este conector.
getOutputStream() devuelve el OutputStream asociado con este conector.
close() cierra el InputStream y el OutputStream.
138
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.14. TRABAJO EN RED
Socket servidor
Los ServerSockets se deben utilizar para crear servidores de Internet. Estos servidores no son necesariamente máquinas, de hecho son programas que están esperando
a que programas cliente locales o remotos se conecten a ellos en puertos públicos.
Los ServerSockets son bastante diferentes de los Sockets normales. Cuando se crea un
ServerSocket, se registrará en el sistema que tiene interés en conexiones de cliente.
Tiene un método adicional, accept, que es una llamada que se bloquea ya que espera
que un cliente inicie la comunicación y después devuelve un Socket normal.
Los dos constructores de ServerSocket reflejan el número del puerto en el que
se desean aceptar las conexiones y, opcionalmente, durante cuánto tiempo se desea
esperar a que se deje de utilizar el puerto. Ambos constructores pueden lanzar una
IOExeption bajo condiciones adversas. Estos son los dos prototipos:
ServerSocket(int puerto) crea un conector de servidor en el puerto especificado.
ServerSocket(int puerto, int número) crea un conector de servidor en el puerto
especificado esperando número milisegundos si el puerto se está utilizando.
Funcionalmente, el método accept de un ServerSocket es una llamada que se bloquea y que espera que un cliente inicie la comunicación y después devuelve un Socket
normal. Después, este conector se utiliza para la comunicación con el cliente.
4.14.4.
Conexión
Conexión cliente
Lo primero debe ser crear un objeto socket diciendo con que servidor y por que
puerto se realiza la conexión. Después para que haya una comunicación entre las dos
máquinas es necesario abrir dos flujos uno de entrada y otro de salida, en los que por
ellos se realiza el intercambio de información. Es recomendable utilizar el buffer para
la transferencia de la información. Por último una vez se quiera desconectar, se debe
cerrar el socket.
Socket conexion = new Socket(servidor, puerto);
DataInputStream in = new DataInputStream(new BufferedInputStream
(conexion.getInputStream()));
DataOutStream out = new DataOutputStream(new BufferedOutputStream
r
GVA-ELAI-UPMPFC0075-2003
139
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
(conexion.getOutputStream()));
//...
conexion.close();
Conexión servidor
Es muy interesante que el servidor sea multihilo para que pueda atender varias
peticiones de clientes distintos a la vez, por lo que la clase del servidor tiene que
derivarse de la clase Thread. Para abrir el socket del servidor vale con pasarle que
puerto es utilizado para la trasnmisión de datos. Este puerto debe ponerse a la escucha
de posibles peticiones de los clientes. También se deben declarar los flujos de entrada
y salida de datos.
ServerSocket conexion = new ServerSocket(puerto);
conexion.accept();
conexion.start();//start de Thread crea nuevo hilo y va a run()
//...
public void run(){
DataInputStream in = new DataInputStream(new BufferedInputStream
(conexion.getInputStream()));
DataOutStream out = new DataOutputStream(new BufferedOutputStream
(conexion.getOutputStream()));
//...
4.15.
Interfaces Gráficas de Usuario
4.15.1.
Componentes AWT
Los componentes de AWT están en el paquete java.AWT. y son utlizados para la
creación de GUIs5 . Un componente (component) es una clase abstracta que encapsula
todos los atributos de un componente visual. Todos los elementos de la interfaz de
usuario que se visualizan en la pantalla y que interactuan con un usuario son subclases
de component.
Subclases de Component:
5
140
Graphics User Interfaces
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.15. INTERFACES GRÁFICAS DE USUARIO
Container (contenedor). Contendrá métodos adicionales que permiten que otros
componentes se aniden dentro de el.
Panel. Es una subclase de container. Se pueden añadir otros componentes a
panel mediante el método add (añadir), modificar estos componentes con move
(desplazar), resize (cambiar el tamaño).
Canvas (lienzo). En el se puede pintar cualquier componente.
Label (etiqueta). Es una subclase de canvas.
Button (botón). Componente que se puede utilizar para ejecutar alguna acción
cuando el usuario lo pulsa y lo libera.
Checkbox (cuadro de comprobación). Se utiliza para seleccionar una condición
booleana. Cuando se construye un checkbox se le pasa un string y opcionalmente
un boolean que especifica el estado inicial de la marca de comprobación. Se
puede establecer y obtener el estado actual de la marca de comprobación con
los métodos setstate y getestate respectivamente.
Checkboxgroup. Permite crear un grupo de opciones que solo se pueden seleccionar de una en una. Los métodos getcheckboxgroup y secheckboxgroup se
utilizan para obtener y establecer el grupo al que pertenece un chekbox.
Getcurrent, setcurrent. Obtienen y establecen, respectivamente, el checkbox seleccionado actualmente.
Choice (opción). Se utiliza para crear un menú de selección emergente. El método additem (añadir elemento) añade nuevas cadenas a la clase choice.
Countitems (contar elementos). Devuelve el numero de elementos de el menú de
opciones.
List (lista). Proporciona una lista de selección compacta, de elecciones múltiples
y de desplazamiento.
Scrollbar (barras de desplazamiento). Se utiliza para seleccionar valores continuos entre un mı́nimo y un máximo especificados.
Textfield (campo de texto). Implementa un área de entrada de texto de una sola
lı́nea.
Seteditable. Congela el contenido del textfield.
Iseditable. Comprueba la posibilidad de edición.
Gettext. Obtiene el valor actual del campo.
Settext. Establece el valor actual.
r
GVA-ELAI-UPMPFC0075-2003
141
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
Setechocaracter. Establece el carácter único que mostrará el textfield para todos
los caracteres que se introduzcan, muy útil para esconder códigos o información
secreta.
Textarea (área de texto). Es un editor de texto muy simple.
Appendtext. Añade su parámetro string al final del buffer.
Inserttext. Inserta su string en una posición dada, de base 0 que comienza al
principio del buffer.
Replacetext. Copia caracteres del string a partir del primer ı́ndice y hasta el
segundo.
Figura 4.9: Jerarquı́a de componentes del AWT
4.15.2.
Organización
Cada objeto container tiene un gestor de organización, Layoutmanager. Java tiene
varias clases de layoutmanager predefinidas:
Flowlayout (organización continuada). Los componentes se colocan desde la
esquina superior izquierda, de izquierda a derecha y de arriba a abajo.
Borderlayout (organización con limites). Tiene cuatro componentes estrechos y
de anchura fija en los extremos, y un área grande en el centro que se amplia y
contrae en dos dimensiones, cada una de estas áreas tiene un nombre que es un
string: north, south, easty, west, representan los cuatro lados y center el área
del centro.
142
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.15. INTERFACES GRÁFICAS DE USUARIO
Insets (recuadros). Se utiliza para recuadrar un panel.
Cardlayout (organización con tarjetas).
Window (ventana). Parecido a panel con la excepción de que crea su propia
ventana de nivel superior, en vez de estar contenida dentro de otro panel.
Frame (marco). Tiene una barra de tı́tulo, esquinas para cambiar el tamaño y
una barra de menú.
4.15.3.
Componentes de menú
Cada ventana de nivel superior, puede tener una barra de menú asociada con
ella. Un objeto menubar (barra de menú) puede contener varios objetos menú en
él. Los menús tienen una lista de objetos menuitem (elemento de menú) dentro de
ellos. Menú, es una subclase de menuitem, lo que permite anidar submenus de forma
jerárquica.
4.15.4.
Componentes Swing
Las componentes Swing se identifican porque pertenecen al paquete javax.swing.
Son contenedores como el AWT pero que continen otros componentes. Estos componentes se pueden añadir al contenedor y para ciertas operaciones se puedan tratar
como un todo. Mediante un gestor de diseño controlan la disposición(layout) de estos componentes en la pantalla. Ejemplos de estos componentes son JPanel, JFrame,
JApplet. . .
Administrador de diseño
Tipos de diseños y composiciones:
FlowLayout: Los componentes se ponen de izquierda a derecha hasta llenar la
lı́nea, y se pasa a la siguiente. Cada lı́nea se centra.
BorderLayout: Se ponen los componentes en un lateral o en el centro. Se indica
con una dirección:“East”, “West”, “North”, “South”, “Center”.
GridLayout: Se colocan los componentes en una rejilla rectangular (filas x columnas). Se añaden en orden izquierda-derecha y arriba-abajo.
r
GVA-ELAI-UPMPFC0075-2003
143
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
Figura 4.10: Componentes Swing
Para poner un layout se utiliza el método setLayout():
GridLayout nuevolayout = new GridLayout(3,2);
setLayout(nuevolayout);
Figura 4.11: Layout de Swing
4.15.5.
Eventos
Cualquier componente puede gestionar eventos sobrescribiendo ciertos métodos
llamados por la implementación por defecto de método handleevent (gestionar evento)
de component, se llama a dicho método con una instancia de la clase event (evento).
Estos son algunos ejemplos:
144
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.16. ENCRIPTACIÓN
MouseEnter se le llama cuando el ratón entra por primera vez en un component.
MouseExit se le llama cuando el ratón abandona el componente.
MouseMove se le llama cuando se mueve por el componente.
MouseDown se le llama cuando se pulsa primero cualquier botón del ratón.
MouseDrag se le llama cuando el ratón se mueve con un botón pulsado.
MouseUp se le llama cuando se libera el ratón.
Keydown se le llama cuando se pulsa una tecla.
Keyup se le llama cuando se libera una tecla.
Shifthdown comprueba si esta pulsada la tecla shift.
Controldown comprueba si esta pulsada la tecla control.
A los eventos relacionados con el ratón, se les llama con una copia del evento
original y la ubicación (x, y) del evento.
4.16.
Encriptación
[ENCRI]
El soporte que da el JDK a la criptografı́a se divide en dos grandes bloques, el
JCA “Java Cryptography Architecture” y el JCE “Java Cryptography Extension”.
La primera parte nos define las bases del soporte criptográfico de Java, y la segunda
nos provee de los algoritmos necesarios para poder encriptar y desencriptar datos.
Debido a las leyes de los Estados Unidos, que prohiben exportar software de
encriptación de datos, el JCE no viene incluido en el JDK, y existen restricciones
para bajarlo de la site de SUN, pero existen paquetes de terceros, desarrollados fuera
de los Estados Unidos, que implementan todas las especificaciones del JCE y que no
están sujetos a sus restricciones legales, como por ejemplo la librerı́a CRYPTICS.
4.16.1.
Arquitectura Criptográfica de Java (JCA)
El JCA, se refiere al marco para acceder y desarrollar la funcionalidad criptográfica
de Java. Incluye todo el API relativo a la criptografı́a ( el paquete java.security y sus
r
GVA-ELAI-UPMPFC0075-2003
145
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
subpaquetes), ası́ como una serie de especificaciones a tener en cuenta por los programadores que quieran crear extensiones criptográficas (como la librerı́a CRYPTICS,
etc).
La arquitectura criptografica de Java ha sido diseñada teniendo en cuenta los principios de independencia de la implementación e interoperabilidad. La independencia
de la implementación se consigue introduciendo el concepto de “Proveedor” (Cryptography Package Provider). El termino “Proveedor” se refiere a un paquete o grupo
de paquetes que que implementan algoritmos criptográficos especı́ficos.
El JDK 1.1 viene con un proveedor por defecto llamado “SUN”, el cual incluye
una implementación del algoritmo DSA y una implementación de los algoritmos de
Hashing MD5 y SHA-1. En el JDK se pueden instalar uno o mas paquetes proveedores.
SecureRandom
La clase SecureRandom es un generador de números pseudo-aleatorio. Para crear
objetos SecureRandom usaremos uno de los siguientes constructores:
SecureRandom(): crea un objeto secure random y lo inicializa automáticamente.
SecureRandom(byte[]): crea un objeto secure random y lo inicializa utilizando
la semilla indicada en el array de bytes.
Una vez tenemos un objeto SecureRandom, podemos utilizar los siguientes métodos:
setSeed(byte[]): Reinicializa el SecureRandom utilizando la semilla indicada en
el array de bytes.
setSeed(long): Reinicializa el SecureRandom utilizando los ocho bytes del long
indicado.
next(int):Devuelve un entero conteniendo el número indicado de bits pseudoaleatorios.
Key
El interface Key es el interface de mas alto nivel de todas las claves y define la
funcionalidad compartida por todas las claves.
146
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.16. ENCRIPTACIÓN
PublicKey y PrivateKey
Los interfaces PublicKey y PrivateKey son interfaces sin métodos, que derivan de
la interface Key, utilizados solamente para comprobación de tipos.
KeyPair
La clase KeyPair es simplemente un contenedor de un par de claves (una pública
y una privada). Tiene dos métodos:
PrivateKey getPrivate(): Devuelve la clave privada.
PublicKey getPublicKey(): Devuelve la clave pública.
KeyPairGenerator
La clase KeyPairGenerator se utiliza para crear un par de claves. Para crear
objetos KeyParGenerator usaremos uno de los siguientes métodos:
KeyPairGenerator getInstance(String algorithm): crea un generador de claves
utilizando el algoritmo criptografico indicado.
KeyPairGenerator getInstance(String algorithm, String provider): crea un generador de claves utilizando el algoritmo criptografico indicado del proveedor
indicado.
Identity
La clase Identity se utiliza para manejar identidades. Para crear identidades usaremos el constructor siguiente:
Identity(String nombre): crea una identidad con el nombre indicado.
Signer
La clase Signer deriva de la clase Identity, y se utiliza para manejar identidades
capaces de firmar datos.
r
GVA-ELAI-UPMPFC0075-2003
147
CAPÍTULO 4. PROGRAMACIÓN EN JAVA
Fernando Ballesteros Herranz
Signature
La clase Signature se utiliza para crear o verificar firmas. Para crear objetos Signature usaremos uno de los siguientes métodos:
Signature getInstance(String algorithm): crea un objeto firma utilizando el algoritmo criptografico indicado.
Signature getInstance(String algorithm, String provider): crea un objeto firma
utilizando el algoritmo criptografico indicado del proveedor indicado.
4.16.2.
Extensión criptográfica de Java (JCE)
El JCE extiende el proveedor “SUN” e incluye una implementación de los algoritmos DES, 3DES, los modos ECB y CBC, y el estilo de relleno PKCS#5. Para utilizar
otros algoritmos deberemos utilizar otro proveedor que los implemente. (Para utilizar
el algoritmo RSA nosotros utilizaremos la libreria CRYPTIX).
SecretKey
La interface SecretKey es una interface sin métodos, que deriva de la interface
Key, utilizada solamente para comprobación de tipos.
KeyGenerator
La clase KeyGenerator se utiliza para crear una clave secreta. Para crear objetos
KeyGenerator usaremos uno de los siguientes métodos:
KeyGenerator getInstance(String algorithm): crea un generador de claves utilizando el algoritmo criptografico indicado.
KeyGenerator getInstance(String algorithm, String provider): crea un generador
de claves utilizando el algoritmo criptografico indicado del proveedor indicado.
148
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
4.17. CONCLUSIONES
Cipher
La clase Cipher se utiliza para cifrar o descifrar datos. Para crear objetos Cipher
usaremos uno de los siguientes métodos:
Cipher getInstance(String algorithm): crea un objeto Cipher utilizando el algoritmo criptografico indicado.
Cipher getInstance(String algorithm, String provider): crea un objeto Cipher
utilizando el algoritmo criptografico indicado, del proveedor indicado.
4.17.
Conclusiones
El lenguaje Java puede no ser tan potente como lo pueda ser C++ gracias a los
punteros, pero la forma de programar es mucho más simple, rápida y encapsulada de
lo que puede ser C++. Es un lenguaje orientado a objetos más sencillo de aprender
que C++, y además es más rápido y eficiente. También hay que mencionar que con
Java se pueden hacer dos tipos de programas, aplicaciones completas y Applets. Es
un sistema multihilo y es fácel de aprender como administrar las prioridades de los
hilos. Da mejor soporte para las aplicaciones para internet, ya que uno de los campos
más fuertes de este leguaje son los Applets. Las conexiones y envı́o de información a
través de la red es verdaderamente muy fácil.
En la creación de GUI, java ha avanzado mucho con los nuevos componentes
Swing haciendo más facil la programaión de éstos. Gracias a la Máquina Virtual
de Java, todas las aplicaciones desarrollas en este lenguaje pueden funcionar bajo
cualquier plataforma o sistema operativo, siendo por lo tanto multiplataforma. El
único impedimento de esto es que para que funcionen las aplicaciones previamente
hay que instalar la JVM, lo que trae consigo una molestia más para los usuarios de
estos programas.
r
GVA-ELAI-UPMPFC0075-2003
149
Capı́tulo 5
Estudio de librerı́as JDT
[SOFT] [TIANI]
5.1.
Introducción
Java DICOM Toolkit es la ayuda para un programador en JAVA para construir
una aplicación que siga lo marcado por el estándar DICOM 3.0. Combina las ventajas
y la fuerza de DICOM y JAVA en una API muy fácil de usar. Proporciona numerosas
clases y métodos que simplifican la programación de aplicaciones DICOM.
JDT1 es el primer equipo de desarrollo de software DICOM que está implementado totalmente en JAVA. Con esto, los desarrolladores DICOM pueden beneficiarse de
las numerosas ventajas del lenguaje de programación JAVA y desplegarlo en DICOM
applets, aplicaciones independientes JAVA y en software de servidor. JDT viene con
una API bien documentada que ha sido diseñada para hacer que la estructura compleja del estándar DICOM sea más accesible para los desarrolladores. JDT funciona
sobre JDK 1.1.X y JAVA 2.
5.2.
Terminologı́a
En esta sección se usa palabras como conjunto de datos (Dataset) y atributos.
Conjunto de datos se usa para identificar una colección de atributos DICOM. Un
1
Java Dicom Toolkit
151
CAPÍTULO 5. ESTUDIO DE LIBRERÍAS JDT
Fernando Ballesteros Herranz
atributo se identifica por su par (número de grupo, número de elemento), y tiene un
cierto tipo DICOM (value representation - VR).
5.3.
5.3.1.
Datasets o conjunto de datos
Introducción
En JDT, todos los conjuntos de datos están representados por com.archimed.
dicom.DicomObject. Esta clase es una subclase de com.archimed.dicom.GroupList.
Básicamente es donde residen los atributos DICOM com.archimed.dicom.TagValue.
5.3.2.
Manipulación de los atributos
Un conjunto de datos DICOM es representado por un objeto de la clase DicomObject. Los diferentes atributos de estos conjuntos de datos están internamente almacenados en el DicomObject como objetos com.archimed.dicom.Tagvalue. El objeto
TagValue contiene un par (grupo,elemento) y los valores del atributo están almacenados en un Vector. El tamaño del Vector corresponde a la multiplicidad del atributo.
El tipo JAVA que representa el valor de un atributo depende del tipo DICOM (Value Representation - VR) definido para ese atributo especı́fico. Las tablas 5.1 y 5.2
muestra la equivalencia entre los tipos DICOM y sus correspondientes tipos JAVA.
Figura 5.1: Conversión entre tipo Java y tipo DICOM
152
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
5.3. DATASETS O CONJUNTO DE DATOS
Manipulación de atributos simples
Hay un número de métodos set/get en DicomObject con los que se pueden meter,
sacar o modificar los atributos guardados en un DicomObject. La forma de hacer
esto es con la clase com.archimed.dicom.DDict. La clase DDict tiene una constante
definida para cada atributo definido en el estándar DICOM. Por ejemplo:
DDict.dPatientName
DDict.dAccessionNumber
Esas constantes pueden ser usadas en los métodos set/get del DicomObject:
Person p = (Person)dcm.get(DDict.dPatientName);
Integer acnumber = (Integer)dcm.get(DDict.dAccessionNumber);
dcm.set(DDict.dPatientName, new Person("Fernando"));
dcm.set(DDict.dAccessionNumber, new Integer(12345));
El método set implı́citamente convierte el valor del argumento dado al tipo DICOM
correcto.
También se puede acceder a los atributos de un DicomObject a través del par
(grupo.elemento).
Person p = (Person)dcm.get ge(0x0010, 0x0010);
Integer acnumber = (Integer)dcm.get ge(0x0008,0x0050,
DDict.dAccessionNumber);
dcm.set ge(0x0010, 0x0010, new Person("Fernando"));
dcm.set ge(0x0008, 0x0050, new Integer(12345));
Hay también dos métodos get que convierten directamente a String o int:
String s = dcm.getS(DDict.dPatientName);
int i = dcm.getI(DDict.dAccessionNumber);
Para manipular atributos con una multiplicidad mayor de uno, se usan los métodos get/set con un argumento adicional. La multiplicidad de un atributo se obtiene
con getSize(). Por ejemplo, suponiendo que un DicomObject dcm contiene un atributo ImageType con multiplicidad 2 y valores DERIVED/SECONDARY, entonces se
puede coger esos valores de la siguiente forma:
r
GVA-ELAI-UPMPFC0075-2003
153
CAPÍTULO 5. ESTUDIO DE LIBRERÍAS JDT
Fernando Ballesteros Herranz
int multiplicity = dcm.getSize(DDict.dImageType);
//devuelve el valor 2
String str1 = (String)dcm.get(DDict.dImageType,0);
//devuelve el valor DERIVED
String str2 = (String)dcm.get(DDict.dImageType,1);
//devuelve el valor SECONDARY
Insertando el valor de un atributo ocurre lo mismo:
dcm.set(DDict.dImageType,0,"DERIVED");
dcm.set(DDict.dImageType,1,"SECONDARY");
Secuencias
Las secuencias se tratan de una forma parecida que los valores de multiplicidad
mayor de uno. Cuando un atributo en un DicomObject representa una secuencia (tipo
SQ DICOM), entonces los “items” de la secuencia pueden ser insertados y cogidos
con los mismos métodos get/set del DicomObject que ahora aceptan y devuelven los
DicomObejcts completos. Por ejemplo, suponiendo que el DicomObject dcm contiene
un atributo DirectoryRecordSequence con un cierto número de items:
int numberofitems = dcm.getSize(DDict.dDirectoryRecordSequence);
DicomObject item0 = (DicomObject)dcm.get
(DDict.dDirectoryRecordSequence,0);
DicomObject item1 = (DicomObject)dcm.get
(DDict.dDirectoryRecordSequence,1);
Para añadir un valor a una secuencia, simplemente se usa el método set que tiene
el DicomObject que representa el item y el ı́ndice del item.
Son accesibles con las mismas funciones get/set de las secuencias como las usadas en los datasets de los DicomObject. Esto provee a las secuencias de la misma
funcionalidad que los DicomObject.
Para un rápido acceso, hay una utilidad de la clase com.archimed.dicom.tools.
Sequences que contiene varios métodos para acceder a las secuencias. También cuida
de todas las diferentes excepciones encontradas. El nombre elegido para los métodos
son muy similares que los encontrados en el DicomObject.
Comentarios:
154
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
5.3. DATASETS O CONJUNTO DE DATOS
las longitudes de los grupos no se almacenan en un DicomObject, se calculan
cuando se necesitan, ası́ que no hay acceso a ellos.
cuando usamos set para insertar valores de atributos, los valores se alamacenan
por referencia y no se copian.
cuando usamos get para sacar valores de atributos, se devuelve una referencia
al valor.
Manipulación de grupos de atributos
Para usuarios que quieran manipular los grupos enteros del conjunto de datos,
hay el acceso al grupo proporcionado por com.archimed.dicom.GroupList, el cual es
la superclase de com.archimed.DicomObject. Un grupo es un conjunto de atributos
que tienen el mismo número de grupo en su par (grupo,elemento).
DicomObject copyGroup(int groupnr)
Copia el grupo con el número groupnr y lo devuelve como un DicomObject nuevo.
Notar que sólo se hace una copia no profunda, sólo se copian referencias a los atributos.
void addGroups(DicomObject o)
Agrega a todos los grupos encontrados en “o” a este dataset. Solamente agregan
a los grupos que no estaban ya presentes en este dataset. Una vez más solamente se
hace una copia baja o no profunda.
DicomObject removeGroup(int groupnr)
Suprime un grupo entero con el número “groupnr” de este dataset. Y lo devuelve
como un DicomObject.
5.3.3.
Entrada/Salida de los datasets DICOM
Hay varias formas de leer o escribir datasets DICOM a y desde InputStreams /
OutputStreams. En ambos casos hay un método básico y algunos métodos más que
permiten especificar todas las clases de parámetros.
r
GVA-ELAI-UPMPFC0075-2003
155
CAPÍTULO 5. ESTUDIO DE LIBRERÍAS JDT
Fernando Ballesteros Herranz
Leer datasets
void read(java.io.InputStream in)
Este método lee todos los atributos DICOM desde un inputStream de un DicomObject. El inputStream puede contener tanto un archivo DICOM como un conjunto
de datos (datasets) DICOM. Cuando el inputStream contiene un archivo de la parte
10 DICOM, se lee y se almacena la Meta File Information en un DicomObject separado que se puede coger mediante getFileMetaInformation(). La transfer syntax se
asume que es Implicit VR Little Endian cuando el inputStream contiene un conjunto de datos DICOM. Cuando el inputStream contiene un archivo de la parte 10 de
DICOM, el transfer syntax se detecta desde la File Meta Information.
void read(java.io.InputStream in, boolean process)
Este método hace igual que el anterior pero además permite especificar si analizar
o saltar datos de pı́xel. Esto ahorra el tiempo de transformación en el que no se
necesita los datos de pı́xel.
void read(java.io.InputStream in, int ts, boolean process)
En el parámetro “ts” se puede especificar qué transfer syntax se usa. Este parámetro
puede venir dado cuando se conoce por adelantado con qué transfer syntax se codificó el dataset.
Escribir datasets
void write(java.io.OutputStream out, boolean f)
Éste es el método más básico de la exportación. Si el argumento f se fija como
“true”, el dataset se codifica en un archivo de la parte 10 de Dicom (archivo Dicom).
En este caso, la File Meta Information se usa si está presente, o se crea cuando
es necesitada. Observar que la creación de la meta information puede lanzar una
excepción, cuando los atributos requeridos faltan (SOP Class UID, SOP Instance
UID).
void write(java.io.OutputStream out, boolean f,
int ts, boolean seq_undef)
156
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
5.3. DATASETS O CONJUNTO DE DATOS
Los parámetros adicionales “ts” y “seq_undef” se pueden utilizar para escribir
conjunto de datos casi en todos los posibles tipos de DICOM. Los parámetros ts y
seqUndef pueden ser usados para insertar la Transfer Syntax. Toda posible combinación de parámetros ts y f se permiten, pero no todas las combinaciones siguen los
dictados del estándar de DICOM. Si se escribe un conjunto de datos con f “false” y ts
otra cosa que no sea Implicit VR Little Endian, será imposible para otras aplicaciones
decodificarlo ya que no pueden detectar el Transfer Syntax usado. El parámetro seqUndef indica al escribir secuencias si se usa longitud undefinida (true) o definida
(false).
Visualización de datasets
DicomObject contiene dos métodos para mostrar todos los atributos contenidos
en un OutputStream de forma ordenada para que el ser humano sea capaz de leerlo.
void dumpVRs(java.io.OutputStream os)
void dumpVRs(java.io.OutputStream os, boolean metainfo)
Poner “metainfo” como “true” si se quiere ver la File Meta Information.
Ejemplos
Estos trozos de código demuestran el fácil uso de JDT. Con sólo unas lı́neas de
código, es posible construir soluciones DICOM poderosas.
El código siguiente lee un archivo DICOM desde un archivo y muestra los atributos
(incluidos los contenidos en la meta information si existe) por la pantalla.
DicomObject dcm = new DicomObject;
dcm.read(new FileInputStream("foo.dcm"));
dcm.dumpVRs(System.out, true);
El siguiente ejemplo lee los datos de un archivo y lo escribe en otro archivo usando
una transfer syntax y una secuencia de codificación especı́ficas.
DicomObject dcm = new DicomObject;
dcm.read(new FileInputStream("in.dcm"));
dcm.write(new FileOutputStream("out.dcm"), true,
TransferSyntax.ExplicitVRBigEndian, true);
r
GVA-ELAI-UPMPFC0075-2003
157
CAPÍTULO 5. ESTUDIO DE LIBRERÍAS JDT
5.3.4.
Fernando Ballesteros Herranz
Métodos útiles
Enumeración de los atributos de un dataset
Con el método enumerateVRs es posible conseguir una enumeración (clase de java)
de todos los atributos sontenidos en un DicomObject.
Enumeration e = dcm.enumerateVRs(false);
enumerateVRs() devuelve una enumeración de todos los atributos de dcm como
objetos TagValue. TagValue tiene métodos para coger el valor y el par (grupo,elemento)
de un atributo.
File Meta Information
DicomObject fmi = dcm.getFileMetaInformation();
Devuelve la File Meta Information del DicomObject dcm si existe. Se puede usar
ahora fmi para añadir o alterar atributos especı́ficos de esta información como se
quiera.
Información general
Unos pocos métodos de com.archimed.dicom.GroupList proporcionan información
general sobre un conjunto de datos:
int numberOfElements(): devuelve el número total de atributos.
int numberOfGroups(): devuelve el número total de grupos.
boolean isEmpty(): devuelve si el GroupList contiene algún atributo.
boolean containsGroup(int g): devuelve si el GroupList contiene el grupo especificado.
158
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
5.4.
5.4. DEPÓSITOS
Depósitos
Hay unas clases en el paquete com.archimed.dicom que hacen más fácil a los programadores usar los data elements y los registros UIDs.
5.4.1.
Clase DDict: depósito de atributos
La clase com.archimed.dicom.DDict es un almacen de los VRs (value representations) y los data elements. Contiene un número de constantes que representan los
diferentes VRs y un gran conjunto de constantes para los data elements:
DDict.tPN //representa el tipo DICOM PERSON.
DDict.tUS //representa el tipo DICOM UNSIGNED SHORT.
DDict.dAccesionNumber //representa el atributo AccessionNumber.
DDict.dPatientName //representa el atributo PatientName.
Los métodos de DDict
La clase DDict tiene métodos para obtener el par (grupo,elemento) de un atributo,
un tipo de atributo, una descripción del atributo y para consultar una constante DDict
del atributo basada en su par (grupo,elemento).
static int getGroup(int dct)
Devuelve el número de grupo para una constante DDict que representa un atributo.
static int getElement(int dct)
Devuelve el número de elemento para una constante DDict que representa un
atributo.
static int getTypeCode(int dct)
r
GVA-ELAI-UPMPFC0075-2003
159
CAPÍTULO 5. ESTUDIO DE LIBRERÍAS JDT
Fernando Ballesteros Herranz
Devuelve el tipo para una constante DDict que representa un atributo. Los elementos de datos que no están en la lista de arriba tendrán un DDict.tUNKNOWN.
static java.lang.String getDescription(int dct)
Da una descripción elaborada para una constante DDict que representa un atributo.
static int lookupDDict(int g, int e)
Devuelve la constante DDict que representa el atributo con número de grupo “g”
y número de elemento “e”. Si no se encuentran constantes, el método devolverá DDict
.dUNDEFINED.
5.4.2.
Clase UID: depósitos UID
La clase com.archimed.dicom.UID contiene un depósito de los UIDs DICOM registrados (Parte 6 DICOM).Las constantes que representan los UIDs y que tienen que
ser usadas a través de JDT se definen en subclases de UID:
com.archimed.dicom.TransferSyntax: constantes que representan las transfer syntax.
com.archimed.dicom.SOPClass: constantes que representan las clases SOP.
com.archimed.dicom.MetaSOPClass: constantes que representan las clases Meta
SOP.
com.archimed.dicom.SOPInstance: constantes que representan las instancias SOP.
El objeto com.archimed.dicom.UIDEntry representa un único identificador y se
obtiene con la clase UID de dos formas. Usando una constante de una de las subclases
UID:
UIDEntry entry = UID.getUIDEntry(TransferSyntax.JPEGBaseline);
o usando una cadena UID:
160
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
5.5. IMÁGENES EN JDT
UIDEntry entry = UID.getUIDEntry("1.2.840.10008.1.2.4.50");
Cada uno de esos métodos de consulta devuelve un objeto UIDEntry, el cual es
un contenedor de varias propiedades del identificador único especı́fico. Esos atributos
pueden ser obtenidos usando los métodos get.
5.5.
Imágenes en JDT
Esta parte habla de las capacidades de imagen de JDT. Todas las clases relacionadas con las imágenes pueden ser encontradas en el paquete com.archimed.dicom.image.
5.5.1.
La clase DicomImage
La clase base para las imágenes es com.archimed.dicom.image.DicomImage. A
parte de los métodos set/get básicos para manipular los datos, inherentes al DicomObject, contiene otras formas de coger e insertar los atributos requeridos (tipo
1 y tipo 2) que son comunes a todos los DICOM Image Modality IODs (ver parte
3 de DICOM). Cuando se escribe una DicomImage en un outputstream, no hay un
reconocimiento de si todos los atributos requeridos están presentes.
5.6.
5.6.1.
Guı́a para usuarios de JDT
Insertar datos que no son de imagen
DicomImage contiene un número de métodos para insertar los atributos requeridos
que no están relacionados con los datos de imágen. Una corta descripción son estos
métodos:
void patientData(String patientName, String patientID, String birthDate, String
sex): inserta los datos del paciente.
void generalStudyData(String instanceUID, String date, String time, String physName, String studyID, String orderNumber): inserta los atributos del estudio
general.
r
GVA-ELAI-UPMPFC0075-2003
161
CAPÍTULO 5. ESTUDIO DE LIBRERÍAS JDT
Fernando Ballesteros Herranz
generalSeriesData(String modality, String instanceUID, String seriesNumber):
añade los datos generales de serie.
generalEquipmentData(String manufacturer): añade datos sobre el equipo utilizado.
generalImageData(String imageNumber): añade datos de imagen.
sopCommonData(String sopClassUID, String sopInstanceUID): inserta los datos
comunes SOP. SOP Class UID es tı́picamente uno de las diferentes image storage
SOP Classes, que pueden ser encontrados en com.archimed.dicom.SOPClass.
5.6.2.
Insertar datos de imagen con los métodos de DicomImage
Hay también métodos en com.archimed.dicom.image.DicomImage que pueden ser
usados para insertar los datos de los pı́xeles de la imagen. La clase contiene métodos
para imágenes en escala de grises, en paleta de colores y en RGB. Una definición de
todos los parámetros pueden ser encontrados en la API.
DicomImage dcmi = new DicomImage();
byte[] pixels = new byte[640*480]; // rellena este array con pı́xeles.
byte[] red = new byte[256]; // rellena este array con un LUT rojo.
byte[] green = new byte[256]; // rellena este array con un LUT verde.
byte[] blue = new byte[256]; // rellena este array con un LUT azul.
dcmi.imagePixelData(480, 640, pixels, red, green, blue);
Esto da una DicomImage con una interpretación fotométrica PALETTE COLOR,
tamaño 640x480 y con una profundidad de pixel de 8.
5.6.3.
Insertando los datos de imagen con ImageProducer
Hay otra forma de insertar los datos de la imagen. Dado una “ImageProducer ip”,
construyendo un objeto ImageIO y usando el método setImageProducer() para copiar
los datos de imagen desde la ImageProducer a la DicomImage:
DicomImage dcmi = new DicomImage();
ImageIO imgio = new ImageIO(dcmi);
imgio.setImageProducer(ip);
162
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
5.6. GUÍA PARA USUARIOS DE JDT
Cuando se llama al método setImageProducer(), todos los datos se copian dentro
de la DicomImage.
Obteniendo una ImageProducer desde una DicomImage es también posible. Todo
marco simple de una imagen DICOM se puede coger como una ImageProducer usando
uno de los métodos siguientes:
java.awt.image.ImageProducer getImageProducer()
java.awt.image.ImageProducer getImageProducer(int i)
java.util.Vector getImageProducers()
Para imágenes de escalas de grises con profundidad de pixel mayor que 8 bits, hay
un color model (clase de java) especial com.archimed.dicom.image.GrayColorModel.
Este color model se usa en combinación con un array int de pı́xeles, para producir
imágenes de 256 grises sin pérdida de datos. Con este GrayColorModel, también es
posible meter el Window/Level usado en la producción de la imagen.
no-comprimido transfer syntax, una imagen: un array de bytes que mantiene el
formato original de los datos de pixel definido en el estándar DICOM, ejemplos:
• imagen MONOCHROME2, 8 bits asignados, 8 bits alamcenados: 1 elemento del array de bytes por pixel.
• imagen MONOCHROME2, 16 bits asignados, 12 bits alamcenados: 2 elementos consecutivos del array de bytes por pixel.
• imagen MONOCHROME2, 12 bits asignados, 12 bits alamcenados: 1 elemento y medio del array de bytes por pixel.
• imagen RGB, configuración plana color por pixel: 3 bytes consecutivos
representando 1 pixel.
• imagen RGB, configuración plana color por plano: el array de bytes está dividivo en 3 partes de igual longitud cada una representando un color de
plano (Red-Green-Blue).
Los array de bytes se cogen e insertan con los métodos get(DDict. dPixelData)
y set(DDict.dPixelData,¡byte array¿) respectivamente.
no-comprimido transfer syntax, varias imágenes: un array de bytes que contienen
marcos consecutivos.
comprimido transfer syntax, una imagen: un array de bytes en el formato original de compresion.
r
GVA-ELAI-UPMPFC0075-2003
163
CAPÍTULO 5. ESTUDIO DE LIBRERÍAS JDT
5.6.4.
Fernando Ballesteros Herranz
Compresión
Los datos de pı́xel de una imagen DICOM se almacena en el atributo DDict.dPixelData.
Cuando una imagen DICOM comprimida se lee desde un inputstream, los pixeldata
no se decodifican pero se almacenan internamente en arrays de bytes en su formato
de compresión por razones de rendimineto. El tipo de codificación puede ser sacado
de la sintaxis de transferencia en el File Meta Information.
DcmObject dcm = new DicomObject();
dcm.read(new FileInputStream("c://encodedimage.dcm"));
DicomObject fmi = dcm.getFileMetaInformation();
UIDEntry tsentry = UID.getUIDEntry(fmi.get(DDict.
dTransferSyntaxUID));
System.out.println("encoding: "+ tsentry.getName());
Una utilidad de la clase com.archimed.dicom.codec.Compression proporciona un
número de decodificadores:
JPEG baseline
JPEG lossless
RLE Lossless
Todos los decodificadores están limitados a 8 bits por pı́xel. El decodificador JPEG
puede manejar 1 o 3 muestras por pı́xel. RLE es sólo capaz de descomprimir 1 muestra
por pı́xel. El camino más fácil para descomprimir imagen entera DICOM es construir
un objeto Compression desde un DicomObject y después llamar al método decompress. Éste descodifica los datos del array de pı́xeles del DicomObject y los reemplaza
por los datos descomprimidos.
En el caso de una imagen DICOM multimarco, se puede decodificar el array de
bytes correspondioente a un marco individual. Primero obteniendo un array de bytes
de un marco con get(DDict.dPixelData, ¡index of frame¿) y luego usando el método
estático decompressframe() del objeto Compression para obtener un array de bytes
decodificado desde el array de bytes comprimido.
static byte[] decompressframe(int encoding, byte[] frame,
int width, int heigth);
Los argumentos de codificación, ancho y alto que tienen que ser suministrados
para usar decompressframe() se encuentran en la imagen DICOM original.
164
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
5.7.
5.7. CREACIÓN DE UNA CONEXIÓN
Creación de una conexión
Para establecer una asociación con una entidad del par DICOM, se hace uso
las clases del paquete com.archimed.dicom.network.. Es necesario un iniciador de la
asociación y un receptor de la asociación.
5.7.1.
Iniciador de la asociación
Pasos a seguir para crear un iniciador de una asociación DICOM.
1. Hacer una conexión TCP/IP con la entidad del par DICOM que hace uso las
clases estándares de java.net. En este ejemplo el servidor es “Fourier” y el puerto
104.
Socket s = new Socket("Fourier",104);
2. Crear un objeto “Association” con los Input and Output Streams derivadas de
Socket.
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
Association as = new Association(in,out);
3. Preparar un objeto “Request” con los parámetros necesarios para establecer una
asociación. Los parámetros son al menos un tı́tulo de la entidad de la aplicación
llamada (called), un tı́tulo de la entidad de la aplicación llamar (calling) y un
abstract syntax con un sintaxis de transferencia. En el ejemplo el tı́tulo de la
entidad called es “hola” y el calling es “Servicio”. Estos tı́tulos no deben ser más
de largos de 16 caracteres. Conectamos con “hola” para almacenar una imagen
secundaria de la captura con Implicit Little Endian transfer syntax.
Request request = new Request();
request.setCalledTitle("hola");
request.setCallingTitle("Servicio");
int[] transfersyntaxes = {TransferSyntax.
ImplicitVRLittleEndian};
request.addPresentationContext(SOPClass.
SecondaryCaptureImageStorage, transfersyntaxes);
4. Se envı́a la petición a la entidad del par DICOM y recibe la respuesta.
r
GVA-ELAI-UPMPFC0075-2003
165
CAPÍTULO 5. ESTUDIO DE LIBRERÍAS JDT
Fernando Ballesteros Herranz
as.sendAssociateRequest(request);
Response response = as.receiveAssociateResponse();
5. Analiza la respuesta. Se comprueba si se acepta, se rechaza o se aborta nuestra
petición.
if (response instanceof Reject)
{
System.out.println("petición de asociación rechazada");
System.out.println(response);
}
else if (response instanceof Abort)
{
System.out.println("petición de asociación abortada");
System.out.println(response);
}
else
{
System.out.println("petición de asociación aceptada");
Acknowledge ack = (Acknowledge)response;
if (ack.getPresentationContexts() != 1)
{
System.out.println("número incorrecto de Contexto
de Presentación");
throw something;
}
int result = ack.getResult(0);
if (result == Acknowledge.ACCEPTANCE)
{
System.out.println("Contexto de Presentación para
Secondary Capture aceptada");
}
else if (result == Acknowlege.ABSTRACT_SYNTAX_NOT_SUPPORTED)
{
System.out.println("Secondary Capture no soportada");
}
else if (result == Ackn...
...
}
6. En este punto se tiene una asociación válida para el Secondary Capture Image
Storage y podemos enviar imágenes SC a la entidad del par DICOM.
DicomObject cstorerequest;
166
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
5.7. CREACIÓN DE UNA CONEXIÓN
DicomObject cstoreresponse;
DicomObject scimage;
// crear una petición C-STORE en la variable cstorerequest
// y una instancia SOP Secondary Capture en la variable scimage.
...
// enviar la imagen al par de entidad DICOM
as.send(SOPClass.SecondaryCapture,cstorerequest,scimage);
// recibir la respuesta C-STORE desde el par de entidad DICOM.
cstoreresponse = as.receiveCommand();
// analizar cstoreresponse para ver si la imagen SC enviada,
// se ha guardado bien.
...
7. Acabar asociación.
as.sendReleaseRequest();
as.receiveReleaseResponse();
5.7.2.
Receptor de la asociación
Cuando una aplicación actúa como receptor de la asociación, espera conexiones
entrantes de TCP/IP con el método de accept() de java.net.ServerSocket y dedica un
hilo para cada conexión entrante. En este ejemplo se empieza con el punto donde una
entidad del par DICOM ha hecho una conexión de TCP/IP, dando por resultado un
objeto válido de java.net.Socket que es devuelto por el método accept(). El código del
ejemplo se ejecuta normalmente en diferentes hilos en los cuales el método accept()
los ejecuta.
Pasos a seguir para crear un receptor de una asociación DICOM.
1. Obtener el InputStream/OutputStream del objeto de java.net.Socket devuelto
por el accept() y crear un nuevo objeto Association.
r
GVA-ELAI-UPMPFC0075-2003
167
CAPÍTULO 5. ESTUDIO DE LIBRERÍAS JDT
Fernando Ballesteros Herranz
// s es el Socket devuelto por accept()
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
Association as = new Association(in,out);
2. Se lee la petición de asociación y se crea la respuesta apropiada para la petición.
Se hace en el ejemplo el servicio “Service Class Provider for Secondary Capture
Image Storage y Verification” y nuestro tı́tulo de la entidad de aplicación es
= “hola”. No se comprueba el tı́tulo de la entidad de aplicación del llamador
(calling title).
Request request = as.receiveAssociateRequest();
System.out.println("incoming association request");
System.out.println(request);
int[] abstractsyntaxes = {SOPClass.
SecondaryCaptureImageStorage,SOPClass.Verification};
Response response = ResponsePolicy.
prepareResponse(request,"hola",null,abstractsyntaxes,
TransferSyntax.ImplicitVRLittleEndian,true);
as.sendAssociateResponse(response);
3. Si la respuesta es un “Reject” (Rechazo) se cierra la conexión. Si la respuesta
es “Acknowlwdge” (Reconocida) se entra es un lazo que reciba y procese la
verificación o Secondary Capture Image Storage relacionado con el comando
DIMSE. El lanzamiento de la asociación también se maneja en el lazo.
if (response instanceof Reject)
{
System.out.println("Petición de asociación Rechazada");
System.out.println(response);
s.close();
return;
}
else if (response instanceof Acknowledge)
{
int result;
com.archimed.dicom.DicomObject dcm;
String sopclass;
// Para un mejor manejo se almacena los
//SOP Class UIDs de SC y Verification en variables
String sc_sopclass = UID.getUIDEntry(SOPClass.
SecondaryCaptureImageStorage).getValue();
String ve_sopclass = UID.getUIDEntry(SOPClass.Verification).
getValue();
168
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
5.7. CREACIÓN DE UNA CONEXIÓN
while (true)
{
result = as.peek();
if (result == Association.PDATA_PDU)
{
dcm = as.receiveCommand();
sopclass = dcm.getS(DDict.dAffectedSOPClassUID);
if(sopclass.equals(sc_sopclass)
{
// Se chequea para ver si es una válida petición
// C-STORE, si es ası́ se leen los datos con
// receiveData(), se procesan los datos para el
// almacenaje y se envı́a una respuesta C-STORE
}
else if (sopclass.equals(ve_sopclass)
{
// Chequear si es una petición válida C-ECHO
// y enviar respuesta C-ECHO
}
else
{
System.out.println("sopclass " + sopclass +
" no negociada, abortado");
as.sendAbort(Abort.DICOM_UL_SERVICE_USER,
Abort.REASON_NOT_SPECIFIED);
s.close();
return;
}
}
else if (result == Association.RELEASE_REQUEST)
{
as.receiveReleaseRequest();
as.sendReleaseResponse();
s.close();
System.out.println("asociación acabada");
return;
}
else if (result == Association.ABORT)
{
Abort abort = as.receiveAbort();
s.close();
System.out.println("asociación acabada por el par");
System.out.println(abort);
r
GVA-ELAI-UPMPFC0075-2003
169
CAPÍTULO 5. ESTUDIO DE LIBRERÍAS JDT
Fernando Ballesteros Herranz
return;
}
}
}
5.8.
5.8.1.
Estructura de JDT
Árbol de clases
class java.lang.Object
class com.archimed.dicom.network.Association
class java.awt.image.ColorModel (implements java.awt.Transparency)
• class com.archimed.dicom.image.GrayColorModel
class com.archimed.dicom.codec.Compression
class com.archimed.dicom.DDate
class com.archimed.dicom.DDateRange
class com.archimed.dicom.DDict
class com.archimed.dicom.DDictEntry
class com.archimed.dicom.Debug
class com.archimed.dicom.network.DimseUtil
class com.archimed.dicom.network.ExtendedNegotiation
class com.archimed.dicom.GroupList
• class com.archimed.dicom.DicomObject
◦ class com.archimed.dicom.image.DicomImage
class com.archimed.dicom.image.SCImage
class com.archimed.dicom.image.ImageIO
class com.archimed.dicom.Jdt
170
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
5.8. ESTRUCTURA DE JDT
class com.archimed.dicom.Offsets
class com.archimed.dicom.Person
class com.archimed.dicom.network.Request
class com.archimed.dicom.network.Response
• class com.archimed.dicom.network.Abort
• class com.archimed.dicom.network.Acknowledge
• class com.archimed.dicom.network.Reject
class com.archimed.dicom.network.ResponsePolicy
class com.archimed.dicom.tools.Sequences
class com.archimed.dicom.TagValue
class java.lang.Throwable (implements java.io.Serializable)
• class java.lang.Exception
◦ class com.archimed.dicom.DicomException
◦ class com.archimed.dicom.IllegalValueException
◦ class com.archimed.dicom.UnknownUIDException
class com.archimed.dicom.UID
• class com.archimed.dicom.MetaSOPClass
• class com.archimed.dicom.SOPClass
• class com.archimed.dicom.SOPInstance
• class com.archimed.dicom.TransferSyntax
class com.archimed.dicom.UIDEntry
class com.archimed.dicom.image.WL
5.8.2.
Packages
Com.archimed.dicom.network
Abort (Abortar): Representa el aborto de una asociación. Los dos parámetros
son, la fuente y la razón del aborto.
r
GVA-ELAI-UPMPFC0075-2003
171
CAPÍTULO 5. ESTUDIO DE LIBRERÍAS JDT
Fernando Ballesteros Herranz
Acknowledge (Reconocer): Estos objetos tienen los parámetros de la asociación
Acknowledge, contiene todos los contextos de presentación del Acknowledge y
son numerados desde 0 hasta el no de contextos de presentación menos uno.
Puede actuar como receptor de asociación o como iniciador de la asociación.
Association (Asociación): Contiene métodos para construir y destruir una asociación entre dos entidades de aplicación DICOM y mandar/recibir comandos
y datos (data sets) una vez que la asociación está establecida.
DimseUtil: Las funciones DICOM que pueden hacerse.
ExtendedNegotiation: Representa los datos de negociación para un sintaxis abstracto
Reject (Rechazo): Representa el rechazo de una asociación. Sus parámetros son
fuente, resultado y razón.
Request (petición): Representa todos los parámetros relevantes de una asociación
Request. Contiene todos los contextos de presentación y son numerados desde 0
hasta el no de contextos de presentación menos uno. Puede actuar como receptor
de asociación o como iniciador de la asociación.
Response (Respuesta): Representa una respuesta de un par de entidades DICOM.
Las clases implementadas son: Reject, Acknowledge y Abort.
ResponsePolicy: contiene dos tipos de métodos:
• Métodos para creación de objetos Response, basados en una peticón dada
y una polı́tica de aceptación de la asociación.
• Métodos para el análisis de respuestas Acknowledge, en el contexto de una
petición dada.
Com.archimed.dicom.codec
Compression (compresión): Es una clase que proporciona métodos para la descompresión de datos de Pixel. DICOM soporta muchos tipos de técnicas de
compresión.
Com.archimed.dicom.image
DicomImage: Esta clase provee de métodos para construir una imagen Dicom.
GrayColorModel: Esta clase representa un ColorModel para el empleo con imágenes
de Escala de gris.
172
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
5.8. ESTRUCTURA DE JDT
ImageIO: Es una clase que proporciona métodos de convertir datos de imagen
almacenados a un ImageProducer (Productor de imagen) y viceversa.
SCImage: Esta clase proporciona métodos para construir una imagen SC.
WL: Es un contenedor básico para un par Ventana/Nivel.
Com.archimed.dicom.tools
Sequences: Estos objetos proveen los “atajos” para coger/poner valores dentro de secuencias. La conversión de valores está hecha usando el esquema de
conversión DicomType-JavaType dada en la clase DicomObject.
Com.archimed.dicom
DDate: Esta clase representa la fecha de un objeto, conteniendo el dı́a, mes y
año. Se ha desarollado en correspondencia al tipo Dicom DA. Es útil, cuando
se quiere buscar en una gama de fechas.
DDateRange: Esta clase representa la gama de fechas.
DDict: Esta clase provee de un diccionario (Diccionario de datos Dicom) para
los VRs y todos los elementos de datos. Cada par (grupo,elemento) es accesible por una variable static int. Por ejemplo, (0010,0010) es representado por
DDic.dPatientName.
DDictEntry: Un objeto para una etiqueta que puede ser almacenado en el diccionario de datos.
Debug: Proporciona una variable static int por si hay que imprimir información
de reparación de los errores a System.err.
DicomObject: Esta es la clase base de todos los datasets. Los métodos de acceso
proporcionados aquı́ son el modo de obtener/poner elementos de dato (data
elements) dentro de un objeto Dicom (DicomObject).
GroupList: Provee de métodos para el acceso de datos por grupo.
Jdt: Para obtener información sobre este Jdt
MetaSOPClass: Extensión de la clase UID.
Offsets (Compensación): Esta clase proporciona utilidades para calcular compensaciones en un DicomObject que va a ser escrito.
Person: Esta clase representa el PN (Person Name) en Dicom.
r
GVA-ELAI-UPMPFC0075-2003
173
CAPÍTULO 5. ESTUDIO DE LIBRERÍAS JDT
Fernando Ballesteros Herranz
SOPClass: Extensión de la clase UID.
SOPInstance: Extensión de la clase UID.
TagValue: Representa un par (grupo, elemento) y su valor.
TransferSintax: Extensión de la clase UID.
UID: Esta clase contiene un depósito de todos los UIDs Dicom certificados.
Cada UID está en función del Transfer Syntax, SOPClass, MetaSOPClass y
SOPInstance.
UIDEntry: Representa la entrada de un UID en el depósito, almacenándose.
DicomExcepcion: Indica que la aplicación ha violado la estructura y codificación
del Dicom Data.
IllegalValueExcepcion: Indica que un valor ilegal es leı́do durante una asociación
o cuando un valor ilegal es argumento de un método.
UnknownUIDExcepcion: Indica que el UID incluido no está definido en la clase
UID.
5.9.
Conclusiones
Una vez trabajado y experimentado con los dos toolkit de DICOM (dcmtk y JDT),
se llegan a las siguientes conclusiones:
El toolkit dcmtk351 cuenta con la ventaja de ser un producto gratuito, pero si
no se es un gran experto en materia DICOM y en programación en C++, la profundización de su estudio es muy complicada y engorrosa, debido a la poca documentación
proporcionada con dicha herramienta y a la gran dificultad y amplitud del código.
Por el contrario, JDT es un producto no gratuito, pero cuenta con las grandes
ventajas que el toolkit dcmtk351 no tiene. Lo primero a señalar es que el lenguaje
de programación es JAVA, con las ventajas que conlleva con respecto a C++. Por
otro lado, contiene una documentación amplia y muy bien estructurada, gracias a la
utilidad de javadocs, lo que facilita enormemente el trabajo y su comprensión. JDT
contiene un árbol de clases, información de los diferentes packages, información sobre
las clases y sus métodos.
La elección después de trabajar con los dos Toolkit ha sido el Java Dicom Toolkit
(JDT), ya que es más fácil de utilizar y debido a la creación de un Cliente/Servidor
para la Red, las aplicaciones en Java son más fáciles y potentes.
174
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
5.9. CONCLUSIONES
Figura 5.2: Conversión de tipo DICOM a tipo Java
r
GVA-ELAI-UPMPFC0075-2003
175
Capı́tulo 6
Desarrollo de aplicación
6.1.
Introducción
En este capı́tulo se describen las herramientas usadas para la implementación de
la aplicación DICOM, tanto del cliente como del servidor.
Para estas dos aplicaciones hay que elegir el entorno de desarrollo a utilizar.
Pueden ser utilizados múltiples sistemas como TextPad, Visual J++, el propio JDK
o JBuilder.
El primero en analizar es el que viene incluido en el SDK, que es el JDK. Éste
compilador es utilizable con cualquier editor de texto, pero es inadecuado para proyectos largos, por su pesadez textual y poca ayuda. Este compilador fue el primero en
utilizarse, pero debido a la extensión del proyecto realizado se tuvo que mirar otros
compiladores.
El Visual J++ es el entorno de trabajo de Java proporcionado por Microsoft.
También se utilizó pero al querer que el programa fuera multiplataforma y no perder
el potencial de Java, se decidió cambiar a otro entorno.
El TextPad fue el elegido para la creación de la aplicación Servidor, ya que es
un compilador parecido al JDK, pero con más ayudas y menos pesadez a la hora de
programar.
El JBuilder de Borland fue utilizado para deserrollar el Cliente, ya que trae un
buen soporte a para la implementación de las GUIs. Éste entorno de desarrollo es
mucho más completo, especı́fico y con muchas más prestaciones que Visual J++.
177
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Por lo tanto para el desarrollo del Servidor se utiliza el compilador TextPad 4.7.0,
las librerı́as SDK v1.4.1, el paquete JCE para la encriptación/desencriptación y las
librerı́as DICOM JDT, mediante las cuales se va a implementar la aplicación DICOM.
Para el desarrollo del Cliente es necesaria la utilización del entorno de desarrollo
JBuilder (versión 7.0 Enterprise, pero compatible con la 8.0 y 9.0), las librerı́as del
SDK v1.4.1, el paquete JCE1 y las librerı́as DICOM JDT.
6.2.
Uso de SDK
6.2.1.
Introducción
En esta sección se van a ver los aspectos más importantes para la compilación de
archivos fuentes y se van a describir las herramientas más utilizadas en el trabajo con
Java.
Para poder realizar aplicaciones en Java es necesaria la instalación de las librerias de SDK. Este paquete de librerı́as viene con la Máquina Virtual de Java, para
poder desde cualquier archivo fuente (.java) poder crear una apliación. Esta máquina
virtual también es válida para poder visualizar y que se puedan ejecutar programas
desarrollados en java.
6.2.2.
Instalación en Windows 98
La instalación puede ser o bien sólo de la Máquina Virtual de Java(JRE Java Enviroment Enterprise), para poder ejecutar programas de Java pero no poder compilar
ficheros fuente, o bien la instalación de las librerı́as y la MVJ para poder ejecutar y
compilar programas Java.
Máquina Virtual de Java
Para la instalación de la Máquina Virtual de Java se debe descargar de la página
http://java.sun.com, teniendo que elegir la opción del JRE para Windows. Una vez
descargado el archivo “j2re-1_4_1_03-windows-i586-i.exe”, se procede a la instalación
la cual es muy sencilla. Únicamente hay que ejecutar el archivo nombrado, de esta
1
178
Java Cryptography Extension
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.2. USO DE SDK
forma la JVM está instalada y podemos ejecutar correctamente cualquier aplicación
desarrollada en Java.
SDK
La instalación a realizar son de las librerı́as de la última versión SDK 1.4.1 que se
puede descargar de la página (http://java.sun.com). Con la instalación de las librerı́as
viene incluida la JVM2 .
El primer paso a realizar es descargar el archivo, eligiendo la opción SDK para
Windows. Este archivo se llama “j2sdk-1_4_1_03-windows-i586.exe”.
El siguiente paso es ejecutar el archivo, de esta forma se generan las librerı́as y
los ejecutables de las utilidades que ofrece Java, como son el compilador javac.exe, el
javadocs,. . .
El tercer paso es el más importantes ya que aunque se tengan las librerı́as y los
ejecutables, hay que decir a la computadora donde están. Este paso es el que diferencia
Windows 95/98 con Windows NT/2000/XP. En Windows 98 hay que dar el PATH de
donde se encuentran los ejecutables y hay que crear un CLASSPATH donde debemos
dar el camino para llegar a las librerı́as del SDK. Los pasos para realizar esto son:
1. En el directorio raı́z del sistema operativo “C:\”, se encuentra el archivo “Autoexec.bat”. Este archivo se carga cuando se inicia la computadora. Para modificarlo, hay que abrir el archivo con un editor de texto, esto se puede hacer
haciendo click derecho mientras se pulsa Shift, y se elige Abrir con. . . . Saldrá un
menú y se debe elegir un editor de texto, por ejemplo el Bloc de Notas.
2. Una vez abierto, nos disponemos a escribir en el PATH. Hay una lı́nea en la
que pone “SET PATH”, pues en esa lı́nea debemos incluir el directorio bin del
sdk1.4.1. con lo que quedarı́a:
SET PATH = . . . ;C:\J2SDK1.4.1_03\BIN; %Path %
3. Ahora hay que crear el CLASSPATH. Para realizar esto hay que escribir el final
del fichero:
SET CLASSPATH = C:\j2sdk1.4.1_03\lib\dt.jar;.; %Classpath %
4. Salir guardando los cambios del fichero.
De esta forma quedan instaladas las librerı́as del SDK y la Máquina Virtual de
Java.
2
Java Virtual Machine
r
GVA-ELAI-UPMPFC0075-2003
179
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Para utilizar las librerı́as en cualquier fichero fuente, basta realizar un import del
paquete o clase a utilizar. Para poder trabajar con SDK es muy importante disponer
de la ayuda del API de la página web http://java.sun.com. La figura 6.1 muestra la
organización de esta API.
Figura 6.1: API de SDK 1.4.1
JCE
El JCE (Java Cryptography Extension) es un paquete especial de Java, el cual es
necesario para la encriptación y desencriptación de la información que se transfiere
en las asociaciones realizadas en la aplicación desarrollada.
Para la instalación hay que seguir una serie de pasos:
1. Bajarse este paquete de internet, de las posibles páginas como http://java.sun.com
o bien http://snad.ncsl.nist.gov.
2. Descomprimir el archivo descargado, el jce-b1.1-socket.zip. El lugar donde hemos
descomprimido nosotros es en C:\JAVA
180
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.2. USO DE SDK
3. Añadir en el CLASSPATH:
SET CLASSPATH = C:\j2sdk1.4.1_03\lib\dt.jar;C:\JAVA\JCE;
C:\JAVA\JCE\DemoApps;C:\JAVA\JCE\Server;C:\JAVA\JCE\SCM;
C:\JAVA\JCE\rfm;C:\JAVA\JCE\jaudio;.; %Classpath %
4. Poner en el PATH:
SET PATH = . . . ;C:\J2SDK1.4.1_03\BIN;C:\JAVA\JCE\jaudio; %Path %
5. Crear una carpeta llamada .jce en C:\ y copiar en este directorio el .jce que
viene en el archivo descargado de internet, que está dentro de la carpeta JCE.
Gracias al paquete JCE, se puede encriptar y desencriptar en alto grado.
6.2.3.
Instalación en Windows 2000
Máquina Virtual de Java
1. Descargar de la página http://java.sun.com, teniendo que elegir la opción del
JRE para Windows.
2. Una vez descargado el archivo “j2re-1_4_1_03-windows-i586-i.exe”, se procede
a la instalación la cual es muy sencilla. Únicamente hay que ejecutar el archivo
nombrado, de esta forma la JVM está instalada y podemos ejecutar correctamente cualquier aplicación desarrollada en Java.
SDK
1. Descargar el archivo eligiendo la opción SDK para Windows. Este archivo se
llama “j2sdk-1_4_1_03-windows-i586.exe”.
2. Ejecutar el archivo de esta forma se generan las librerı́as y los ejecutables de
las utilidades que ofrece Java, como son el compilador javac.exe, el javadocs,
jar.exe,. . .
3. Entrar en Inicio->Configuración->Panel de Control->Sistema->Avanzado->Variables
de Entorno
4. En Variables del Sistema buscar la variable Path y pulsar Editar. . .
5. Seguido de lo que ponga escribir: C:\J2SDK1.4.1\03\BIN;
6. Pulsar Nueva. . . , y en nombre de variable escribir classpath y en valor de variable
escribir C:\j2sdk1.4.1_03\lib\dt.jar;.;
r
GVA-ELAI-UPMPFC0075-2003
181
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
7. Como último paso dar a Aceptar tres veces secuencialmente para que los cambios
se apliquen.
JCE
1. Bajarse este paquete de internet, de las posibles páginas como http://java.sun.com
o bien http://snad.ncsl.nist.gov.
2. Descomprimir el archivo descargado, el jce-b1.1-socket.zip. El lugar donde hemos
descomprimido nosotros es en C:\JAVA
3. Añadir en el CLASSPATH, en variables de entorno:
SET CLASSPATH = C:\j2sdk1.4.1_03\lib\dt.jar;C:\JAVA\JCE;
C:\JAVA\JCE\DemoApps;C:\JAVA\JCE\Server;C:\JAVA\JCE\SCM;
C:\JAVA\JCE\rfm;C:\JAVA\JCE\jaudio;.; %Classpath %
4. Poner en el PATH, variables de entorno:
SET PATH = . . . ;C:\J2SDK1.4.1_03\BIN;C:\JAVA\JCE\jaudio; %Path %
5. Crear una carpeta llamada .jce en C:\ y copiar en este directorio el .jce que
viene en el archivo descargado de internet, que está dentro de la carpeta JCE.
6.2.4.
Utilidades del SDK
Compilador
Es una herramienta del JDK o SDK3 . Realiza un análisis del sintaxis del código escrito en los ficheros fuente de Java (con extensión *.java). Si no encuentra errores en el
código genera los ficheros compilados (con extensión *.class). En el JDK de Sun dicho
compilador se llama javac.exe. Java.exe es el intérprete para sistemas PC/Windows.
Una vez compilado no deberı́a ser necesaria ninguna modificación por el hecho
de cambiar de procesador o de ejecutarlo en otra máquina. La clave consistió en
desarrollar un código “neutro” el cual estuviera preparado para ser ejecutado sobre
la JVM.
Para realizar una aplicación con el compilador del SDK, se debe escribir el código
en Java en un editor de texto cualquiera como puede ser el “Bloc de Notas”. Una vez
escrito debe ser guardado el fichero con extensión .java, por ejemplo nombre.java. La
3
182
JDK para las antiguas versiones y SDK para las nuevas versiones
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.2. USO DE SDK
compilación debe realizarse con un “shell” de comandos, como el del MSDOS. Para
realizar la compilación escribir:
X:\. . . \javac nombre.java
Figura 6.2: Compilación con SDK
Con la compilación se genera un archivo .class, en este caso serı́a nombre.class.
Después ya se puede ejecutar o interpretar, para esto escribir en el Shell:
X:\. . . \java nombre
Todo ello se realiza en el directorio donde se encuentre el fichero fuente .java.
Javadocs
En el diseño del lenguaje se ha tenido en cuenta la documentación de los programas
y el mantenimiento de dicha documentación. La documentación y el código se incluyen
dentro del mismo fichero.
El tipo de comentario especı́fico para documentar debe ser:
/** Comentario de documentación */
La generación de la documentación se realiza en formato HTML. Se pueden crear
etiquetas de documentación, que luego en la documentación en HTML, saldrá como
un pequeño apartado, esto se realiza poniendo @ delante de la lı́nea que queramos
que sea una etiqueta.
r
GVA-ELAI-UPMPFC0075-2003
183
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Figura 6.3: Api generada con Javadocs
Los comentarios deben aparecer inmediatamente antes de los elementos a comentar. La utilidad de documentación javadoc es un programa que se suministra dentro
de la distribución de J2SE4 .
/**
* La clase <em> Storagescp </em> es utilizada para poner al Servidor
DICOM a la escucha de asociaciones.
* @author Fernando Ballesteros Herranz
* @version Beta
*
*/
Modo de uso:
Javadoc [opciones] [paquetes] [archivosFuente] [@ficheros]
Hay más de 40 opciones (consultar API) que modifican el funcionamiento de
Javadoc.
4
184
Java 2 Standard Edition
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.2. USO DE SDK
jar
Esta utilidad es usada para generar archivos .jar que contienen todas las clases
de la aplicación realizada. Esto se realiza para su posterior distribución. Ejecutando
el .jar generado, la MVJ podrá ejecutar el programa desarrollado.
El formato básico del comando para crear un fichero JAR es:
jar cf fichero-jar fichero(s)-de entrada
Este comando tiene varias opciones y argumentos:
c - indica que se quiere crear un fichero JAR.
f - indica que quieres que la salida vaya a un fichero en vez de a stdout.
v - produce un salida verbosa en stderr (en versión 1.1) o stdout (en versión 1.2)
mientras se construye el fichero. La salida verbosa te dice el nombre de cada
fichero añadido al fichero JAR.
0 - indica que no quieres que el fichero JAR sea comprimido.
M - indica que no se deberı́a producir el fichero de manifiesto por defecto.
m - utilizada para incluir información de manifiesto desde un fichero de manifiesto existente. El formato utilizado por esta opción es: jar cmf existingmanifest output-file input-file(s)
x - indica que quieres extraer los ficheros de un archivo JAR.
u - actualiza el fichero JAR existente.
fichero-file es el nombre que se quiere para el fichero JAR resultante. Puedes
utilizar cualquier nombre de fichero. Por convención, a los ficheros JAR se les
da la extensión .jar, aunque no es obligatorio.
El argumento fichero(s)-de entrada es una lista delimitada por espacios de uno
o más ficheros que deben ser situados dentro de tu fichero JAR. Este argumento
puede tener simbolo del comodı́n *. Si alguno de los fichero(s)-de entrada, es un
directorio, el contenido de dicho directorio se añadirá al fichero JAR recursivamente.
Este comando generará un fichero JAR comprimido y lo situará en el directorio
actual. El comando también generá un fichero de manifiesto, por defecto. METAINF/MANIFEST.MF, para el archivo JAR.
r
GVA-ELAI-UPMPFC0075-2003
185
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Los pasos seguidos para crear el JAR de nuestra aplicación Servidor. Estos pasos
se realizan en el Shell de comandos de MSDOS:
1. Crear un archivo nuevo (incluyendo las clases y otros recursos que te interesen
empaquetar).
jar Main.jar c:\encri.class c:\Connection.class c:\Storagescu.class
c:\Storagescp.class
2. Extraer el archivo MANIFEST.MF del archivo .jar creado:
jar xvf Main.jar META-INF/MANIFEST.MF
3. Modicar dicho archivo (en algún editor de texto corriente). Lo que se hace es
agregar la lı́nea siguiente al archivo MANIFEST.MF (este paso no se hace en
MSDOS):
Main-Class: Storagescp
4. Actualizar el .jar con el archivo MANIFEST.MF modificado:
jar -uvfm Main.jar META-INF/MANIFEST.MF
5. Probar el funcionamiento del .jar:
java -jar prueba.jar o bien haciendo doble click sobre el fichero Main.jar.
6.3.
6.3.1.
Uso de TextPad
Introducción
TextPad es un editor que incluye un compilador de java. En este apartado se ve
las caracterı́sticas de este editor y su relación con java.
6.3.2.
Caracterı́sticas
TextPad es un poderoso editor de programas diseñado para proporcionar potencia y funcionabilidad para satisfacer los requisitos más exigentes. Archivos enormes
pueden ser editados (hasta los lı́mites de memoria virtual). El interfaz múltiple de
documento de Windows permite editar múltiples archivos simultáneamente, con hasta 2 vistas en cada fichero. El texto puede ser copiado y pegado entre los archivos.
Además de las capacidades de copiado y pegado, se pueden corregir los errores de
186
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.3. USO DE TEXTPAD
tipeo más comunes con comandos, y transportar palabras, caracteres y lı́neas. El texto puede ubicarse automáticamente en el márgen, o en una columna especificada, si
no cabe en una lı́nea. Cualquier cambio puede ser deshecho o hecho de nuevo. Las
combinaciones con frecuencia usadas de comandos se pueden salvar como macros. El
programa posee herramientas personalizables y opciones de búsquedas. Ver figura 6.4
Figura 6.4: Entorno de trabajo de TextPad 4.7.0
6.3.3.
Uso con Java
Con este editor se pueden escribir documentos fuentes de java. Para crearlos tan
solo hay que grabarlos con la extensión .java.
El TextPad también tiene un compilador de java, aunque carece de máquina virtual para ejecutar programas desarrollados en java y de las librerı́as. Este compilador
sólo funciona con la instalación previa de las librerı́as del JDK o SDK.
Una vez instaladas las librerı́as, para instalar el TextPad tan solo hay que ejecutar
el archivo Setup del programa.
r
GVA-ELAI-UPMPFC0075-2003
187
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
El compilador muestra que errores ocurren en la compilación y si no ocurre ningún
error genera el archivo .class.
No tiene ayudas para java. Es un editor en el que viene incluido un compilador de
java. No es bueno para la creación de interfaces gráficas, por esto en nuestra aplicación
sólo ha sido utilizado para la creación del Servidor DICOM, ya que éste no necesita
interfaz de usuario, es una aplicación que se administra ella sola sin necesidad de
intervención directa.
6.4.
6.4.1.
Uso de JBuilder
Introducción
En esta sección se van a ver los aspectos más importantes del JBuilder 7.0 Enterprise. Este entorno de desarrollo está orientado a la creación de interfaces gráficas,
por este motivo la mayor parte de la aplicación cliente DICOM ha sido desarrollada
con el JBuilder. La aplicación del cliente es compatible con las nuevas versiones que
han ido saliendo a lo largo del año del JBuilder como las versiones 8.0 y 9.0.
6.4.2.
Instalación
La instalación es muy sencilla tan solo hay que seguir estos pasos:
1. Ir a la página web de JBuilder www.borland.com y descargar la versión de
JBuilder deseada.
2. Pedir un archivo de activación. Para esto hay que registrarse.
3. Colocar el archivo de activación recibido en la carpeta de usuario si se utiliza
Windows NT/2000 o colocarla en la carpeta Windows si se trabaja en Windows
95/98.
4. Ejecutar el JBuilder y cuando pida un archivo de activación indicarle la ruta a
seguir para llegar a éste.
5. Una vez hecho esto se tiene un programa de prueba de 1 mes, pero si se consigue
un archivo jbuilder.jar sustituto al que venga con la aplicación, éste se debe sobrescribir sobre el existente, que está locacizado en . . . /JBuilder/bin/jbuilder.jar.
188
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.4.3.
6.4. USO DE JBUILDER
JDK y JBuilder
Al instalarse el JBuilder, instala por defecto el JDK v1.3.1 y utiliza estas librerı́as
para compilar.
En nuestra aplicación ha sido necesaria la utilización de las JDK 1.4.1, por lo que
hay que cambiar la referencia de las librerı́as. Para cambiar las JDK 1.3.1 a las JDK
1.4.1 hay realizar una pequeña configuración dentro del JBuilder.
1. Entrar en Herramientas
2. Pinchar en Configurar JDK. . .
Figura 6.5: Configuración de JDK
3. Pulsar el boton Cambiar. . .
4. Elegir en el árbol que se abre al directorio donde se encuentren las nuevas
librerı́as en nuestro caso C:/j2sdk1.4.1_03
5. Pulsar Aceptar
r
GVA-ELAI-UPMPFC0075-2003
189
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Figura 6.6: Designación de nuevas JDK
Con esto hecho, las aplicaciones que se realicen a partir de este momento se apoyarán en las nuevas librerı́as designadas. Ver figura 6.6
6.4.4.
Creación de aplicaciones en JBuilder
Se va a crear un simple editor de texto para ver cómo se realiza una aplicación en
el JBuilder. A partir de este ejemplo es posible realizar aplicaciones más completas y
complejas. Tan sólo recordar que el JBuilder está orientado a la creación de interfaces
de usuario y con esto desarrollamos nuestra aplicaión Cliente DICOM.
Pasos:
Paso 1: Creación de un proyecto
Para crear un proyecto se usa el asistente para proyectos y el asistente para aplicaciones, de esta forma:
1. Pulsar Archivo->Nuevo Proyecto
2. Realizar los siguientes pasos:
190
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.4. USO DE JBUILDER
Figura 6.7: Asistente para proyectos
Nombre: Editor de Texto. (Ası́ se llamará el proyecto y la carpeta donde
se encontrará el proyecto)
Tipo (tipo de archivo): .jpx
Seleccionar la opción “Generar archivo de notas del proyecto”. Al seleccionar esta opción, el asistente para proyectos crea un archivo HTML para
las notas del proyecto y lo añade al mismo.
3. Aceptar con las opciones por defecto de los pasos 1 ,2 y 3. Ver figura 6.7
Para ajustar las propiedades del proyecto hay que entrar en Proyecto->Propiedades
del Proyecto. . . . En nuestro caso ajustaremos el Estilo de código a Adaptador estándar
Una vez creado nuestro proyecto, pasamos a crear una aplicación dentro del proyecto mediante el asistente para aplicaciones:
1. Pinchar en Archivo->Nuevo.
2. Hacer doble click sobre el icono Aplicación para abrir el Asistente para aplicaciones. Ver figura 6.8
3. Poner el nombre del paquete igual al nombre del proyecto creado, y el nombre
de la clase el que se quiera. (Tener en cuenta que este nombre será el nombre
de la clase principal)
4. Pulsar Siguiente para ir al Paso 2. Marcar la opción de Generar comentarios de
cabezera
r
GVA-ELAI-UPMPFC0075-2003
191
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Figura 6.8: Galerı́a de objetos
5. Poner nombre de clase y de Tı́tulo (este será el tı́tulo que aparecerá en la barra de
tı́tulo de la aplicación). Marcar las 5 opciones que hay: Generar barra de menú,
Generar barra de herramientas, Generar barra de estado, Generar cuadro Acerca
de y Centrar marco en la pantalla. De esta forma se genera automáticamente el
código más general correspondiente a las opciones seleccionadas. Ver figura 6.9
6. Pulsar en Finalizar. Se añade al proyecto un archivo .java y archivos de imagen.
7. Guardar el proyecto utilizando Archivo->Guardar Proyecto.
8. Pulsar la pestaña Diseño del archivo abierto, TextEditFrame.java. La pestaña
Diseño, ubicada en la parte inferior de la ventana del Visualizador de aplicaciones, abre el diseñador de interfaces de usuario. Ver figura 6.10 Se puede
observar cambios en el IDE de JBuilder:
En el panel de contenido aparece el diseñador de interfaces.
El árbol de componentes aparece en el panel de estructura.
El Inspector aparece a la derecha del diseñador.
Paso 2: Añadir área de texto
En este paso se crea un área de texto que rellena por completo el marco de la
interfaz de usuario entre la barra de menús y la barra de estado. Para lograrlo, el
gestor de diseño del contenedor principal de la interfaz de usuario debe utilizar BorderLayout. Como consecuencia de la utilización del Asistente para aplicaciones, el
principal contenedor de esta interfaz de usuario, que aparece como this en el árbol de
192
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.4. USO DE JBUILDER
Figura 6.9: Asistente para aplicaciones
componentes, contiene un JPanel denominado contentPane que ya se ha cambiado a
BorderLayout. Lo único que hay que hacer ahora es añadir los componentes del área
de texto a contentPane.
Para ello, se añade un panel de desplazamiento en el contentPane y después se
coloca un componente de área de texto dentro del panel de desplazamiento. El panel
de desplazamiento proporciona barras de desplazamiento al área de texto.
1. Hacer click en la pestaña TextEditFrame del editor, y a continuación seleccionar
la pestaña Diseño.
2. Hacer click en el componente contentPane del árbol de componentes para seleccionarlo, como se muestra a continuación. Figura 6.11.
3. Pulsar la pestaña Contenedores Swing en la paleta de componentes y seleccionar
el componente JScrollPane.
4. Hacer click en el centro de contentPane del diseñador de interfaces. Esto coloca el
componente JScrollPane en el panel de contenido y deberı́a darle una restricción
de centro BorderLayout, haciendo que ocupe completamente el área situada
entre la barra de herramientas y la barra de desplazamiento. Otra forma es
seleccionando Edición->Deshacer.
5. Seleccionar el nuevo componente jScrollPane1 en el árbol de componentes.
r
GVA-ELAI-UPMPFC0075-2003
193
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Figura 6.10: Vista en diseño
6. Fijarse en el valor de la propiedad constraints del Inspector y compruebar que
se le está asignando el valor “Center”. Si no es ası́, seleccionar Center de la lista
desplegable.
7. Pulsar la pestaña Swing en la paleta y seleccionar el componente JTextArea.
8. Hacer click sobre el componente jScrollPanel en el árbol de componentes o
arrastrarlo al diseñador de interfaces para colocar JTextArea en el panel de
desplazamiento.
9. En el Inspector, hacer click con el botón derecho sobre la propiedad text y
seleccionar “Borrar” el valor de la propiedad para eliminar es “jTextArea1” del
área de texto.
10. Por último, se deben definir algunas propiedades en jTextArea1 para que se
ajusten automáticamente las lı́neas de texto y se haga en los espacios entre
palabras. En el Inspector, asignar los siguientes valores:
lineWrap = true
wrapStyleWord = true
background = white
A continuación, compilar el programa y ejecutarlo para ver qué aspecto ofrece:
194
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.4. USO DE JBUILDER
Figura 6.11: contentPane
1. Seleccionar Proyecto->Ejecutar Make del proyecto en el menú. Esto compila
todos los archivos del proyecto y crea un archivo TextEdit -> Class.class y un
TextEditFrame.class en una carpeta de clases dentro de la carpeta de proyectos.
Deberı́a compilarse sin errores.
2. Hacer click en el botón “Ejecutar” en la barra de herramientas de JBuilder o
seleccionar Ejecutar->Ejecutar proyecto en el menú. Ahora la interfaz de usuario
ofrece un aspecto similar al de la figura 6.12
3. En la aplicación “Editor de texto”, seleccione Archivo->Salir para cerrar la
ventana de ejecución.
Paso 3: Crear menús
En este paso se van a crear estos menús:
1. Hacer click en la pestaña Diseño de TextEditFrame.java si aún no está seleccionada.
r
GVA-ELAI-UPMPFC0075-2003
195
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Figura 6.12: Editor de texto ejecutado
Figura 6.13: Menú
2. Hacer doble click sobre jMenuBar1 en la carpeta Menu del árbol de componentes
para abrir el diseñador de menús. (También puede seleccionar un elemento de
menú del árbol de componentes y pulsar Intro)
3. Seleccionar el elemento de menú Archivo->Salir en el diseñador de menús o
jMenuFileExit en el árbol de componentes. El diseñador de menús resaltará el
elemento seleccionado.
4. Hacer click en el botón Insertar elemento de menú de la barra de herramientas
del diseñador de menús, o pulse la tecla “Insert” del teclado. Encima de Salir
se introduce un nuevo elemento de menú resaltado y vacı́o.
5. Escribir “Nuevo” en el área resaltada.
6. Pulsar Flecha abajo para aceptar la nueva entrada y bajar al siguiente elemento
(en este caso, el elemento de menú Salir).
196
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.4. USO DE JBUILDER
7. Hacer click derecho en Salir y seleccionar Insertar elemento de menú en el
menú contextual. Escribir “Abrir”.
8. De la misma forma, añadir los elementos de menú “Guardar” y “Guardar como”.
9. Seleccionar Salir y hacer click en el botón Separador de la barra de herramientas
para insertar una barra. El menú Archivo ya está terminado.
10. Hacer click derecho en la barra principal de menús y seleccionar Insertar menú.
Ası́ se crea un menú entre los menús Archivo y Ayuda. Escribir Edición como
nombre de este menú.
11. Pulsar Intro para descender hacia la siguiente entrada vacı́a. No es necesario
pulsar Insert aquı́ porque este menú no contiene ningún elemento después de la
entrada actual. Sugerencia: Para borrar una entrada, seleccionar y hacer click
en el botón Borrar de la barra de herramientas, o pulsar la tecla “Supr” dos
veces. La primera vez que se pulsa la tecla Supr se borra el texto de la entrada.
La segunda vez elimina la entrada del menú.
12. Proseguir con la construcción del menú Edición tal y como se indica en la imagen
6.14, añadiendo tres elementos: Fuente (JBuilder SE y Enterprise), Color de
texto y Color de fondo. Si alguna entrada tiene una longitud superior al área
de edición, el texto se desplazará automáticamente a medida que se escriba.
Cuando se pulse Intro, el diseñador de menús ajustará el ancho del menú para
mostrar el elemento más largo de la lista.
Figura 6.14: Editor
13. Cerrar el diseñador de menús con un doble clic en cualquier componente de la
sección de la interfaz de usuario del árbol de componentes. Esto hará que el
panel de contenido cambie al diseñador de interfaces.
r
GVA-ELAI-UPMPFC0075-2003
197
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
14. Guardar el archivo y ejecutar la aplicación. Ahora la interfaz de usuario ofrecerá un aspecto similar al de la figura 6.14.
Paso 4: Añadir un cuadro de diálogo Selector de fuentes
Se comienza a enlazar los sucesos de menú, empezando con el elemento de menú Edición->Fuente que es el que va a mostrar el cuadro de diálogo Selector de fuentes.
En primer lugar, para poder utilizar esta opción de menú, se debe añadir un
componente cuadro de diálogo Selector de fuentes a la clase TextEditFrame:
1. Abrir TextEditFrame.java en el diseñador de interfaces.
2. Seleccionar la pestaña Más dbSwing de la paleta de componentes y hacer click
en el componente FontChooser.
3. Hacer click en cualquier lugar del árbol de componentes o en el diseñador de
interfaces, para añadir el FontChooser al diseño. Esto situará el componente
dentro de la clase como fontChooser1 y lo mostrará en la carpeta Otros del
árbol de componentes.
Sólo se ve el componente cuadro de diálogo en el árbol de componentes, no en el
diseñador de interfaces.
Creación de un suceso para el elemento de menú Edición->Fuente, que lanzará el
Selector de fuentes:
1. Seleccionar el elemento de menú Edición->Fuente en el árbol de componentes.
Deberı́a ser jMenuItem5 (en el segundo nodo de menú, llamado jMenu1). Se
observa que la propiedad text para este elemento de menú del Inspector dice
“Fuente”. No importa si su elemento de menú Fuente tiene un número diferente
a éste. Pero asegúrarse de seleccionar el correspondiente al menú Fuente.
2. Hacer click en la pestaña sucesos en el Inspector, y hacer doble click en el campo de valor (la segunda columna) del suceso actionPerformed. En los menús,
botones y otros muchos componentes de la interfaz de usuario de Java, actionPerformed es el suceso principal de usuario, que deberı́a capturar para responder al usuario cuando utiliza el menú o el botón. El nombre del método de
tratamiento de sucesos aparece en el campo de valor. Si el método no existe
todavı́a, esta operación muestra el nombre propuesto por defecto para el nuevo
método de gestión del suceso. Para este nuevo manejador de sucesos, el nombre
propuesto es jMenuItem5 actionPerformed. Figura 6.15
198
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.4. USO DE JBUILDER
Figura 6.15: actionPerformed
3. Hacer doble click en el valor de este suceso, o pulsar Intro para crear el suceso.
Si el método de tratamiento del suceso es nuevo, esta operación generará un stub
vacı́o para el método en el código fuente. Independientemente de si el método
es nuevo o ya existe, el foco de ventana cambiará a código fuente en el editor y
colocará el cursor dentro del método de tratamiento de sucesos. En el caso de
un método nuevo de tratamiento de sucesos, como es el caso, verá que la sección
principal del método no contiene todavı́a código alguno.
4. Escribir esta lı́nea de código en el cuerpo de este nuevo método vacı́o (entre las
llaves de apertura y cierre): fontChooser1.showDialog();
Ahora el método deberı́a parecerse a éste:
void jMenuItem5_actionPerformed(ActionEvent e) {
fontChooser1.showDialog();
}
5. Guardar y ejecutar la aplicación. El elemento de menú Edición->Fuente deberı́a abrir el cuadro de diálogo Selector de fuentes. Si no, compruebar que la
propiedad frame tiene el valor this. Aunque se intente cambiar la fuente, no
sucederá nada. Esto se debe a que no se utiliza el resultado del FontChooser
para cambiar el texto del área de edición. Esto será lo siguiente que se haga.
6. Cerrar la aplicación “EditorDeTexto”.
r
GVA-ELAI-UPMPFC0075-2003
199
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Paso 5: Vinculación de sucesos de elemento de menú al cuadro de diálogo
Selector de fuentes
Se va a utilizar el cuadro de diálogo Selector de fuentes para modificar la propiedad
font de textArea1.
1. Hacer click en la pestaña Fuente y seleccionar el método de tratamiento del suceso del elemento de menú Fuente (jMenuItem5_actionPerformed(ActionEvent
e))) recién creado.
Figura 6.16: jMenu
2. Introducir este código en el método de tratamiento de sucesos para el elemento de menú Fuente (jMenuItem5), entre las llaves de apertura y cierre, asegurándose de reemplazar el código antiguo fontChooser1.showDialog();:
// Gestiona el elemento de menú "Edición Fuente"
// Obtiene la fuente existente en el área de texto
// y la lleva al Selector de fuente antes de mostrarlo
200
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.4. USO DE JBUILDER
// para que se modifique la fuente
// que ya existe
fontChooser1.setSelectedFont(jTextArea1.getFont());
//
//
//
if
Obtiene la nueva fuente del Selector de fuentes
Comprueba primero el valor devuelto por showDialog() para
ver si el usuario pulsó Aceptar.
(fontChooser1.showDialog()) {
// Asigna a la fuente de jTextArea1 el valor
// seleccionado por el usuario antes de pulsar Aceptar
jTextArea1.setFont(fontChooser1.getSelectedFont());
}
//pinta el menú de nuevo una vez que el elemento se
//ha seleccionado
this.repaint();
//Vuelve a dibujar el texto correctamente si hay
//texto selecionado al cambiar la fuente.
jTextArea1.repaint();
Todo el método debe tener el siguiente aspecto:
void jMenuItem5_actionPerformed(ActionEvent e) {
// Gestiona el elemento de menú "Edición Fuente"
// Obtiene la fuente existente en el área de texto
// y la lleva al Selector de fuente antes de mostrarlo
// para que se modifique la fuente
// que ya existe
fontChooser1.setSelectedFont(jTextArea1.getFont());
//
//
//
if
Obtiene la nueva fuente del Selector de fuentes.
Comprueba primero el valor devuelto por showDialog() para
ver si el usuario pulsó Aceptar.
(fontChooser1.showDialog()) {
// Asigna a la fuente de jTextArea1 el valor
// seleccionado por el usuario antes de pulsar Aceptar
jTextArea1.setFont(fontChooser1.getSelectedFont());
}
//pinta el menú de nuevo una vez que el elemento se
//ha seleccionado
this.repaint();
//Vuelve a dibujar el texto correctamente si hay texto
//selecionado al cambiar la fuente.
r
GVA-ELAI-UPMPFC0075-2003
201
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
jTextArea1.repaint();
}
3. Guardar y ejecutar la aplicación y escribir algo en el área de texto.
4. Seleccionar el texto y utilizar el elemento de menú Edición->Fuente para cambiar la fuente. En esta aplicación, se cambia la fuente de la totalidad del área de
texto (no solamente del texto seleccionado). No espere que la configuración de
fuentes se mantenga. No introduciremos código para activar esa caracterı́stica.
5. Cerrar la aplicación “EditorDeTexto”.
Paso 6: Vinculación de sucesos de elementos de menú a JColorChooser
A continuación se crean los sucesos de menú Edición->Color de texto y Edición>Color de fondo y se los vincula con el cuadro de diálogo JColorChooser de Swing.
Al no necesitar asignar valores a ninguna de las propiedades de JColorChooser en
el diseñador, no es preciso añadirlo a la interfaz de usuario del diseñador. Puede llamarse directamente desde el manejador del suceso actionPerformed() de un elemento
de menú del siguiente modo:
1. Vuelva al diseñador de TextEditFrame.java.
2. Seleccionar el segundo elemento de menú del árbol de componentes en Edición
(jMenuItem6) que tiene escrito “Color de texto” en la propiedad actionCommand.
3. Seleccionar la pestaña Sucesos en el Inspector y haga click tres veces en el suceso
actionPerformed() para crear el manejador del suceso:
void jMenuItem6\verb’_’actionPerformed(ActionEvent e) {
}
4. Añadir el código siguiente en el stub del manejador del suceso:
//Gestiona el elemento de menú "Color de texto"
Color color = JColorChooser.showDialog(this,"Color de texto",
jTextArea1.getForeground());
if (color != null) {
jTextArea1.setForeground(color);
}
//pinta el menú de nuevo una vez que el elemento
//se ha seleccionado
this.repaint();
202
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.4. USO DE JBUILDER
5. Volver al diseñador.
6. Seleccionar el tercer elemento de menú en el árbol de componentes, en Edición
(menuItem7), que debe tener la etiqueta “Color de fondo” en la propiedad
actionCommand. Crear un suceso actionPerformed() para él, tal como hizo con
jMenuItem6
7. Insertar el siguiente código en el suceso actionPerformed() de jMenuItem7:
// Gestiona el elemento de menú "Color de fondo"
Color color = JColorChooser.showDialog(this,"Color de fondo",
jTextArea1.getBackground());
if (color != null) {
jTextArea1.setBackground(color);
}
//pinta el menú de nuevo una vez que el elemento
//se ha seleccionado
this.repaint();
8. Guardar el archivo, compilar y ejecutar la aplicación. Escribir texto y hacer
pruebas con los colores de primer plano y de fondo.
9. Cerrar la aplicación “EditorDeTexto”.
Paso 7: Adicción de un manejador a un suceso de menú para borrar el
área de texto
Se va a capturar el elemento de menú Archivo->Nuevo con un manejador que borra
el contenido del área de texto.
1. Vuelva al diseñador.
2. Seleccionar el elemento de menú Archivo->Nuevo del árbol de componentes
(jMenuItem1).
3. Crear un suceso actionPerformed() e introducir en él este código:
// Gestiona el elemento de menú Archivo|Nuevo.
// Borra el texto del área del texto.
jTextArea1.setText("");
4. Guardar y ejecutar la aplicación, escribir algo en el área de texto y ver qué sucede
al seleccionar Archivo->Nuevo. Deberı́a borrarse el contenido. Observar que no
se pregunta si se desea guardar el archivo antes. Para poder tratar este aspecto,
se tiene que configurar la infraestructura para la lectura y escritura de archivos
de texto, para controlar si el archivo ha cambiado y necesita guardarse.
r
GVA-ELAI-UPMPFC0075-2003
203
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
5. Cerrar la aplicación “EditorDeTexto”.
Paso 8: Añadir un cuadro de diálogo selector de archivos
Se va a enlazar el elemento de menú Archivo->Abrir con un manejador de un suceso
que presenta al usuario un JFileChooser (cuadro de diálogo para abrir archivos) para
archivos de texto. Cuando el usuario selecciona un archivo y hace click en Aceptar
el manejador del suceso abre el archivo de texto y coloca su contenido dentro de
JTextArea.
1. Volver al diseñador y seleccionar el componente JFileChooser de la ficha Swing
Containers de la paleta de componentes.
2. Hacer click en la carpeta IU del árbol de componentes para colocar el componente.
3. Seleccionar el elemento de menú Archivo->Abrir en el árbol de componentes
(jMenuItem2).
4. Crear un suceso actionPerformed() e introducir este código:
//Gestionar el elemento de menú Archivo|Abrir.
//Utilizar la versión OPEN del cuadro de diálogo, comprobar
//el valor devuelto de Aceptar/Cancelar
if (JFileChooser.APPROVE_OPTION == jFileChooser1.
showOpenDialog(this)) {
// Muestra el nombre del directorio y archivos abiertos en
//la barra de estado.
statusBar.setText("Abierto "+jFileChooser1.getSelectedFile().
getPath());
// El código debe ir aquı́ para cargar realmente el texto
// en el TextArea.
}
5. Salvar y ejecutar la aplicación. En el menú Archivo->Abrir, seleccionar un archivo y pulsar aceptar. Debe aparecer el nombre del archivo y el directorio completo
en la lı́nea de estado en la parte inferior de la ventana. Sin embargo, el área de
texto seguirá vacı́a.
6. Cerrar la aplicación “EditorDeTexto” antes de continuar.
204
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.4. USO DE JBUILDER
Paso 9: Añadir código para leer texto de un archivo
Se va a añadir código para leer el texto del archivo seleccionado por el usuario y
ponerlo en el JTextArea.
En primer lugar, hay que añadir un nuevo método a la clase para realizar la
operación de apertura del archivo. Este método se llamará openFile().
1. Cambiar el editor a TextEditFrame.java e introducir el siguiente método openFile(). Se puede poner en cualquier lugar de la clase (fuera de otros métodos).
Un buen lugar para ubicarlo es justo después del código del método jbInit() y
justo antes del suceso jMenuFileExit_actionPerformed().
// Abrir el archivo con nombre; lee el texto del archivo al
//jTextArea1; informar a la barra de estado.
void openFile(String fileName)
{
try
{
// Abrir un archivo con nombre.
File file = new File(fileName);
// Obtener el tama~
no del archivo abierto.
int size = (int)file.length();
// Asignar cero a un contador para realizar un recuento de
// los caracteres que se han leı́do del archivo.
int chars_read = 0;
// Crear un lector de entrada basado en el archivo,
//para leer los datos.
// FileReader gestiona las conversiones de código de
//caracteres internacionales.
FileReader in = new FileReader(file);
// Crea una matriz de caracteres del tama~
no del archivo,
// para utilizarla como búfer de datos, en el que leer
// los datos del texto.
char[] data = new char[size];
// Leer todos los caracteres disponibles en el búfer.
while(in.ready()) {
// Incrementar el recuento de cada carácter leı́do,
// y acumularlos en el búfer de datos.
r
GVA-ELAI-UPMPFC0075-2003
205
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
chars_read += in.read(data, chars_read, size - chars_read);
}
in.close();
// Crear una cadena temporal que contenga los datos,
// y asignar la cadena a JTextArea.
jTextArea1.setText(new String(data, 0, chars_read));
// Muestra el nombre del directorio y archivos abiertos en
//la barra de estado.
statusBar.setText("Abierto "+fileName);
}
catch (IOException e)
{
statusBar.setText("Error al abrir "+fileName);
}
}
2. Añadir la importación siguiente a la lista de importaciones de la parte superior
del archivo:
import java.io.*;
3. Hacer click en el manejador del suceso de Archivo->Abrir (jMenuItem2_ actionPerformed(ActionEvent)) del panel de estructura para buscarlo rápidamente en
el código fuente.
4. Reemplazar el código fuente en el manejador del suceso de Archivo->Abrir if()
que contenı́a previamente:
// Muestra el nombre del directorio y archivos abiertos en
//la barra de estado.
statusBar.setText("Abierto "+jFileChooser1.getSelectedFile().
getPath());
// El código debe ir aquı́ para cargar realmente el texto
// desde el archivo al JTextArea.
con este nuevo método openFile(), empleando el nombre de directorio y archivo
concatenados.
// Llamar a openFile para intentar cargar el texto desde el
//archivo al JTextArea
openFile(jFileChooser1.getSelectedFile().getPath());
//pinta el menú de nuevo una vez que el elemento se ha
//seleccionado
this.repaint();
206
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.4. USO DE JBUILDER
5. Probar el programa ahora y ver si funciona. Guardar y ejecutar el programa,
y abrir un archivo de texto en el editor. El editor de textos debe tener algún
contenido.
6. Cerrar la aplicación “EditorDeTexto”.
Paso 10: Adicción de código a los elementos de menú para guardar un
archivo
Ahora se precisa un código que vuelva a grabar el archivo a disco cuando se
seleccione Archivo->Guardar y Archivo->Guardar como. . .
Para ello, es necesario añadir una variable de instancia String para almacenar el
nombre del archivo abierto, además de añadir métodos para escribir de nuevo el texto
en este y en otros archivos.
1. Hacer click en jFileChooser1 en el panel de estructura. Esto llevará a la última entrada de la lista de declaraciones de variables de instancia (dado que
jFileChooser1 fue la última declaración realizada).
2. Añadir las siguientes declaraciones al final de la lista después de jFileChooser1:
String currFileName = null; //Vı́a completa con nombre de archivo.
//null significa nuevo / sin tı́tulo.
boolean dirty = false; // True significa texto modificado.
3. Hacer click en el método openFile(String fileName) del panel de estructura
para buscarlo rápidamente en el código fuente. Situar el cursor en el método, a
continuación de la lı́nea siguiente que se lee el archivo en JTextArea:
jTextArea1.setText(new String(data, 0, chars_read));
4. Insertar el siguiente código en esta posición:
// Almacenar en caché el nombre de archivo abierto
//actualmente para utilizarlo al guardar...
this.currFileName = fileName;
// ...y marcar la sesión de modificación como borrada
this.dirty = false;
5. Crear un método saveFile() al que se pueda llamar desde el manejador del suceso
de Archivo->Guardar. Puede ser colocado justo después del método openFile().
Este método escribe el nombre de archivo en la barra de estado al guardar.
r
GVA-ELAI-UPMPFC0075-2003
207
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
// Guardar archivo actual; gestionar los que no tienen
//nombre de archivo; informar a la barra de estado.
boolean saveFile() {
//Gestionar donde aún no exista nombre de archivo.
if (currFileName == null) {
return saveAsFile();
}
try
{
// Abrir el archivo del nombre actual.
File file = new File (currFileName);
// Crear un escritor de salida que escribirá ese archivo.
// FileWriter gestiona las conversiones de códigos de
//caracteres internacionales.
FileWriter out = new FileWriter(file);
String text = jTextArea1.getText();
out.write(text);
out.close();
this.dirty = false;
// Muestra el nombre del directorio y archivos abiertos
//en la barra de estado.
statusBar.setText("Error al guardar "+currFileName);
return true;
}
catch(IOException e) {
statusBar.setText("Error al guardar "+currFileName);
}
return false;
}
6. Crear el método saveAsFile() al que se llama desde saveFile() si no existe nombre de archivo actual. Se utilizará también desde el menú Archivo->Guardar
como. . . . Añadir el código siguiente justo a continuación del método saveFile():
// Guardar el archivo actual, preguntando al usuario el
//nuevo nombre de destino.
// Informar a la barra de estado.
boolean saveAsFile() {
//Utilizar la versión SAVE del cuadro de diálogo,
//comprobar el valor devuelto de Aceptar/Cancelar
if (JFileChooser.APPROVE_OPTION == jFileChooser1.
208
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.4. USO DE JBUILDER
showSaveDialog(this)) {
// Asignar al nombre de archivo actual la selección
//del usuario
// a continuación realizar un saveFile normal
currFileName = jFileChooser1.getSelectedFile().getPath();
//pinta el menú de nuevo una vez que el elemento se ha
//seleccionado
this.repaint();
return saveFile();
}
else {
this.repaint();
return false;
}
}
7. Volver al diseñador y crear un manejador del suceso actionPerformed() para el
elemento de menú Archivo->Guardar (jMenuItem3). Insertar el siguiente código:
//Gestionar el elemento de menú Archivo|Guardar.
saveFile();
8. Crear un manejador de sucesos actionPerformed() para el elemento de menú Archivo>Guardar como. . . (jMenuItem4) e introducir este código:
//Gestionar el elemento de menú Archivo|Guardar como.
saveAsFile();
9. Guardar y compilar el archivo. Ejecutarlo e intentar guardar texto en un archivo.
10. Cerrar la aplicación “EditorDeTexto”.
Paso 11: Adicción de código para comprobar si se ha modificado un archivo
El programa debe controlar si un archivo se ha modificado desde que se creó,
abrió o guardó de forma que pueda preguntar al usuario si debe guardarse antes
cerrar el archivo o salir del programa. Para ello, se añadirá una variable de tipo
booleano denominada dirty.
1. Hacer click en el siguiente método del manejador del suceso de Archivo->Nuevo
en el panel de estructura: jMenuItem1_actionPerformed(ActionEvent e)
r
GVA-ELAI-UPMPFC0075-2003
209
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
2. Añadir el código siguiente al final de este método para borrar el contenido de
las variables dirty y currFileName. Colocarlo inmediatamente detrás de la lı́nea
jTextArea1.setText(“”);, y antes de la llave de cierre.
// borra el nombre de archivo actual y define el
// archivo como limpio:
currFileName = null;
dirty = false;
Se utiliza el componente cuadro de diálogo JOptionPane para presentar un
cuadro de mensaje de confirmación para constatar si el usuario desea guardar un
archivo modificado antes de cerrarlo cuando selecciona Archivo->Abrir, Archivo>Nuevo o Archivo->Salir. Este cuadro de diálogo se abre con una llamada a
un método de clase en JOptionPane, por lo que no es necesario añadir un
componente JOptionPane al programa.
3. Añadir el método okToAbandon() siguiente al código fuente. Puede situar este
método justo a continuación del método saveAsFile():
// Comprobar si el archivo se ha modificado.
// Si es ası́ obtener del usuario una decisión ">Guardar?
// sı́/no/cancelar".
boolean okToAbandon() {
int value = JOptionPane.showConfirmDialog(this,
">Guardar cambios?", "Editor de texto", JOptionPane.
YES_NO_CANCEL_OPTION) ;
switch (value) {
case JOptionPane.YES_OPTION:
// sı́, por favor guardar cambios
return saveFile();
case JOptionPane.NO_OPTION:
// no, abandonar modificaciones
//por ejemplo devolver true sin guardar
return true;
case JOptionPane.CANCEL_OPTION:
default
// cancelar
return false;
}
}
4. Situar las llamadas a este método okToAbandon() en la parte superior de los
manejadores de los sucesos de Archivo->Nuevo y Archivo->Abrir, ası́ como en
el manejador del suceso de Archivo->Salir generado por el asistente. En cada
210
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.4. USO DE JBUILDER
caso, compruebe el valor que devuelve okToAbandon() y realice solamente la
operación si el valor devuelto es “true”.
A continuación aparecen los manejadores de los sucesos modificados:
En el caso de Archivo->Nuevo encerrar el código de la sección principal
del método en un nuevo if, de manera que ese código se ejecute solamente
si okToAbandon() devuelve “true”. El método modificado debe tener el
siguiente aspecto:
void jMenuItem1_actionPerformed(ActionEvent e) {
// Gestiona el elemento de menú Archivo|Nuevo.
if (okToAbandon()) {
// borrar el texto del TextArea
jTextArea1.setText(("");
// borra el nombre de archivo actual y define
// el archivo como limpio:
currFileName = null;
dirty = false;
}
}
En el caso de Archivo->Abrir, realizar el mismo cambio o, sencillamente,
regresar inmediatamente del método si okToAbandon() devuelve “false”.
El método modificado debe tener el siguiente aspecto:
void jMenuItem2_actionPerformed(ActionEvent e) {
// Gestiona el elemento de menú Archivo|Abrir.
if (okToAbandon()) {
return;
}
//Utiliza la versión OPEN del cuadro de diálogo,
// comprueba el valor devuelto de Aceptar/Cancelar
if (JFileChooser.APPROVE_OPTION == jFileChooser1.
showOpenDialog(this)) {
// Llamar a openFile para intentar cargar el texto
// desde el archivo hasta TextArea
openFile(jFileChooser1.getSelectedFile().getPath());
}
this.repaint();
}
En el caso de Archivo->Salir, escribir una comprobación de okToAbandon()
antes de la lı́nea de código que sale de la aplicación. El método modificado
debe tener el siguiente aspecto:
//Realizar Archivo | Salir
public void jMenuFileExit_actionPerformed(ActionEvent e) {
if (okToAbandon()) {
r
GVA-ELAI-UPMPFC0075-2003
211
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
System.exit(0);
}
}
Ahora, estos métodos de tratamiento de los sucesos de menú realizan su
función sólo si okToAbandon() devuelve “true”.
5. Guardar y ejecutar el programa e intentar abrir, editar y guardar varios archivos.
6. Cerrar la aplicación “EditorDeTexto”.
Con estos pasos se tiene un conocimiento básico de cómo crear un GUI (graphical
user interface) que es nuestro punto básico para construir nuestra aplicación DICOM.
6.5.
Instalación de JDT
Estas son las librerı́as de Java utilizadas que implementan funciones del estándar
DICOM. Es necesario hacer una instalación manual como la realizada con las JDK.
También al realizar el programa se han utilizado las librerı́as JDT que se distribuyen
de forma gratuita por lo que tienen un perı́odo de validez, este perı́odo se acaba el
22 de Abril del 2003, pues bien para poder utilizarlas, lo que hacemos es retrasar el
reloj del ordenador hasta el 22 Abril del 2002 y ası́ tenemos un año completo para
poder utilizar las librerı́as.
Para realizar la instalación es común en todos los sistemas operativos el crear una
carpeta que se llame como se quiera, en nuestro caso se llama “classpath”. En esta
carpeta hay que guardar los archivos enviados por softlink que son jdt.jar y jdt.key.
La página para hacer la petición de las librerı́as es www.softlink.be.
En nuestro caso hemos creado una carpeta llamada classpath en el disco D:\, por
lo que hay que copiar los archivos jdt.jar y jdt.key en D:\classpath.
6.5.1.
Instalación en Windows 95/98
Para la instalación de las librerı́as JDT en este sistema operativo, hay que abrir el
archivo “autoexe.bat” que se encuentra en C:\ con un editor de texto (click derecho
sobre el archivo mientras se deja pulsado “Shift”, y elegimos el Bloc de Notas). En la
variable classpath creada anteriormente cuando instalamos las librerı́as JDK, hay que
escribir el path o camino para llegar a los archivos de las librerı́as JDT. En nuestro
caso es:
212
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.5. INSTALACIÓN DE JDT
D:\classpath\jdt.key;D:\classpath\jdt.jar;
Una vez realizado esto, hay que hacer una copia del archivo “jdt.key” en los
directorios donde haya archivos fuente que utilicen estas librerı́as. Por ejemplo si
tenemos en la carpeta C:\java un archivo fuente main.java que utilice estas librerı́as,
hay que poner en la carpeta al archivo “jdt.key”.
6.5.2.
Instalación en Windows NT/2000/XP
Para la instalación de JDT, hay que entrar en las variables de entorno. Para llegar
a las variables de entorno ir a Inicio->Configuración->Panel de Control->Sistema>Avanzado->Variables de entorno. . . y en variables del sistema pinchar en la variable
classpath creada anteriormente, ahı́ añadir:
D:\classpath\jdt.key;D:\classpath\jdt.jar;
Una vez realizado esto, hay que hacer una copia del archivo “jdt.key” en los
directorios donde haya archivos fuente que utilicen estas librerı́as. Por ejemplo si
tenemos en la carpeta C:\java un archivo fuente main.java que utilice estas librerı́as,
hay que poner en la carpeta al archivo “jdt.key”.
6.5.3.
Incluir JDT en JBuilder
Una vez instaladas las librerı́as ahora hay que incluir las librerı́as en el proyecto
que se esté realizando una aplicación DICOM. Este proceso es el mismo para cualquier
tipo de librerı́as que se quieran utilizar. Para ello hay que realizar los siguientes pasos:
1. En la barra de herramientas seleccionar Proyecto
2. Propiedades del proyecto. . .
3. Ahora en la estaña de Vı́as de acceso y dentro de ésta en la pestaña de Bibliotecas
necesarias, se pulsa Añadir. . . y seguidamente Nuevo. . . . Mediante el asistente
de bibliotecas se añaden las de JDT:
Nombre: JDT
Ubicación: Directorio Inicial
Pulsar Añadir. . .
Selecionar el camino hasta las librerı́as JDT que en nuestro caso son:
r
GVA-ELAI-UPMPFC0075-2003
213
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Figura 6.17: Bibliotecas
• D:\classpath\jdt.jar
• D:\classpath\jdt.key
• D:\classpath\
Aceptar
4. Asegurarse que las bibliotecas se han añadido bien entrando en Herramientas>Configurar bibliotecas. . .
Figura 6.18: Configurar bibliotecas
5. Hecho esto ahora podemos añadir las clases de estas bibliotecas a nuestro codigo
fuente sin que de error. Por ejemplo:
import com.archimed.dicom.*;
214
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz 6.6. IMPLEMENTACIÓN DE SERVIDOR DICOM
Con esto podemos declarar nuevos objetos de las clases de JDT, por ejemplo:
DicomObject CT = new DicomObject();
Las librerı́as instaladas ya son utilizables en el proyecto y se puede trabajar con
ellas.
6.6.
6.6.1.
Implementación de Servidor DICOM
Introducción
La aplicación Servidor DICOM implementa todas las funciones DICOM que puede
realizar un servidor con las librerı́as JDT. Se ha realizado un programa multiplataforma que estará en ejecución indefinidamente y que él mismo es capaz de administrarse
sin mantenimiento exterior.
El programa se ha elaborado con Java usando el TextPad como compilador con
el soporte las librerı́as SDK 1.4.1 y JDT de DICOM.
El servidor realizado da múltiples elementos servicio a los clientes como son CSTORE, C-MOVE, C-FIND, C-GET y C-CANCEL. Con estos elementos de servicio
se ha podido implementar las funciones query, guardar, enviar, editar y listar una los
archivos Dicom que se encuentran en el servidor. Todos estos servicios de red están
codificados mediante algoritmos DES5 de encriptación.
El servidor DICOM realizado es multiusuario (multihilo), lo que quiere decir que
si hay varios clientes intentando acceder al servidor y haciendo peticiones al éste,
él mismo administra las peticiones en diferentes hilos y ası́ puede dar servicios a
diferentes clientes a la vez.
El servidor va dando informes sobre lo que se va desrrollando e información acerca
de los servicios que está realizando y le están pidiendo los clientes.
Vamos a analizar cada función que realiza el servidor. Los pasos previos a todas las
funciones es el que se eralice una asociación entre cliente y servidor y estén deacuerdo
en la información que van a compartir.
5
Digital Encription Standard
r
GVA-ELAI-UPMPFC0075-2003
215
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
6.6.2.
Fernando Ballesteros Herranz
Listar
EL servidor a petición del cliente, realiza una lista de los archivos Dicom contenidos
en la base de datos. Esta lista es enviada y codificada por el servidor a los clientes
que la soliciten.
Figura 6.19: Listado en Servidor
El código en Java es el siguiente:
String dirname = "/BaseDeDatos";
File f1 = new File(dirname);
if(f1.isDirectory()){
String si[] = f1.list();
int j = si.length;
int i = 0;
String cadena = new Integer(j).toString();
ps.println(j);
Integer numero = new Integer(cadena);
j = numero.intValue();
for(i=0;i<(j);i++){
//Para leer cada archivo de base de datos y
//ver cuantas imagenes tiene
FileInputStream fin = new FileInputStream
("c://BaseDeDatos//"+si[i]);
DicomObject scimage = new DicomObject();
scimage.read(fin,true);
int a = scimage.getI(DDict.dNumberOfFrames);
if(a>30){
a=1;
}
fin.close();
216
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz 6.6. IMPLEMENTACIÓN DE SERVIDOR DICOM
System.out.println(si[i]);
ps.println(si[i]);
ps.println(a);
}
return;
Donde primero se mira cuantos archivos Dicom hay en la base de datos y luego
sabiendo este número se van listando. También es importante saber cuantas imágenes
tiene cada archivo Dicom ya que es una información que el cliente debe de conocer.
Toda esta información es enviada al cliente cada vez que hace una petición de la base
de datos.
6.6.3.
Enviar
Esta función es muy inportante ya que es la base de la transmisión de los objetos
Dicom. El servidor envı́a al cliente el archivo pedido. Esta función suele realizarse
despues de hacer una petición de lista para ver que archivos hay en la base de datos,
una vez que se ven cuales hay, el cliente pide un archivo y el servidor se lo envı́a.
Figura 6.20: El servidor envı́a objeto Dicom
La implementación es muy extensa pero la base es:
.......
DicomObject scimage = new DicomObject();
scimage.read(fin,true);
fin.close();
.......
as.send(SOPClass.CTImageStorage,cstorerequest,scimage);
.......
r
GVA-ELAI-UPMPFC0075-2003
217
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Donde lo primero que se hace es crear un objeto Dicom DicomObject scimage =
new DicomObject() en el que almacena la información del archivo (este proceso se
realiza con las funciones de JDT que tienen en cuenta que lo que se debe almacenar
debe tener la estructura definida por el estándar). Después la instancia es enviada
mediante el método send() de un objeto de la clase Association incluida en el JDT.
6.6.4.
Guardar
Cuando el cliente envı́a archivos Dicom al servidor, éste debe saber administrar
la forma de guardarlo sabiendo qué nombre debe dar al archivo recibido y donde se
producirá su almacenaje.
Figura 6.21: El servidor recibe objeto Dicom
El código fuente es muy extenso pero para entender la forma de realizarse esta
función vale con:
.......
DicomObject im = new DicomObject();
.......
//recibe los VRs
im = as.receiveData();
im.write(fin,true);
fin.close();
.......
Para esto se ha tenido que crear un objeto Dicom DicomObject im = new DicomObject() que será quien reciba los datos que se están recibiendo del cliente vı́a
network. Estos datos son los data sets con los valores correspondientes del archivo
Dicom. El objeto Dicom recibe los datos mediante el método receiveData() de la clase
218
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz 6.6. IMPLEMENTACIÓN DE SERVIDOR DICOM
Association y luego los guarda para no perderlos y ası́ crear un nuevo archivo Dicom
en la base de datos del servidor. Esto se realiza con im.write(fin,true), siendo fin el
objeto tipo archivo donde se guarda el objeto Dicom.
6.6.5.
Query/Retrieve
El servidor da información o partes de información de los archivos Dicom almacenados en la base de datos. Esta función es muy importante y útil para saber que
archivos queremos ya que nos da la información del estudio realizado.
La información que da el servidor de nuestra apliación es:
Fecha del estudio: Dı́a-Mes-Año
Nombre del paciente
Edad
Sexo
Número de células y de virus
Número de imágenes que tiene cada archivo
Esta información es de suma importancia para tener conocimiento del estudio que
queremos analizar, modificar, borrar o eliminar.
La implementación del código:
.......
FileInputStream fin = new FileInputStream("c://BaseDeDatos//"+nombre);
DicomObject scimage = new DicomObject();
scimage.read(fin,true);
String nombres = scimage.getS(DDict.dPatientName);
ps.println(nombres);
String nombr = scimage.getS(DDict.dPatientAge);
.......
ps.println(nombr);
String nom = scimage.getS(DDict.dPatientSex);
ps.println(nom);
String dia = scimage.getS(DDict.dPlanes);
ps.println(dia);
r
GVA-ELAI-UPMPFC0075-2003
219
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
String mes = scimage.getS(DDict.dAccessionNumber);
ps.println(mes);
String ano = scimage.getS(DDict.dAcquisitionNumber);
ps.println(ano);
.......
Se abre un FileInputStream para el archivo del que se quiera obtener la información
y se crea un objeto Dicom para leer la información del archivo que tiene formato Dicom
según el estándar. Una vez leido el archivo Dicom, se leen las partes que nos interesan
del objeto Dicom y son enviadas al cliente.
6.6.6.
Editar
Esta función permite modificar los archivos Dicom del servidor sin necesidad el
cliente de tener que traerse todo el archivo Dicom. Es muy útil para modificar los
estudios de los pacientes o poner notas que los médicos creen convenientes, de una
forma rápida y sencilla.
Los datos que se pueden modificar en nuestra aplicación son:
Fecha del estudio: Dı́a-Mes-Año
Nombre del paciente
Edad
Sexo
El código es:
.......
String nomb = in.readLine();
String archiv = in.readLine();
String edad = in.readLine();
String sexo = in.readLine();
String dia = in.readLine();
String mes = in.readLine();
String ano = in.readLine();
FileInputStream fin = new FileInputStream
("c://BaseDeDatos//"+archiv);
220
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz 6.6. IMPLEMENTACIÓN DE SERVIDOR DICOM
DicomObject scimage = new DicomObject();
scimage.read(fin,true);
.......
scimage.set(DDict.dPatientName,nomb);
scimage.set(DDict.dPatientAge,edad);
scimage.set(DDict.dPatientSex,sexo);
scimage.set(DDict.dPlanes,dia);
scimage.set(DDict.dAccessionNumber,mes);
scimage.set(DDict.dAcquisitionNumber,ano);
FileOutputStream salvar = new FileOutputStream
("c://BaseDeDatos//"+archiv);
scimage.write(salvar,true);
.......
De esta forma se reciben los datos que el cliente quiere modificar del archivo que
desee y mediante el método set de la clase DicomObject se van modificando los datos.
Una vez hecho esto se deben guardar los cambios realizados en el objeto con el método
write().
6.6.7.
Encriptación/Desencriptación
La encriptación realizada en la aplicación tanto de servidor como de cliente está basada en los algoritmos DES.
En la criptografı́a tradicional, (también llamada criptografı́a de “clave secreta”)
tanto el emisor como el receptor poseen una misma clave o password. El emisor utiliza
esta clave para cifrar el mensaje obteniéndose el “mensaje cifrado”, que es ilegible.
El receptor utiliza la misma clave utilizada para el cifrado para descifrar el mensaje
y obtener ası́ el mensaje original. Si esta clave es conocida únicamente por emisor
y receptor, se asegura que el mensaje recibido es el original y que es enviado por la
única persona (además del receptor), que tiene la clave.
La criptografı́a realizada en esta aplicación sólo se ha realizado en la información
o partes de información de los objetos Dicom y en los elementos de servicio que se
deseaban realizar. No se ha aplicado en la transmisión de archivos Dicom enteros ya
que las librerı́as JDT no lo soportan.
La implementación del algoritmo es de caracterı́sticas fáciles:
.......
byte caracterEncriptacion=’n’;
r
GVA-ELAI-UPMPFC0075-2003
221
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
String cadenaEncriptada="";
int caracterEncriptado=0;
String cadenaDesencriptada="";
String encriptar(String cadenaEncriptar)
{
// Encriptación según los algoritmos DES
// Devuelve la cadena encriptada
for (int x=0;x<cadenaEncriptar.length();x++)
{
caracterEncriptado=cadenaEncriptar.charAt(x)
^ caracterEncriptacion;
cadenaEncriptada+=(char)caracterEncriptado;
}
return(cadenaEncriptada);
}
String desencriptar(String cadenaEncriptada)
{
// Desencriptación según los algoritmos DES
// Devuelve la cadena desencriptada
for (int x=0;x<cadenaEncriptada.length();x++)
{
caracterEncriptado=cadenaEncriptada.charAt(x)
^ caracterEncriptacion;
cadenaDesencriptada+=(char)caracterEncriptado;
}
return(cadenaDesencriptada);
}
.......
6.7.
6.7.1.
Implementación de Cliente DICOM
Introducción
Esta aplicación sigue todos los pasos del estándar DICOM en la implementación de
las funciones. Se ha querido realizar un programa multiplataforma y que esté deacuerdo con las especificaciones requeridas.
Este programa ha sido elaborado en Java en el entorno JBuilder con soporte de
222
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
librerı́as SDK 1.4.1 y JDT de DICOM.
La aplicación tiene varias partes. Lo primero, y a través de los componentes de
javax.swing es construir un marco que concuerde con las expectativas. En nuestro caso
se ha dispuesto varias pestañas que albergan paneles mediante las clases JTabbedPane
y JPanel para que quede una estructura de interfaz de cliente DICOM.
De esta forma se puede poner en cada panel lo deseado. En nuestro caso se ha
dispuesto de los paneles que aparecen en la figura: panelCliente-Servidor, panelProcesamiento, panelVisorDicom y panelCrearDicom.
Vamos a ver para que sirven cada uno de estos paneles y una pequeña muestra de
cómo han sido implementados.
6.7.2.
Panel Cliente-Servidor
Figura 6.22: Panel Ciente-Servidor
Este panel sirve para comunicarse con el Servidor Dicom. Mediante este panel se
puede solicitar al servidor una lista de los archivos que tenga en la base de datos,
r
GVA-ELAI-UPMPFC0075-2003
223
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
se puede coger cualquier archivo de esa base de datos, se pueden enviar archivos a
la base de datos, se pueden modificar estos archivos desde el cliente y se puede ver
partes de la información que contienen estos archivos Dicom que están en la base de
daros del servidor. Ver figura 6.22
Antes de realizar cualquier acción en este panel, se debe escribir el nombre del
servidor del que queremos tener estos servicios.
Base de Datos
Mediante el botón Base De Datos, se hace una petición al servidor de los archivos
que contenga. Estos archivos contenidos en la base de datos del servidor, se muestran
en el cliente en un árbol, en el que se ve también por cuantas imágenes está compuesto
el archivo. Ver figura 3.2.
Para que el funcionamiento de este botón sea correcto, hay que poner el nombre
del servidor con el que queremos crear una asociación en el espacio creado para ello.
Después de presionar el botón Base De Datos, saldrá una orden a su derecha que nos
dirá “Haz click en Dicom”, entonces hay que hacer click en la palabra Dicom que
está escrita en el árbol.
La implementación consta básicamente:
jTree1.addMouseListener(ml);
// Al pulsar la tecla, haga la peticion de la lista.
String servidor = textoServidor.getText();
Storagescu BasedeDatos = new Storagescu(servidor,104,
"storecp","storecu");
BasedeDatos.lista();
//creamos arbol y lisening
createNodes(top);
jTree1.setEditable(true);
jTree1.getSelectionModel().setSelectionMode
(TreeSelectionModel.SINGLE_TREE_SELECTION);
jTree1.setShowsRootHandles(true);
jTree1.addTreeSelectionListener(new javax.swing.event.
TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
jTree1_valueChanged(e);
}
});
224
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
jScrollPane9.setVerticalScrollBarPolicy(JScrollPane.
VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane9.setViewportBorder(BorderFactory.
createEtchedBorder());
jScrollPane9.setBounds(new Rectangle(313, 308, 378, 255));
Al pulsar el botón Base de Datos, creamos un listening para el ratón para actuar
con sus eventos, pedimos una lista al servidor sobre su base de datos y creamos un
árbol de los archivos.
Figura 6.23: Botón Base De Datos y Enviar
Enviar
Para enviar estudios o archivos Dicom al servidor para que los almacene en la base
de datos, implementamos este botón, el botón Enviar. Ver figura 6.23.
Para enviar los datos, primero hay que poner el nombre del servidor con el que
queremos conectar en el JTextArea que hemos creado para ello. Este boón cogera con
que servidor queremos conectarnos y nos abrirá un browser para buscar el archivo
que queremos enviar.
r
GVA-ELAI-UPMPFC0075-2003
225
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
El código para esto es:
open();
String servidor = textoServidor.getText();
.......
Storagescu enviar = new Storagescu(servidor,104,
"storecp","storecu",openFileName);
.......
int ok=enviar.store();
if(ok==enviar.STORE_OK)
etiquetaEnvio.setText("Enviado con éxito");
else
etiquetaEnvio.setText("Enviado sin éxito");
Donde los parámetros del objeto enviar de la clase Storagescu son los datos necesarios para enviar el archivo más tarde mediante el método store() de la clase Storagescu.
Coger
Este botón ha sido implementado para poder hacer peticiones al servidor de que
envı́e al cliente el archivo marcado en el árbol. El archivo enviado por el servidor se
guardará en el cliente y podrá ser visualizado en el panel Visor Dicom. Ver figura
6.24.
Figura 6.24: Botón Coger
La implementación es muy extensa pero lo básico en el GUI:
String archivo = textoArchivo.getText();
String servidor = textoServidor.getText();
Storagescu Coger = new Storagescu(servidor,104,
"storecp","storecu",archivo);
Coger.coger();
226
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
Coge el nombre del servidor al que está conectado y el nombre del archivo que se
quiere traer, luego se crea un objeto de la clase Storagescu que es la encargada de
establecer la asociación con el servidor. Este objeto llama a la función coger() que
la que hace el elemento de servicio necesario para traer el archivo especificado del
servidor.
Editar
Su función es modificar los datos de los archivos que están en el servidor sin
tener que traernos el objeto entero. Cada vez que se pinche sobre un archivo se trae
la información necesaria no todo el archivo. La información que se trae y se puede
modificar es:
Fecha del estudio: Dı́a-Mes-Año
Nombre del paciente
Edad
Sexo
Para modificar estos datos hay que escribir en los espacios JTextField (ver figura
6.25) dispuestos para ver y para escribir en ellos. Para que las modificaciones se
conserven, hay que escribir los datos que se quieran en los campos y darle al botón
Editar, de esta forma se modifican los datos de los arhivos Dicom del Servidor.
El código de la GUI es básicamente:
String nombre = TextoNombre.getText();
String servidor = textoServidor.getText();
String archivo = textoArchivo.getText();
String edad = TextoEdad.getText();
String sexo = TextoSexo.getText();
String dia = TextoDia.getText();
String mes = TextoMes.getText();
String ano = TextoAno.getText();
Storagescu Poner = new Storagescu(servidor,104,"storecp",
"storecu",archivo,nombre,edad,sexo,dia,mes,ano);
Poner.poner();
r
GVA-ELAI-UPMPFC0075-2003
227
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Figura 6.25: Botón Editar
Donde se cogen mediante el método getText() los datos modificados y luego se
crea un objeto de la clase Storagescu con un constructor en el que se le pasan todos
los datos. Finalmente se utiliza el método poner() de la clase Storagescu que ha sido
creada por nosotros.
6.7.3.
Panel VisorDicom
Este panel sirve para poder visualizar todo tipo de archivos DICOM: archivos
comprimidos, no comprimidos, en color, en escala de grises y de una o varias imágenes,
también es capaz de insertar datos de texto en los campos ya existentes de un archivo
228
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
Figura 6.26: Panel Visor DICOM
DICOM y de crear nuevos campos e insertar datos en ellos.
Se ha conseguido a través de la implementación de una clase llamada Imagedos
en el proyecto de JBuilder, la cual nos va a permitir en última instancia ser capaces
de visualizar la imagen de los archivos DICOM. Ver figura 6.26
Visualizar datos
Esta clase tiene un constructor de la forma public Imagedos(DicomObject dcm) al
cual vamos a llamar y a pasarle un objeto de la clase DicomObject.
Este parámetro que se pasa es un archivo DICOM sacado de archivos .dcm (formato DICOM).
La forma de pasar de un archivo .dcm a una instancia de la clase DicomImage
(subclase de DicomObject) se consigue mediante este código, implementado en nuestra clase principal MarcoCuatro.java en el método open():
r
GVA-ELAI-UPMPFC0075-2003
229
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
.......
if (JFileChooser.APPROVE OPTION == jFileChooser1.
showOpenDialog(this))
openFileName = jFileChooser1.getSelectedFile().
getAbsolutePath();
f = new File(openFileName);
fin = new FileInputStream(f);
bis = new BufferedInputStream(fin);
dcm.read(bis, true);
.......
Donde con la primera lı́nea de código conseguimos que se abra un selector de
archivos, donde elegimos el archivo DICOM deseado. Con la lı́nea it openFileName
= jFileChooser1.getSelectedFile().getAbsolutePath(); conseguimos guardar el camino
completo del archivo, el cual necesitamos para crear un objeto de la clase File, depués
uno de la clase FileInputStream y finalmente uno de la clase BufferedInputStream para
poder usar el método read de la clase DicomObject, el cual lee desde el BufferedInputStream el archivo DICOM.
De esta forma tenemos en “dcm” (DicomImage dcm = new DicomImage();) nuestro archivo DICOM .dcm.
Para sacar los datos de texto de este archivo DICOM usamos:
ReSystemOut systemArea = new ReSystemOut(areaTextoDatosDicom);
dcm.dumpVRs(systemArea,true);
Donde la clase ReSystemOut es una implementación realizada para poder mostrar
estos datos en un objeto de la clase JTextArea, que es lo que nos interesa para poder
visualizar estos datos en nuestro GUI (en este caso en la instancia areaTextoDatosDicom de JTextArea).
El paso siguiente es coger los datos reunidos en este objecto. Para ello necesitamos
la clase Imagedos. Llamamos a su constructor public Imagedos(DicomObject dcm) con
lo que tenemos un objeto de esta clase:
imagedcm = new Imagedos(dcm);
Mediante el método getBufferedImage(int numeroDeImagen) podemos sacar las
imágenes y poderlas visualizar de esta forma:
230
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
imagen = imagedcm.getBufferedImage(numeroImagen);
etiquetaMostrarImagen.setIcon(new ImageIcon(imagen));
Donde etiquetaMostrarImagen es un objeto de la clase JLabel la cual mediante el
método setIcon(ImageIcon a) puede mostrar nuestras imágenes. La instancia de la
clase ImageIcon se crea como se ve arriba mediante su constructor.
Hacer zoom in o zoom out
Una vez visualizada la imagen, se ha dotado de la posibilidad de hacer zoom de
dos formas diferentes:
1. Botones Zoom In y Zoom Out. Ver figura 6.27
Figura 6.27: Zoom In y Zoom Out
La implementación básica es (para el caso de Zoom In):
int altura = zoomImagen.getHeight(null);
int anchura = zoomImagen.getWidth(null);
zoomImagen = imagen.getScaledInstance(anchura*2,altura*2,
imagen.SCALE DEFAULT);
etiquetaMostrarImagen.setIcon(new ImageIcon(zoomImagen));
Donde con getHeight y getWidth (métodos de la clase Image) sacamos la altura
y anchura de la imagen zoomImagen. Y mediante el método getScaledInstance
hacemos una imagen a escala de la anterior, para lo que necesitamos nuevos
datos de alto/ancho, que después con el método antes visto setIcon podemos
visualizamos en el mismo objeto JLabel, etiquetaMostrarImagen.
2. Mediante eventos de ratón:
En este caso se ha conseguido que mediante dos cliqueos con el ratón sobre
la imagen se haga “zoom in” de la zona selecionada. Se hace, creando para la
r
GVA-ELAI-UPMPFC0075-2003
231
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Figura 6.28: Zoom con eventos
JLabel deseada (etiquetaMostrarImagen), un código que sea capaz de recoger
un evento, en este caso el chasquido del ratón. La implementación es:
etiquetaMostrarImagen.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
try
if(x1==-1&y1==-1)
{
x1 = e.getX();
y1 = e.getY();
}else if(x2==-1&y2==-1)
{
x2 = e.getX();
int ancho = Math.abs(x2) - Math.abs(x1);
int alto = y2 - y1;
ancho = Math.abs(ancho);
alto = Math.abs(alto);
zoomBufferedImagen = ImageToBufferedImage.
toBufferedImage(zoomImagen);
232
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
if((x1>x2)&(y1>y2))
{
zonaBImagen= zoomBufferedImagen.getSubimage
(x2,y2,ancho,alto);
}if((x1<x2)&(y1>y2))
{
zonaBImagen= zoomBufferedImagen.getSubimage
(x1,y2,ancho,alto);
}if((x1<x2)&(y1>y2))
{
zonaBImagen= zoomBufferedImagen.getSubimage
(x1,y1,ancho,alto);
}if((x1>x2)&(y1<y2))
{
zonaBImagen= zoomBufferedImagen.getSubimage
(x2,y1,ancho,alto);
}
Image zonaZoomImage = zonaBImagen.
getScaledInstance(4*ancho,4*alto,Image.SCALE DEFAULT);
Marco PantallaCompleta marcoZonaZoom = new Marco
PantallaCompleta(zonaZoomImage);
Dimension dlgSize = marcoZonaZoom.getPreferredSize();
Dimension frmSize = getSize();
Point loc = getLocation();
marcoZonaZoom.setLocation((frmSize.width - dlgSize.
width) / 2 + loc.x, (frmSize.height - dlgSize.height)
/ 2 + loc.y);
marcoZonaZoom.setModal(true);
marcoZonaZoom.pack();
}
}
});
Donde se crea un listener de evento MouseEvent el cual nos permite saber la
posición del ratón en el momento que éste es pulsado, por lo que podemos sacar
la zona de interés (mediante los métodos getX() y getY() ) y donde Marco
PantallaCompleta es una clase que permite visualizar imágenes en un panel
aparte.
También, si se quisiese detectar, por ejemplo el movimiento del ratón sobre un
componente o el rotar de la rueda central del ratón se pueden usar clases del
mismo paquete MouseAdapter, MouseEvent, MouseMotionAdapter o/y MouseWheelEvent para tener efectos homólogos a lo anteriormente visto.
r
GVA-ELAI-UPMPFC0075-2003
233
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Visualizar todas las imágenes
Ya se ha comentado la forma de conseguir visualizar los datos de la imagen de los
archivos DICOM, pero también sabemos que un archivo DICOM puede contener más
de una imagen, por lo que debemos ser capaces de visualizarlas todas y cada una de
ellas.
Figura 6.29: Botones Siguiente y Anterior
Al abrir un archivo DICOM se muestra en pantalla (en una instancia de la clase
JLabel) la primera imagen y en el caso de que haya más de una imagen en dicho
archivo, los botones Siguiente, Anterior y Seguidas realizarán las funciones siguientes.
1. Botones Siguiente y Anterior:
Estos dos botones permiten ver, si existe, la imagen siguiente o la anterior
como indica su nombre. La implementación es muy sencilla. Primero, se ve
si hay más de una imagen mediante la captura del dato del objeto DICOM
dcm.getI(DDict.dNumberOfFrames) y si existe, se muestra en pantalla. Ver figura 6.29.
La parte importante de esta implementación es:
void botonImagenSiguiente actionPerformed(ActionEvent e)
{
.....
.....
numeroImagen++;
imagen=imagedcm.getBufferedImage(numeroImagen);
etiquetaMostrarImagen.setIcon(new ImageIcon(imagen));
.....
.....
}
Donde imagedcm es un objeto de la clase Imagedos que puede coger la imagen
de número seleccionada mediante el int numeroImagen.
234
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
Figura 6.30: Botón Seguidas
2. Botón Seguidas:
Se basa en lo anterior, pero se consigue que las imágenes pasen una detrás de
otra (formando una pelı́cula). La pelı́cula se para si se pulsa con el ratón sobre
el panel donde aparece esta secuencia. Ver figura 6.30
Se va a ver una parte importante de la implementación:
void botonImagenesSeguidas actionPerformed(ActionEvent e)
{
.....
.....
Image [] secuencia = new Image[dcm.getI(DDict.
dNumberOfFrames)];
for(int n=0;n<dcm.getI(DDict.dNumberOfFrames);n++)
{);
secuencia[n]=imagedcm.getBufferedImage(n);
System.out.println(n);
}cargado = true;
ImageSequenceTimer controller = new ImageSequenceTimer();
controller.secuencia(secuencia,dcm.getI(DDict.
dNumberOfFrames));
.....
.....
}
Donde, como se puede ver, se cargan todas las imágenes en un array de Images
y más tarde se crea una instancia de la clase ImageSequenceTimer con la cual
se crea el panel donde se va a visualizar la secuencia.
r
GVA-ELAI-UPMPFC0075-2003
235
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Figura 6.31: Botón Guardar JPEG
Guardar imágenes como JPEG
Se puede guardar la imagen visualizada en formato JPG mediante las posibilidades
de JDK 1.4.1. Esta función sólo se encuentra en esta versión del API JAVA, por lo
que aquı́ vemos el porqué del uso de esta versión.
Para implementar esto necesitamos importar el paquete:
import javax.imageio.*;
Debido a que en éste se encuentra lo buscado, que es el método de la clase
javax.imageio.ImageIO que nos permite guardar los datos de una instancia de la
clase Image en un archivo de formato JPEG. La implementación esencial es:
void botonGuardarIamgenComoJpg actionPerformed(
ActionEvent e){
.....
.....
if (JFileChooser.APPROVE OPTION == jFileChooser1.
showSaveDialog(this))
{
String salvarJPG = jFileChooser1.getSelectedFile().
getAbsolutePath();
FileOutputStream salvar = new FileOutputStream
(salvarJPG);
File save = new File(salvarJPG);
BufferedOutputStream salida = new BufferedOutputStream
(salvar);
javax.imageio.ImageIO.write(imagen,"JPEG",save);
}
.....
.....
}
236
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
Donde la lı́nea de código más importante es javax.imageio.ImageIO.write(imagen,
“JPEG”,save); que realiza la función deseada.
Meter y modificar datos de texto en el archivo DICOM
En un archivo DICOM, como sabemos tenemos datos de imagen y también de
texto, es decir el nombre del paciente, que aparato ha realizado la captura de la imagen. . . . La función, que se ha hecho para esta GUI y para este panel, es la capacidad
de poder añadir datos de texto al archivo visualizado.
Esto se puede hacer de dos formas diferentes. Se puede insertar datos en campos
ya existentes, como el nombre del paciente, o se puede crear nuestro propio campo
como por ejemplo número de moléculas infectadas.
Del primer tipo se han dispuesto una serie de campos, los cuales pueden ser válidos
o no. En este aspecto deben ser los profesionales de la medicina los que deben suministar información para saber los datos que quieren insertar para poder adaptarnos
a ellos.
Ya se vió de que manera se puede visualizar todos los datos del archivo DICOM.
Aquı́ vamos a cambiar o meter nuevos datos en determinados campos y podremos
visualizar si estas modificaciones se llegan a producir.
Para ésto se han dispuesto dos instancias de la clases JComboBox, dos botones
de la clase JButton para insertar y para ver lo insertado y de dos objetos JTextArea
siendo éstas las zonas de visualización. Todo esto se puede ver en la figura 6.32
Figura 6.32: Insertar y ver datos
La forma de implementar esto es creando dos instancias de la clase JComboBox
con los campos adecuados:
private JComboBox jComboBox1
r
GVA-ELAI-UPMPFC0075-2003
237
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
= new JComboBox(opcionesCombobox);
Siendo en este caso opcionesCombobox:
String[] opcionesCombobox = {"dAdditionalPatientHistory"
,"dBeamName","dBitsAllocated","dBodyPartExamined"
,"dContrastAllergies","dHistogramData","dImageComments",
"dInterventionDrugName","dModality","dPatientName","dPixelData"
,"dROIArea","dSeriesNumber","dSmokingStatus","dNumberOfFrames"};
Por lo que al pinchar sobre la flecha del combobox, aparecen todos estos campos. Ahora hay que interconectarlos para que al seleccionar uno y escribir sobre las
JTextArea se inserte y visualicen los datos.
Para insertar:
void botonInsertarDato actionPerformed(ActionEvent e)
{
try
{
String opcion = (String)jComboBox1.getSelectedItem();
String dato = areaTextoInsertarDato.getText();
if(opcion=="dPatientName")
dcm.set(DDict.dPatientName, new Person(dato));
.....
Donde new Person(dato) es el dato del nombre del paciente que se inserta en el
campo del archivo DICOM DDict.dPatientName.
Hecho esto, el dato estarı́a en el objeto DicomImage pero no todavı́a en el
archivo .dcm, para lo que se implementa estas otras lı́neas de código:
FileOutputStream save = new FileOutputStream(openFileName);
dcm.write(save,true);
Siendo write un método de la clase DicomObject que lo que hace es escribir a
través de un FileOutputStream todos los datos de la instancia DicomImage en
un archivo .dcm que, si no existe, crea uno.
Para ver lo insertado:
238
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
void botonVerDato actionPerformed(ActionEvent e)
{
String opcion2 = (String)jComboBox2.getSelectedItem();
if(opcion2=="dPatientName")
{
String cadena = dcm.getS(DDict.dPatientName);
areaTextoVerDato.setText(dcm.getS(DDict.dPatientName));
.....
Para ver que el funcionamiento de lo anterior es correcto se puede volver a abrir
el archivo DICOM y se podrá observar que el nombre del paciente ha cambiado
o aparece cosa que antes no harı́a. La figura ?? siguiente pretende ser un ejemplo
de lo descrito.
Cómo añadir campos nuevos al archivo DICOM
Existe la posibilidad de crear nosotrosmismos nuestros propios campos, para utilizar según convenga.
Se ha visto cómo insertar datos en los campos del archivo DICOM existentes ya,
como el sexo del paciente, nombre del fabricante, ID del paciente, etc, pero es muy
importante ser capaces de crear nuestros propios campos, como por ejemplo el número
de virus, diagnóstico del médico, y en definitiva, los que se crean convenientes.
Para ello se han dispuesto en la GUI ciertos botones (figura 6.33) que son capaces
hacer este servicio.
Figura 6.33: Crear campos nuevos
r
GVA-ELAI-UPMPFC0075-2003
239
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Se tiene la posibilidad de crear campos donde se albergan datos de tipo Integer o
datos de tipo String, es decir, campos para datos numéricos y campos para datos de
texto.
El código crear campo numérico básicamente es:
void jButton6 actionPerformed(ActionEvent e)
{
.......
DDictEntry entrarDDict1 = new DDictEntry(new Integer(
campoGrupoNumero.getText()) .intValue(), new Integer
(campoElementoNumero.getText()).intValue(), DDict.tUS,
campoNuevoNumero.getText(),"1");
diccionario.addEntry(entrarDDict1);
dcm.set ge(new Integer(campoGrupoNumero.getText()).
intValue(),new Integer(campoElementoNumero.getText()).
intValue(),new Integer(numero.getText()));
.......
}
Este es el código que se ejecuta en el momento en que el botón es pulsado.
Lo primero que se hace es crear una instancia de la clase DDictEntry. Al pasar
los parámetros fijamos el número de grupo, el número de elemento, la descripción del
campo y el tipo de dato DICOM que se puede meter en éste campo.
Una vez hecho esto, creamos un objeto de la clase DDict, en la cual vamos a
insertar nuestro nuevo campo por medio del método addEntry(DDictEntry a).
En este momento tenemos la posibilidad de poder meter en el objeto de la clase
DicomObject (dcm) el nuevo dato mediante el método it set_ge(grupo,elemento,dato),
que en este caso debe ser un Integer ya que el tipo US DICOM es tipo Integer en
Java. Ver tablas de conversión 5.1 y 5.2.
Para el caso de insertar un campo que alberge un dato de tipo String se ha
procedido de la misma forma:
void jButton5 actionPerformed(ActionEvent e)
{
.......
DDictEntry entrarDDict2 = new DDictEntry(new Integer(
campoGrupoTexto.getText()) .intValue(), new Integer (
240
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
Figura 6.34: Nuevo campo insertado
campoElementoTexto.getText()).intValue(), DDict.tST,
campoNuevoTexto.getText(),"1");
diccionario.addEntry(entrarDDict2);
dcm.set ge(new Integer(campoGrupoTexto.getText()).intValue(),
new Integer(campoElementoTexto.getText()).intValue(),
new Integer(numero.getText()));
.......
}
Donde lo único que cambia es el tipo de dato que vamos a insertar, por lo que el
tercer parámetro que se pasa al constructor de la clase DDictEntry es DDict.tST.
6.7.4.
Panel Procesamiento
Este panel sirve para poder procesar una imagen mediante un algoritmo desarrollado por el GVA. Este panel visualiza la imagen de origen a procesar y ejecuta el
r
GVA-ELAI-UPMPFC0075-2003
241
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
algoritmo de procesamiento y cuando acaba éste se visualiza en el panel de imagen
procesada (a la derecha).
Figura 6.35: Panel Procesamiento
Esta panel funciona si está instalado previamente el MATLAB, el programa utilizado para el tratamiento de las imágenes.
Introducción del algoritmo en la aplicación
Pasos a seguir:
1. Lo primero que se debe hacer es poner en las variables de entorno los caminos
para encontrar las librerı́as necesarias:
C:/AWouter/bin/win32; C:/AWouter; C:/matlab6p5/bin/win32;
Esto significa que antes se ha debido copiar en estas carpetas los archivos solicitados.
En la carpeta C:/AWouter se deben copiar los archivos applylut.dll y dataread.dll.
242
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
2. Después se debe ejecutar el setup mglinstaller.exe que instala las librerı́as necesarias de Matlab.
3. Se debe copiar el ejecutable en la carpeta C:/AWouter.
4. Copiar los archivos
5. Después se tiene que crear una carpeta donde se ponen las librerı́as para sólo
este algoritmo:
C:/matlab6p5/toolbox/images/images/private y se incluyen en ésta bwlabel1.dll
y bwlabel2.dll.
Si hubiera algún error con los ficheros “MSVCRTD.DLL” y “MSVCIRTD.DLL”,
copiarlos en las carpetas C:\WINNT\system32, en C:\AWouter y en C:\Matlab6p5\win32.
Esto es a nivel de sistema. Una vez hecho esto se debe realizar una implementación
para que este algoritmo se pueda ejecutar desde nuestro GUI (graphical user interface). Para hacer esto se dan estos pasos:
En el panel de procesamiento se han creado dos JLabel donde poner las imágenes
de origen y la de salida o procesada. Se ha incluido además un JTextArea para decir el
camino y el nombre de la imagen procesada y dos botones, uno para abrir la imagen
a procesar y otro para empezar el procesamiento. Figura 6.35.
Pasos en JBuider7.0:
1. Incluir en el proyecto los archivos CntVirRel.exe y files.txt mediante el botón
que se muestra en la figura 6.36.
2. Se ha implementado de la siguiente forma:
Botón Imagen a tratar. Figura 6.37
void botonSeleccionImagen actionPerformed(ActionEvent e)
{
.....
fotoEntradaCamino = jFileChooser1.getSelectedFile().
getAbsolutePath();
ImageIcon iconoEntrada = new ImageIcon(fotoEntradaCamino);
imagenEntrada = iconoEntrada.getImage();
etiquetaImagenEntrada.setIcon(iconoEntrada);
String caminoFicheroTxt = "files.txt";
File filesTxt= new File(caminoFicheroTxt);
FileOutputStream chorro = new FileOutputStream(filesTxt);
PrintStream escribirEnArchivo = new PrintStream(chorro);
r
GVA-ELAI-UPMPFC0075-2003
243
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Figura 6.36: Botón para añadir archivos al proyecto
escribirEnArchivo.println(fotoEntradaCamino);
imagenProcesada = textoImagenSalida.getText();
escribirEnArchivo.println(imagenProcesada);
etiquetaSeleccionImagen.setText(fotoEntradaCamino);
......
Donde se muestra la imagen de entrada (setIcon) y se escribe el camino
de entrada y de salida en el fichero files.txt de donde después con el botón
que se ve a continuación se saca esta información.
Figura 6.37: Botón para abrir imagen a procesar
En el botón Procesar imagen. Figura 6.38.
void botonProcesamiento actionPerformed(ActionEvent e)
{
Process p = Runtime.getRuntime().exec
("c:/AWouter/CntVirRel.exe");
int valorRetorno = p.waitFor();
ImageIcon iconoSalida = new ImageIcon
(textoImagenSalida.getText());
etiquetaImagenSalida.setIcon(iconoSalida);
.....
244
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
Donde las clases importantes son Process con su método getRuntime().exec()
para ejecutar en este caso un archivo .exe y también el método waitFor()
que hace que la ejecución del código se pare hasta que el proceso no finalize.
Figura 6.38: Botón para procesar imagen
6.7.5.
Panel Crear DICOM
La función de este panel es la de poder crear un archivo DICOM a partir de
imágenes de formato jpeg y datos de texto.
Los datos de texto como el nombre del paciente, el aparato que hace la imagen,
la parte del cuerpo examinada, etc, se insertan de la forma vista en el “Panel Visor
Dicom”.
La parte nueva con respecto al panel de visualización de archivos DICOM es la
zona de meter los datos de imágenes nuestras en formato jpeg dentro del nuevo archivo
DICOM.
Estructura del Panel Crear DICOM
Este panel consta de varias partes:
1. Zona de visualización de imágenes a insertar. Figura 6.40
2. Zona de inserción de datos de texto. Figura 6.41
Inserción de una sola imagen
En esta parte vamos a ver la forma de cómo insertar los datos de una sóla imagen.
r
GVA-ELAI-UPMPFC0075-2003
245
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Figura 6.39: Panel Crear DICOM
Lo primero que se hace es visualizar la imagen a insertar en el área destinada
mediante el botón Abrir imagen y después mediante los botones Monochrome o RGB
metemos la imagen según sea en escala de grises o en color respectivamente.
Al abrir la imagen se graba en una instancia de la clase Image (Image imagenJPG;)
con la que se trabaja de esta manera:
1. Botón Monochrome:
La implementación de la función de este botón es de la forma:
void botonCrearDicomGris actionPerformed(ActionEvent e)
{
.......
String rutaArchivoDicomGuardar = jFileChooser1.
getSelectedFile().getAbsolutePath();
int[] pix = image2IntArray(imagenJPG);
dcmNueva.set(DDict.dSOPClassUID,"1.2.840.10008.5.1.4.1.1.7");
dcmNueva.set(DDict.dSOPInstanceUID,"1.2.840.10008.5.1.4.1.1.7");
246
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
Figura 6.40: Imagen para crear un archivo Dicom
dcmNueva.imagePixelData(imagenJPG.getHeight(null),imagenJPG.
getWidth(null),8,8,7,pix);
dcmNueva.write(salvar,true);
.......
}
Donde image2IntArray es un método que mediante la clase PixelGrabber es
capaz de coger los datos de la imagen pixel a pixel, por lo que el resultado es
un array de int donde se encuentran estos datos.
Las dos lı́neas siguientes se colocan debido a que son datos que se deben encontrar obligatoriamente en un archivo DICOM, ya que sin ellos no es posible
crear el archivo.
Más tarde, en nuestra instancia de la clase DicomImage (DicomImage dcmNueva = new DicomImage();) se insertan estos datos de imagen mediante el
método de esta clase imagePixelData(int filas, int columnas, int planarConf,
int[] pixelData).
Una vez hecho ésto se puede comprobar que los resultados son satisfactorios al
ir al panel VisorDicom y tratar de abrir el archivo creado, donde s3e pueden
ver los resultados. Figura 6.42
r
GVA-ELAI-UPMPFC0075-2003
247
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Figura 6.41: Datos de texto a insertar
2. Botón RGB:
Para el caso de la imagen en color se realiza de la misma forma. La diferencia
es que se usa otra implemtentación del método imagePixelData ya que es un
método sobrecargado y se utiliza debido al cambio de parámetros que se pasan
a éste:
imagePixelData(int rows, int cols, int planarConf,
int[] pixelData);
Por lo que queda de la siguiente manera:
dcmNueva.imagePixelData(imagenJPG.getHeight(null),
imagenJPG.getWidth(null),0,pix);
Los resultados se pueden comprobar igualmente visualizando el archivo creado.
Figura 6.43.
Compresión de archivos Dicom Monochrome
Se ha visto cómo crear un archivo DICOM de escala de grises, pero al hacer ésto
se tiene un problema: el tamaño de los archivos es muy grande debido a que no se ha
248
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
Figura 6.42: Comprobación de la creación de archivo Dicom en escala de grises
realizado ningún tipo de compresión a los datos de pı́xel, por lo que el espacio que
ocupan es bastante grande.
Para ello se ha recurrido a la clase de la API de JDT llamada Compression, la
cual proporcina métodos para realizar compresiones de estos datos.
Para realizar la compresión se actúa de la siguiente forma:
void botonComprir actionPerformed(ActionEvent e)
{
.......
Compression c = new Compression(dcmNueva);
c.compress(TransferSyntax.JPEGLossless);
.......
}
Se crea una instancia de la clase Compression (c) que después usa su método
compress, el cual necesita saber el tipo de compresión a usar. En este momento se
r
GVA-ELAI-UPMPFC0075-2003
249
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Figura 6.43: Comprobación de la creación de archivo Dicom en RGB
tiene que decir que el único tipo de compresión que realiza este servicio es el señalado
arriba, TransferSyntax.JPEGLossless, mientras que con los otros tipos no se consigue
lo buscado con la limitación de que funciona sólo con imágenes monochrome.
La diferencia de tamaño de un archivo comprimido a uno sin comprimir es:
No comprimido: tamaño = X
Comprimido: tamaño = X / 2
Inserción de varias imágenes
Para este caso se ha introducido en un array de Image todas las imágenes que se
quieren insertar en el archivo DICOM.
Una vez insertadas, se procede a sacar los datos de pı́xel de estas instancias Image.
En este caso se van a guardar estos datos en una matriz de bytes en vez de array int.
250
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
Teniendo la matriz de bytes (byte[][]), se continúa uniendo todos estos bytes en
un sólo array de bytes (byte[]) donde van uno detrás de otro.
Una vez hecho ésto se procede a insertar estos datos en el archivo DICOM a crear.
Para todo esto se usan diferentes botones que realizan las diferentes funciones
vistas antes:
1. Botón No de imágenes: donde se señala el número de imágenes que vamos a
insertar. En el código se da valor a una variable que es utilizada para saber el
número de instancias Image que se deben guardar en el array Image[].
La implementación es:
void iniciarArrayImages actionPerformed(ActionEvent e)
{
imagenSecuencia = new Image [new Integer(
datoPantalla.getText()).intValue()];
}
2. Botón Abrir imágenes a insertar: mediante este botón se van almacenando en
el array las imágenes, hasta que se almacena la última, y es en este momento
cuando aparece un nuevo cuadro que te pregunta por el lugar y el nombre donde
insertar este arhivo DICOM. La implementación básica es:
void botonAbrirImagen actionPerformed(ActionEvent e)
{
........
imagenSecuencia[numeroDeImagen] = imagenJPG;
numeroDeImagen++;
int imagenesTotales = new Integer(datoPantalla.
getText()).intValue();
if(numeroDeImagen == imagenesTotales)
{
byte[][] secuenciaBytes = new byte
[imagenesTotales][];
int n,nBytes=0;
for(n=0;n<imagenesTotales;n++)
{
byte[] ver = image2ByteArray(imagenSecuencia[n]);
secuenciaBytes[n]=image2ByteArray
(imagenSecuencia[n]);
}
arrayDeArrayDeBytes=secuenciaBytes;
byte[] todoJunto = unirBytesArray(secuenciaBytes,
r
GVA-ELAI-UPMPFC0075-2003
251
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
imagenesTotales);
todosBytesJuntos = todoJunto;
if (JFileChooser.APPROVE OPTION == jFileChooser1.
showSaveDialog(this))
{
try
{
String rutaArchivoDicomGuardar = jFileChooser1.
getSelectedFile().getAbsolutePath();
........
dcmNueva.imagePixelData(imagenJPG.getHeight(null),
imagenJPG.getWidth(null),8,8,7,todosBytesJuntos);
........
dcmNueva.write(salvar,true);
........
}
}
}
Como se ve en este código, una vez recogidas todas las instancias Image en el
array, se pasa a sacar de cada objeto Image sus datos de pı́xel y se reunen en
una matriz de bytes llamada arrayDeArrayDeBytes.
Una vez hecho esto, se unen esos array de bytes en uno sólo mediante el método
unirBytesArray(byte[][] secuencia, int numeroDeImagenes), el cual es el dato a
insertar en nuestro archivo DICOM, donde se recogen todas nuestras imágenes.
Comprimir archivo DICOM de varias imágenes monochrome
Este archivo está sin compresión. Se puede realizar una compresión como la indicada antes y la reducción de tamaño es de la relación 2 a 1 aproximadamente, es decir
el tamaño del archivo comprimido es la segunda parte del archivo sin comprimir.
El único sistema de compresión soportado sigue siendo JPEGLossless de estas
librerı́as y más particularmente de la clase Compression.
252
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
Figura 6.44: Generación de ejecutables
6.7.6.
Distribución e instalación de la aplicación
Generación de ejecutables
Una vez creada la versión Beta de nuestra aplicación Cliente DICOM es importante
poder distribuirla para que sea ejecutada sobre cualquier sistema operativo, siendo
de esta manera una aplicación multiplataforma.
Figura 6.45: Creador de ejecutables
Para la generación de los ejecutables, JBuilder cuenta con un asistente el Creador
de ejecutables nativos. Ver figura 6.44.
r
GVA-ELAI-UPMPFC0075-2003
253
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
Fernando Ballesteros Herranz
Pasos a seguir:
1. Seleccionar Asistentes->Creador de ejecutables nativos. . .
2. Escribir el nombre del ejecutable. En nuestro caso DICOM.
3. Seleccionar: incluir siempre todas las clases y recursos.
4. Seleccionar: JDT e incluir siempre todas las clases y recursos.
5. Pulsar Siguiente en los pasos 4 y 5, con las opciones marcadas por defecto.
6. Marcar en el paso 6 los ejecutables que queramos crear dependiendo del sistema
operativo en el que se vaya a utilizar.
7. Pulsar Finalizar
8. Una vez realizado esto, se generará en el panel de proyectos un archivo que
se llama igual a como habı́amos llamado al ejecutable que queremos generar.
Entonces lo marcamos y pulsamos en Proyecto->Generar Make del proyecto,
de esta forma se generarán los ejecutables que pueden ser para Windows, para
Linux, para Solaris, para Mac/OS y multiplataforma como el .jar.
Figura 6.46: Marcas de la creación de ejecutables
De esta forma conseguimos que el programa este en un solo ejecutable.
Para el caso del servidor se puede o bien crear el recopilatorio .jar o bien ejecutar
cuando se quiera poner el funcionamiento el .class, ya que el servidor se debe poner
solo una vez en funcionamiento y no hace falta ningún tipo de administración.
Para crear el .jar de una aplición no basada en GUI se hace de la forma descrita
en el apartado de Utilidades de SDK, utilizando la utilidad jar.
254
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
6.7. IMPLEMENTACIÓN DE CLIENTE DICOM
Instalación
Para la instalación de la aplicación cliente hay que seguir los siguientes pasos:
1. Instalación de la Máquina Virtual de Java.
2. Creación de carpeta que se llame “BaseDeDatos” en la raı́z, es decir, para
sistema Windows es C:\. En esta carpeta es donde llegarán los estudios DICOM
que queramos coger del servidor.
3. Poner el programa DICOM en un lugar de fácil ejecución.
4. Instalación del Panel Procesamiento.
5. Retrasar el reloj del ordenador al año 2002, si se utiliza la versión de prueba
Beta.
Para poner el programa, tan solo hay que ejecutar el programa cliente, en nuestro
caso CuatroW.exe
Para la instalación del servidor DICOM:
1. Instalación del SDK entero.
2. Instalación de librerı́as JDT.
3. Creación de carpeta que se llame “BaseDeDatos” en la raı́z, es decir, para
sistema Windows es C:\. Esta carpeta es donde se deben encontrar los estudios
de la base de datos del servidor.
4. Retrasar el reloj del ordenador al año 2002, si se utiliza la versión de prueba
Beta.
5. Poner los .class que en este caso son Storagescp.class, Storagescu.class, Connection.class y Encri.class en la raı́z que en Windows es C:\.
Para poner el servidor en funcionamiento, abrir un Shell de comandos, y ejecutar
en C:\:
java Storagescp
De esta forma saldrá un mensaje que pone “Puerto 104 a la escucha”.
r
GVA-ELAI-UPMPFC0075-2003
255
CAPÍTULO 6. DESARROLLO DE APLICACIÓN
6.8.
Fernando Ballesteros Herranz
Conclusiones
El programa realizado es una muestra clara de que el estándar DICOM es operativo
y muy útil a la hora de la administración de estudios médicos desde diferentes puntos
a grandes distancias.
Esta aplicación es una versión beta de un posible programa mucho más avanzado
que de soporte a más funciones del estándar DICOM. Ha sido desarrollado en Java
por lo cual hace que sea un sistema multiplataforma y más eficiente.
Cierto es que utilizando las librerı́as JDT se han detectado limitaciones no respecto
a lo establecido en el estándar sino con la encriptación de los datos de los pacientes
por la red.
A pesar de ello, se trata de una tecnologı́a que está madurando con mucha rapidez,
estabilidad y fiabilidad. Cabe esperar que en los próximos años DICOM vaya a ser
cada vez más utlilizado en el ámbito de la medicina y la investigación.
El único inconveniente de esta aplicación es que es una versión beta, y por ella sola
no funciona, debe ser retrasado el reloj de la máquina sobre la que estemos trabajando
al año 2002, para ası́ tener un año de utilidad este programa. Si se quieren más años
tan solo habrı́a que retrasar el reloj más tiempo atrás.
256
r
GVA-ELAI-UPMPFC0075-2003
Apéndice A
Administración de sistemas
[GUNT] [LEBLA] [RUSSE97] [STIN]
En este apéndice se recopilan los aspectos más importantes en el amplio mundo
de Windows NT 4.0 y Windows 2000 para que cualquier persona con un mı́nimo de
conocimientos en informática sea capaz de manejar esta plataforma.
A.1.
Introducción a Windows NT y 2000
A.1.1.
Presentación del sistema operativo NT
Tanto el sistema operativo Windows NT 4.0 como el sistema operativo Windows
2000, tienen semejanza en su forma interna, ya que el Kernel es muy semejante. Cada
vez que se refiera a sistemas operativos NT, se incluyen Windows NT 4.0 y Windows
2000.
El sistema operativo NT fue desarrollado por Microsoft para superar los obstáculos
impuestos por la vieja arquitectura de sus sistemas operativos MSDOS y Windows.
NT es un sistema operativo completo, que puede ser instalado sobre un equipo nuevo
sin necesidad de software adicional, como le ocurre a Windows 3.x, y que ofrece nuevas
tecnologı́as para el desarrollo y ejecución de todo tipo de aplicaciones.
Algunas de sus caracterı́sticas más importantes son:
Robustez. NT es un sistema operativo estable y robusto, que impide a las
aplicaciones mal escritas estropear al resto del sistema.
257
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
Seguridad. NT ha sido escrito para satisfacer criterios de seguridad tı́picos
de organismos oficiales y empresas cuyos datos y aplicaciones deben quedar a
salvo de accesos no autorizados. Prácticamente cada objeto del sistema posee
un esquema de seguridad asociado que indica qué usuarios pueden acceder al
objeto y con qué privilegios pueden acceder.
Portabilidad. El diseño de NT permite que se pueda adaptar fácilmente a otras
arquitecturas para las que no fue originalmente desarrollado. Actualmente soporta las arquitecturas de Intel X86, MIPS, Alpha y PowerPC. Su diseño modular y el estar escrito en lenguaje fácilmente portable, como es el C, permite
esta rápida migración.
Compatibilidad con las aplicaciones Windows. La capacidad de NT para ejecutar aplicaciones MSDOS y Windows permite disponer de gran cantidad de
software escrito que permite sacar rendimienteo al sistema sin tener que migrar las aplicaciones. Incluso las nuevas aplicaciones Win32 corren en modo
nativo en las diferentes plataformas de NT, simplemente recompilándolas para
cada plataforma, o incluso a través de los emuladores-compiladores JIT (Just
In Time) como son el X86, distribuido gratuitamente para las plataformas no
Intel soportadas.
Velocidad. NT está desarrollado para hacer frente a las aplicaciones que necesitan gran cantidad de recursos y altas velocidades de ejecución, tı́picas de entornos cliente/servidor y de ingenierı́a, como pueden ser servidores de recursos
de red, de bases de datos y programas de cálculo cientı́fico y diseño gráfico.
A.1.2.
Sistemas de archivos
Hay varios tipos de gestores de archivos para los equipos, éstos son utilizados
dependiendo del sistema operativo y la gestión realizada por el administrador de la
red:
FAT: 16 bits, es compatible con Windows 95/98/NT/2000/XP y MS-DOS. Es
el más utilizado en la gestión de los archivos en los disquetes. Los clúster son
de 32 KB, esto quiere decir que los datos se guardan en paquetes de 32 KB. Un
fichero que ocupe 33KB, ocupará 2 clúster, por lo que se desperdician 31 KB
del 2o clúster.
FAT 32: 32 bits, compatible con Windows 95/98/2000/XP. Más eficiente que
las particiones FAT.
NTFS: Utilizado por los sistemas basados en Red, Windows NT/2000/XP. Los
clúster son de menor tamaño, son de 4 KB, de esta forma se aprovecha mejor
el espacio en el disco.
258
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.1. INTRODUCCIÓN A WINDOWS NT Y 2000
Ext 32: sistema de gestión de archivos utilizado por equipos Unix y sistema
operativo Linux.
Hay más tipos de gestores de archivos, sólo se han señalado los que pueden ser
interesantes en una administración de equipos de una Red basada en Windows y a lo
sumo la utilización de Samba para la compatibilidad con equipos con Linux.
A.1.3.
El interfaz de usuario de NT
NT hereda los interfases de usuario desarrollados para la familia Windows. Por
ejemplo en las versiones 3.X de NT se utilizan el administrador de programas y demás
elementos del Windows 3.X, mientras que en NT 4.0 se emplea el nuevo interfase de
Windows 95/98. Esto permite reducir la curva de aprendizaje para el nuevo sistema
operativo. NT saca un mejor provecho que los diferentes Windows a la ejecución de
aplicaciones en multitarea real, permitiendo ejecutar varias aplicaciones simultáneamente, conmutando rápidamente entre ellas.
NT puede ejecutar varios tipos de aplicaciones:
Aplicaciones MSDOS. La mayor parte de las aplicaciones MSDOS corren sin
problemas.Sólo aquellas que acceden directamente a recursos especı́ficos, como
pueden ser el puerto serie o el paralelo, o que intentan capturar las interrupciones básicas de MSDOS, no funcionan. Tı́pico ejemplo de estas aplicaciones
son las que funcionan con llaves de protección del tipo “mochila” que no están
especı́ficamente preparadas para NT.
Aplicaciones Windows de 16 bits. La mayor parte de las aplicaciones de 16 bits
funcionan sin problemas bajo Windows NT. Algunas aplicaciones, que utilizan
llamadas no documentadas a las APIs de Windows, o que hacen suposiciones
sobre los recursos de Windows que son sólo válidos en Windows 3.x fallan al
ejecutarse sobre NT.
Aplicaciones Win32. Son las nuevas aplicaciones desarrolladas para Windows 95
y NT. Las aplicaciones Win32 eliminan gran parte de los problemas que tenı́an
las aplicaciones Win16, que están basadas en el modelo plano de memoria, que
permite a las aplicaciones disponer de hasta 2 gigabytes de datos. Las aplicaciones Win32 se ejecutan siempre como multitarea real, en espacios de memoria
separados que evitan que el mal funcionamiento de una de ellas repercuta en las
demás. Además las aplicaciones Win32 hacen uso de las nuevas APIs Win32,
más potentes y flexibles, con capacidad de ejecución de múltiples hilos. Esto
permite a las aplicaciones ejecutar tareas de fondo, como la revisión ortográfica, recálculo, repaginación e impresión tı́pica de los procesadores de texto y de
r
GVA-ELAI-UPMPFC0075-2003
259
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
las hojas de cálculo. Esto evita al usuario largos tiempos de espera en su trabajo
habitual.
Aplicaciones POSIX. Son aplicaciones basadas en el estándar común POSIX,
un subconjunto de las APIs de UNIX. El susbsistema POSIX emula el comportamiento de las aplicaciones UNIX, incluyendo elementos como el uso de
enlaces (links) para los ficheros. Para desarrollar aplicaciones POSIX para NT
se puede utilizar el compilador que se distribuye en el kit de recursos, o una
nueva distribución del popular GCC de GNU (distribución Cignus) que incluye
un soporte mucho más avanzado tanto de aplicaciones Win32 como de aplicaciones POSIX. Este compilador se puede encontrar en los espejos de GNU en
la red.
Aplicaciones OS/2. Se pueden ejecutar aplicaciones OS/2 de modo texto. Las
aplicaciones basadas en Presentation Manager se pueden ejecutar utilizando un
módulo adicional disponible a través de Microsoft.
A.2.
La red Microsoft Windows
Para ver el funcionamiento de la red Microsoft hay que distinguir dos partes:
La parte fı́sica de la red. El funcionamiento básico de la red Microsoft, basado
en el protocolo Netbeui, supone que todos los miembros de la red están interconectados entre sı́. Esto implica que no hay barreras del tipo conmutadores
o encaminadores de red entre las diversas partes de la red. Cuando aparece
este tipo de elementos se utilizan otros protocolos, como el TCP/IP o el IPX,
que encapsulan el protocolo Netbeui, permitiendo la integración del la red local
dentro de una red más compleja.
Para la parte lógica de la red, el esquema de red de Microsoft permite trabajar
de dos modos diferentes: como grupos de trabajo y como dominios.
A.2.1.
Los grupos de trabajo
En los grupos de trabajos los servidores y estaciones de trabajo configuran una red
local del tipo de igual a igual. En este modo de funcionamiento, en principio todos los
ordenadores pueden ser clientes y servidores simultáneamente. Los grupos de trabajo
fueron introducidos por Microsoft cuando introdujo en el mercado Windows para
Trabajo en Grupo. Este esquema de funcionamiento es bastante sencillo, ya que no
precisa de la existencia de la figura del administrador del grupo.
260
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.2. LA RED MICROSOFT WINDOWS
Todos los ordenadores a priori se comportan de la misma forma, pudiendo acceder
todos ellos a los demás ordenadores de la red. Esto no impide que dentro de un grupo
de trabajo se puedan introducir máquinas configuradas exclusivamente como clientes
o como servidores.
A.2.2.
Los dominios NT
El sistema de dominios en NT hereda la funcionalidad que permitı́a obtener los
dominios Lan Manager de Microsoft. El esquema de dominios aporta grandes ventajas
en la seguridad de la red, aunque añade mayor carga administrativa. En un grupo de
trabajo, al no existir la figura del administrador, deben ser los propios usuarios los que
se encarguen de la configuración de la seguridad. El sistema de dominios introduce la
figura del administrador. Éste es el responsable de mantener la seguridad del dominio,
dando de alta a los usuarios y asignándoles privilegios de acceso a los recursos del
dominio.
Un dominio está compuesto por al menos un controlador primario del dominio
y por estaciones de trabajo que actúan como clientes del dominio. El controlador
principal del dominio va a ser el ordenador que va a almacenar la base de datos
de usuarios y de ordenadores del dominio. Un dominio puede tener varios tipos de
clientes:
Clientes Windows para trabajo en Grupo, Windows 95/98, Windows NT/2000
Workstation y Server.
Ordenadores con MSDOS o Windows 3.1, con el cliente de red Microsoft instalado.
Ordenadores con OS/2 o Macintosh
Otros tipos de ordenadores, por ejemplo los que usan LAN Manager para UNIX,
o con el software de SMB (por ejemplo Samba).
A.2.3.
Uso de los dominios de NT
El sistema de dominios introduce una mayor carga administrativa sobre el sistema
de grupos de trabajo cuando la red es pequeña. El sistema de dominios necesita una
mayor planificación inicial frente al grupo de trabajo, ya que el administrador debe
dar de alta a los usuarios y equipos. Sin embargo, al ampliar la red esa mayor carga
administrativa inicial se traduce en una mayor simplicidad de la administración de una
red corporativa. Cuando el número de ordenadores y de usuarios de la red comienza a
r
GVA-ELAI-UPMPFC0075-2003
261
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
superar las decenas, la estructura creada por el dominio aporta numerosas ventajas.
La primera y más importante es la seguridad del dominio.
En un dominio la base de datos de usuarios y de equipos es única, y está centralizada. A cada usuario se le asigna una cuenta que le identifica en el dominio. En
principio la autenticidad del usuario está garantizada por el uso de su contraseña.
Esto facilita al usuario el acceso a los recursos del dominio, ya que la mayor parte
de las veces no necesitará introducir su contraseña. El esquema de dominios permite
además crear grupos de usuarios. Los grupos de usuarios facilitan la administración
de los dominios ya que permite asignar seguridad, aplicaciones y otros recursos del
dominio a grupos de usuarios con caracterı́sticas comunes. El sistema de grupos de
usuarios es muy flexible, permitiendo adaptar el dominio a la estructura corporativa.
Un usuario del dominio puede pertenecer a varios grupos, de manera que cada uno
de los grupos a los que pertenece le permita realizar una serie de tareas diferentes.
El sistema de dominios simplifica la administración de servidores y estaciones de
trabajo. A medida que se añaden estaciones y servidores al dominio, el administrador
utiliza las herramientas administrativas para darlos de alta en el dominio. Cuando
un equipo es dado de alta en el dominio puede comunicarse de una manera segura
con los demás miembros del dominio. De esta manera puede reconocer a los demás
usuarios y equipos del dominio. Esta tarea es realmente sencilla. Durante el proceso
de instalación de una estación de trabajo o servidor NT, aparece un cuadro de diálogo
en el que se da la oportunidad de añadir el equipo al dominio. Para añadir el equipo
basta escribir el nombre del dominio y nombre de usuario y contraseña con privilegios
de administrador válido en el dominio. El proceso de instalación se pone en contacto
con el controlador del dominio y da de alta al ordenador en el dominio. Una vez que se
ha dado de alta en el dominio, el programa de instalación configura automáticamente
el sistema para que sea miembro del dominio. El proceso completo se desarrolla en
pocos segundos y sin intervención del usuario.
El sistema de dominios simplifica enormemente la gestión de grandes dominios, ya
que los cambios introducidos en la configuración del dominio se reflejan automáticamente en todos los miembros del dominio. Si por ejemplo se añade un nuevo equipo
al dominio, queda disponible para el uso por los demás miembros del dominio.
A.2.4.
Elementos de un dominio
En un dominio se pueden integrar varios tipos de servidores y de clientes. En todo
dominio puede haber:
Un controlador principal del dominio. Es obligatorio, ya que es el equipo que
mantiene la base de datos del dominio. Este servidor debe ser obligatoriamente
262
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.2. LA RED MICROSOFT WINDOWS
un NT Server configurado como controlador principal del dominio.
Controladores de reserva del dominio. Puede haber varios en el dominio. Su
labor consiste en ayudar al controlador principal en caso de sobrecarga o mal
funcionamiento de éste. Es recomendable siempre tener al menos un controlador de reserva correctamente configurado, ya que de este modo se asegura que
siempre los usuarios podrán iniciar sesión correctamente en el dominio.
Estaciones de trabajo. Son los clientes del dominio, y pueden ser de diferentes
tipos (Windows, Os/2, etc.)
Servidores NT. Se puede configurar NT Server en el modo servidor. En este
modo, el servidor no colabora en la validación de los inicios de sesión por parte
de los usuarios, con lo que la carga del servidor es menor. Este modo se suele
utilizar para configurar servidores de ficheros y aplicaciones, como servidores
SQL y de Internet. Además, un NT Server configurado como servidor mantiene
su propia base de datos, además de poder acceder a la del dominio. Esto permite
tener cuentas separadas de las del dominio. El uso fundamental que se puede
dar a esta funcionalidad consiste en crear grupos de usuarios ajenos al dominio,
que se pueden eliminar fácilmente sin más que eliminar el servidor.
Otros tipos de servidores. Hay varios sistemas operativos que de alguna forma
pueden acceder al dominio NT, normalmente con sus propias herramientas de
integración. Por ejemplo, desde que Microsoft hizo público el protocolo SMB,
hay sistemas que soportan parte de la funcionalidad de este protocolo, aunque
no se pueden construir controladores de dominio con otros sistemas operativos.
A.2.5.
El sistema de recursos de red
En una red Microsoft se pueden compartir varios tipos de recursos, como pueden
ser impresoras y unidades de red. En una red Microsoft el nombre de los recursos
sigue el siguiente convenio:
\\servidor\recurso
escrito en el formato UNC (Universal Name Convention). Servidor es el nombre
del servidor que comparte el recurso. Recurso es el nombre que se le da al recurso.
En el caso de recursos del tipo unidad de red, detrás del nombre de recurso se puede
poner la ruta completa de directorios, y el nombre de un archivo cuando nos estamos
refiriendo a un archivo remoto, de este modo:
\\servidor\recurso\directorio\directorio\fichero.exetension
Además de poder compartir unidades de disco e impresoras, se pueden compartir
r
GVA-ELAI-UPMPFC0075-2003
263
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
otro tipo de recursos, como unidades CD-ROM, modems, fax (con el software adecuado, no incluido en NT), y otros tipos de recursos especiales, como pueden ser las
tuberı́as creadas entre el controlador del dominio y los ordenadores conectados a él.
Para crear los recursos se deben utilizar las herramientas apropiadas en cada caso:
Para unidades de red, se utiliza el explorador de Windows NT, o el administrador de archivos (Winfile.exe)
Para compartir impresoras se utiliza el administrador de impresión.
Para tipos especiales de recursos, normalmente hay herramientas especiales que
lo hacen. Normalmente todos los recursos compartidos aparecen en los listados
de recursos de red de todos los clientes. Se puede modificar el nombre de recurso
para que no aparezca en los listados de recursos. A este tipo de recursos se les
llama recursos compartidos en modo administrativo.
Para compartir un recurso en modo administrativo basta con añadir un signo $ al
final del nombre de recurso:
Por ejemplo, siempre que se inicia NT, el sistema de red comparte automáticamente en modo administrativo las unidades de disco. Ası́ por ejemplo tendremos:
\\servidor\c$
\\servidor\d$
compartidas automáticamente al arrancar el ordenador. Luego se pueden dejar
de compartir, si fuese necesario. Además NT añade los permisos correspondientes
para que sólo tengan acceso los administradores. Para ver los recursos compartidos
en modo administrativo se puede:
Abrir el Panel de Control, en el icono Servidor, y ver los recursos compartidos.
Abrir el Administrador de Servidores de NT Server, y seleccionando un servidor
o estación de trabajo, ver los recursos compartidos.
Este mecanismo permite de una manera muy cómoda acceder a los administradores a los diferentes discos de todas las estaciones de trabajo del dominio,
para realizar labores de copia de ficheros, instalación de aplicaciones, y otras
tareas. Para conectarse a un recurso compartido en modo administrativo, ya
que su nombre no aparece en los listados de recursos, debemos seleccionarlo
manualmente:
264
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.2. LA RED MICROSOFT WINDOWS
• Escribiendo su nombre directamente, en el cuadro de diálogo Conectarse
a una unidad de red.
• Utilizando NET USE \\servidor\recurso$.
Otra forma de acceder los administradores a los discos de las estaciones de trabajo
del dominio es:
1. click derecho en “Mis Sitios de Red”
2. elegir “Conectar a unidad de red. . . ”
3. se abre ventana con dos campos a rellenar:
Uno es “Unidad” donde pondremos el nombre de como ese recurso compartido en modo administrador se llamará en nuestro ordenador. En “Mi
PC” aparecerá éste como si fuera una unidad más de nuestro ordenador.
Otro es “Carpeta”, donde se debe escribir a qué máquina queremos acceder
y a qué recurso. Esto se hace escribiendo: //Servidor/recurso_compartido$
Figura A.1: Conectar a unidad de red
Éste es un buen método para escanear con antivirus las máquinas desde otras
máquinas.
r
GVA-ELAI-UPMPFC0075-2003
265
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
A.2.6.
Inicio de sesión en un grupo de trabajo
Cuando un usuario va a acceder a una red, lo primero que debe realizar es un inicio
de sesión. El inicio de sesión consiste en que el usuario debe introducir un nombre de
usuario y una contraseña, que serán utilizados por el sistema para acceder a la red.
Ya que en el grupo de trabajo no hay servidores dedicados a validar los inicios de
sesión, el inicio de sesión en Windows para trabajo en grupo es simple. El inicio de
sesión es un mero anuncio de que el usuario se dispone a utilizar los recursos de red.
No se realiza ninguna comprobación de seguridad, es decir, cualquier usuario puede
iniciar sesión con cualquier nombre dentro del grupo de trabajo. No existe ningún
mecanismo que impida al usuario iniciar sesión de red.
Durante el inicio de sesión en un grupo de trabajo, al usuario se le pide su nombre de usuario y su contraseña. En Windows para Trabajo en Grupo el nombre de
usuario se utiliza como identificador del usuario, aunque no hay ninguna garantı́a de
la verdadera identidad del usuario. La contraseña facilitada por el usuario se utiliza
para dos tareas:
Cuando se acceden a los recursos de red protegidos por contraseña, Windows
para Trabajo en Grupo facilita esta contraseña en primer lugar. Si la contraseña
no es válida, mediante un cuadro de diálogo se pedirá al usuario la contraseña
correcta para acceder al recurso.
La contraseña además se utiliza para encriptar el archivo de contraseñas, que
normalmente se llamará nombre.pwl, donde nombre es el nombre del usuario.
En este archivo se guardan las contraseñas utilizadas por el usuario para acceder
a los recursos de red.
Si un usuario ha olvidado la contraseña, no podrá desbloquear el archivo de contraseñas. Normalmente puede iniciar sesión con otro nombre de usuario, y borrar el
antiguo archivo de contraseñas, con lo que de nuevo podrá iniciar sesión en el sistema
con su nombre de usuario habitual.
El esquema de contraseñas de los grupos de trabajo suele ser bastante engorroso,
ya que cuando la contraseña de un recurso cambia obliga a difundir de nuevo las
contraseñas a los usuarios interesados. Además los archivos de contraseñas son muy
fáciles de desbloquear, existiendo en Internet numerosas utilidades que lo hacen. Windows para trabajo en grupo es bastante difı́cil de cerrar, para impedir el acceso al
sistema y a la red de un usuario que no tiene permiso para ello.
266
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.2.7.
A.2. LA RED MICROSOFT WINDOWS
Inicio de sesión en un dominio
Aparentemente el método de inicio de sesión en un dominio NT es similar al
utilizado en un grupo de trabajo. El usuario tiene que realizar el proceso de inicio de
sesión o logon, suministrando un nombre de usuario y una contraseña válida para el
dominio.
El proceso de inicio de sesión en un dominio es más sofisticado:
El usuario proporciona el nombre de usuario y la contraseña en el cliente del
dominio. Dependiendo del cliente, este procedimiento puede ser más o menos
seguro. Por ejemplo, en Windows para trabajo en grupo se siguen los mismos
pasos que para el inicio de sesión de red normal, aunque la contraseña para el
dominio hay que proporcionarla en un cuadro de diálogo separado, para mayor
seguridad. En Windows NT, el proceso de inicio de sesión automáticamente
registra al usuario en el dominio, y requiere el uso de una combinación especial
de teclas: Ctrl+Alt+Suprimir.
El cliente solicita el inicio de sesión al servidor controlador del dominio. En este
momento el servidor envı́a al cliente un conjunto de datos. Este esquema de
validación es un esquema de tipo desafı́o/respuesta.
El cliente encripta los datos enviados por el servidor con la contraseña que le ha
suministrado el usuario. Este nuevo conjunto de datos es enviado al servidor.
El servidor encripta los datos originales, con la contraseña del usuario que guarda en la base de datos de NT. Ahora compara ambos conjuntos de datos.
Si los datos codificados por el servidor y por el cliente coinciden, el servidor
valida al usuario para acceder al dominio.
Durante el proceso de inicio de sesión, la contraseña del usuario no viaja por la
red, ya que con el sistema de reto, lo que viajan son paquetes de datos codificados,
pero no la contraseña que los codifica. Este sistema tiene un punto vulnerable, ya que
en el servidor se almacenan las contraseñas de todos los usuarios en la base de datos
de usuarios. Sin embargo, se han introducido mejoras en el sistema de gestión de la
base de datos, que hace muy difı́cil el acceso a las contraseñas incluso para los propios
administradores de NT. Estas mejoras fueron introducidas con el Service Pack 3 para
NT Server.
El inicio de sesión en el dominio sólo se produce una vez. Es decir, una vez que
un usuario ha iniciado sesión en un dominio, no necesita suministrar de nuevo su
contraseña para acceder a los diferentes recursos del dominio. En todo momento, la
validación del usuario se va a realizar a través de los controladores y servidores.
r
GVA-ELAI-UPMPFC0075-2003
267
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
El sistema de seguridad de NT no sólo permite gestionar el acceso de los usuarios
a los recursos, sino que incluso se pueden crear grupos de usuarios a los que se les
asignan privilegios, por lo que la gestión de la seguridad se simplifica dentro del
dominio.
A.2.8.
Los controladores de dominio
Todo dominio tiene una base de datos de usuarios. La copia original de esta base
de datos reside en el controlador principal del dominio. En esta base de datos quedan
registradas todas las caracterı́sticas de los usuarios, sus cuentas, y de los ordenadores
que forman parte del dominio.
Además del controlador principal del dominio, puede haber dentro de un dominio
varios controladores secundarios del dominio. En estos controladores se mantiene una
copia de la base de datos de usuarios del dominio. Si el controlador del dominio
está muy cargado o simplemente está inactivo, cualquier controlador del dominio
puede validar el inicio de sesión en el dominio.
El proceso de inicio de sesión en los controladores del dominio comienza en el
cliente por obtener la lista de controladores del dominio. Para ello el servicio Examinador de computadoras obtiene dicha lista, bien mediante una pregunta por difusión
(broadcast), o bien preguntando a los servidores WINS del dominio. Una vez obtenida
la lista, el cliente envı́a una petición de inicio de sesión a los diferentes controladores
del dominio. El cliente elegirá al primer controlador de dominio que le conteste para
intentar el proceso de inicio de sesión. Este método asegura que siempre el cliente
pueda iniciar sesión en el dominio.
El mantenimiento de la base de datos del dominio es automático. Las herramientas administrativas de NT permiten modificar la base de datos, mediante el Administrador de usuarios para dominios.
Los cambios se realizan siempre sobre el controlador principal del dominio, y son
enviados automáticamente a los demás controladores del dominio. Hay que tener en
cuenta que esto se realiza con una pequeña demora temporal, que se puede reducir
sincronizando los servidores con el administrador de servidores.
A.2.9.
Diferencias entre NT Workstation y NT Server
El sistema operativo Windows NT se comercializa en dos versiones: Workstation
y Server.
268
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.3. EL ADMINISTRADOR DE USUARIOS
La versión Workstation está pensada para configurar puestos de trabajo, donde
se ejecutarán las aplicaciones de usuarios. NT Workstation es una plataforma que
incluye todos los elementos para trabajar con aplicaciones Windows y para trabajar
en red. Incluye una pila completa TCP/IP.
NT Server está preparado para configurar servidores. Aunque realmente los núcleos
de NT Server y Workstation son muy parecidos, la versión Server incluye una serie de
mejoras en el núcleo y en los diferentes módulos del sistema que lo hacen más robusto
en tareas de servidor de red. NT Server da mayor prioridad a los accesos mediante
red frente a las aplicaciones de usuario que se ejecutan en el servidor. Además NT
Server no tiene el lı́mite de 10 conexiones simultaneas de red que tiene NT Workstation. NT Server ofrece mayor seguridad en el almacenamiento de datos, ya que posee
caracterı́sticas avanzadas de tolerancia a fallos que no han sido incluidas en la versión
Workstation.
A.3.
El Administrador de usuarios
En NT hay dos tipos de usuarios, aquellos que pertenecen a una máquina que
corre NT WK o Server y aquellos que pertenecen a un dominio NT. Para cada uno de
estos tipos de usuarios existe una herramienta de administración: el administrador de
usuarios incluido en NT Workstation y el administrador de usuarios para dominios
incluido en NT Server (ver figura A.2).
Figura A.2: Administrador de Usuarios
El funcionamiento de ambos es muy similar, pero el administrador de usuarios
r
GVA-ELAI-UPMPFC0075-2003
269
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
para dominios dispone de más opciones. Por ello, se describirá el administrador de
usuarios para dominios.
Las tareas que se pueden realizar con el administrador de usuarios:
Añadir, modificar y eliminar usuarios del dominio.
Añadir, modificar y eliminar grupos locales y globales del dominio.
Fijar el plan de cuentas y contraseñas en el dominio.
Fijar la polı́tica de derechos de usuario en el dominio.
Establecer el sistema de auditoria en el dominio.
Establecer relaciones de confianza entre dominios.
A.3.1.
Creación y modificación de usuarios en el dominio
Crear un usuario nuevo
Para crear un usuario se pulsa Usuarios\Nuevo y se completa el cuadro de
diálogo. (Ver figura A.3).
Figura A.3: Administrador de Usuarios; usuario nuevo
En este cuadro hay que rellenar una serie de campos:
270
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.3. EL ADMINISTRADOR DE USUARIOS
Nombre de usuario Es el identificador que representa al usuario en el dominio.
Debe ser una palabra completa, sin espacios en blanco ni caracteres especiales,
de hasta 14 caracteres. este identificador debe ser único en el dominio. Se le
suele conocer también como nombre de cuenta o login. Este identificador es
el que se debe suministrar, junto con la contraseña, para iniciar sesión en un
dominio NT.
Nombre completo Es el nombre completo del usuario. Si este usuario es una persona se suele escribir el nombre y apellidos.
Descripción Conviene añadir una descripción de la labor, grupo de personas o departamento al que pertenecen el usuario, sobre todo si la base de datos de
usuarios en el dominio es grande.
Contraseña Aquı́ se debe escribir la contraseña para el usuario. Puede incluir espacios, mayúsculas y minúsculas, e incluso caracteres especiales. NT admite
hasta 14 caracteres. Cuando se va escribiendo aparecen asteriscos, y una vez
completada en el cuadro aparece una lı́nea de asteriscos, siempre de la misma
longitud.
Repetir contraseña Hay que introducir de nuevo la contraseña, para comprobar
que se ha escrito correctamente.
Tras estos campos aparecen una serie de botones activables:
El usuario debe cambiar su contraseña La primera vez que inicia sesión en NT
se va a solicitar que introduzca una nueva contraseña. Habitualmente los administradores crean los usuarios nuevos con contraseñas del tipo “cambiame”, que
obligan al nuevo usuario a cambiar su contraseña al iniciar sesión por primera
vez.
El usuario no puede cambiar su contraseña Se utiliza en tareas administrativas especiales, y bloquea el cambio de contraseña por parte del usuario.
La contraseña nunca caduca Desactiva la caducidad de contraseñas para esta
usuario. Se utiliza normalmente sólo para algunos usuarios que lo necesitan.
Cuenta desactivada Permite bloquear la cuenta fácilmente sin borrarla. Se suele
utilizar cuando el usuario no va a iniciar sesión durante un periodo de tiempo
o cuando se va a cambiar la configuración o entorno del usuario y se necesita
que no pueda acceder temporalmente al sistema.
Al final del cuadro de diálogo aparecen varios botones (ver figura A.3).
r
GVA-ELAI-UPMPFC0075-2003
271
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
Figura A.4: Administrador de Usuarios; usuario nuevo; grupos
Grupos Permite establecer los grupos a los que pertenece un usuario (ver figura
A.4). En NT hay dos tipos de grupos:
Grupos globales Válidos para dominios en los que se confı́an. Aparecen marcados con el icono de grupo global.
Grupos locales Son grupos locales al servidor o estación de trabajo.
Perfil Permite controlar las caracterı́sticas del entorno de un usuario (figura A.5).
Se puede establecer:
Perfil Nombre del fichero que representa el perfil del usuario para NT. Hay que
escribir un fichero en formato UNC (Univer name convention), es decir:
\\servidor\recurso\directorio\fichero.bat.
Figura A.5: Administrador de Usuarios; usuario nuevo; perfil
272
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.3. EL ADMINISTRADOR DE USUARIOS
Archivo de inicio Asigna un archivo que se ejecutará al iniciar la sesión de red
en el dominio. El archivo debe residir en el servidor que valida el inicio de
sesión. Este fichero se debe hallar en la carpeta NETLOGON del servidor
que valida el inicio de sesión.
Directorio de trabajo Admite dos modalidades de uso.
Ruta de acceso local Utilizar una ruta local al ordenador en que se inicia la sesión.
Conectar una letra de unidad a una unidad de red del tipo \\servidor\recurso.
A El directorio de trabajo es el que aparece por defecto en los cuadros de
diálogo de guardar un fichero en una aplicación Windows.
Horas En el botón Horas podemos acceder al cuadro de diálogo de Horas de inicio
de sesión (ver figura A.6). En este cuadro de diálogo se pueden fijar las horas
de inicio de sesión en los servidores del dominio, en intervalos de 1 hora, para
cada dı́a de la semana. En principio una vez iniciada la sesión el usuario puede
seguir trabajando en los servidores, aunque se puede modificar ésto, para que
los servidores cierren la sesión del usuario al terminar las horas permitidas,
mediante el cuadro de diálogo Plan de cuentas en el menú de Directivas del
Administrador de Usuarios.
Figura A.6: Administrador de Usuarios; usuario nuevo; horas
Iniciar desde Este cuadro de diálogo permite seleccionar los ordenadores desde los
cuales un usuario puede iniciar sesión. Se pueden especificar hasta 8 ordenadores
que ejecuten NT, o permitir el inicio en todos los ordenadores del dominio. Ver
figura A.7.
r
GVA-ELAI-UPMPFC0075-2003
273
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
Figura A.7: Administrador de Usuarios; usuario nuevo; iniciar de sesión
Cuenta El cuadro de diálogo Información de cuenta permite especificar el tipo de
cuenta y su duración. Se puede elegir que la cuenta caduque en una fecha determinada o que no tenga caducidad. También se puede especificar si es una
cuenta global o local. Ver figura A.8.
Figura A.8: Administrador de Usuarios; usuario nuevo; cuenta
Marcado El cuadro de diálogo de Marcado permite especificar las propiedades de
marcado para el usuario. Figura A.9.
Modificar un usuario
Utilizando el menú Usuario\Propiedades o haciendo doble clic sobre un usuario
o grupo se puede modificar el mismo.
Al modificar un usuario se acceden a los mismos cuadros de diálogo empleados
al crearlo salvo que ahora aparece una casilla para cuentas bloqueadas. Si el bloqueo
274
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.3. EL ADMINISTRADOR DE USUARIOS
Figura A.9: Administrador de Usuarios; usuario nuevo; marcado
de cuentas está activado en el dominio y el usuario ha fallado el número de veces
limitado para ese dominio, esta casilla aparece activada. Al desactivarla, la cuenta
del usuario es desbloqueada.
Nota importante: existe una ligera demora al cambiar las propiedades de un
usuario o grupo del dominio, debido a que la base de datos de usuarios del dominio
tarda unos minutos en actualizarse en los controladores secundarios. Se puede forzar
la actualización inmediata mediante la sincronización manual de los servidores.
A.3.2.
Creación de grupos
Para un NT Workstation (o Server configurado como servidor) el administrador
de usuarios permite crear grupos locales, que sólo tienen validez en el propio ordenador. El administrador de usuarios para dominios permite crear dos tipos de grupos:
globales y locales.
Los grupos locales pueden obtener permisos en los servidores del dominio propio.
Pueden ser miembros de los grupos locales los miembros del dominio, los grupos
globales del dominio y los grupos globales de otros dominios en los que se confı́a.
Los grupos globales tienen como miembros a los usuarios del dominio y se pueden
utilizar tanto en los servidores del dominio como en las estaciones de trabajo del
dominio. También se pueden usar en otros dominios en los que se confı́a.
r
GVA-ELAI-UPMPFC0075-2003
275
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
Creación de un grupo global nuevo
Para añadir un grupo global nuevo se selecciona el menú Usuario\Grupo Global nuevo y se proporcionan en el cuadro de diálogo el nombre del grupo y una
descripción opcional. Podemos además añadir usuarios al grupo.
Creación de un grupo local nuevo
Para añadir un grupo local nuevo se selecciona el menú Usuario\Grupo Local nuevo y se proporcionan en el cuadro de diálogo el nombre del grupo y una
descripción opcional. Podemos además añadir usuarios al grupo.
Usos de grupos locales y globales
Cuando se crea un dominio el programa de instalación de NT crea una serie de
grupos globales y locales del dominio. También se crea la cuenta del administrador
del dominio, y se añade al grupo administradores del dominio.
El grupo administradores que se ha creado permite administrar todos los servidores del dominio. NT añade al grupo local administradores el grupo administradores
del dominio. De igual manera ocurre con el grupo de usuarios e invitados. Cuando una
estación de trabajo es añadida al dominio, NT añade automáticamente los tres grupos
globales del dominio (administradores, usuario e invitados del dominio) a los grupos
locales correspondientes de la estación de trabajo. Los grupos locales se utilizan para
asignar tareas especiales en las estaciones de trabajo o servidores del dominio. Por
ejemplo se pueden crear los grupos especiales para trabajar con el recurso como una
impresora laser en color, cuyo acceso queremos restringir. Uno lo podemos llamar
“Administradores de láser color” y otro “Usuarios de láser color”. Ahora basta dar
permisos de impresión al grupo “Usuarios de láser color” y control total al grupo
“Administradores de láser color”. Para añadir usuarios a estos grupos bastarı́a añadir
al grupo “Administradores de láser color” el grupo “Administradores del dominio” y
al grupo “Usuarios de láser color” los miembros del dominio autorizados a imprimir
en ella. Este último paso lo podemos hacer de un medio más eficiente si creamos un
grupo global “Usuarios de impresora láser color” y añadimos este grupo al grupo local “Usuarios de láser color”. Para dar permisos de impresión a los usuarios y grupos
utilizaremos el Administrador de Impresión de dicha impresora, accesible desde el
menú de inicio Configuración\Impresoras
Cada usuario en NT debe pertenecer a uno o varios grupos globales o locales,
indistintamente. Los grupos locales se definen en cada estación de trabajo NT o en
cada servidor.
276
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.4.
A.4. PERMISOS Y SEGURIDAD
Permisos y seguridad
En NT se pueden fijar una serie de directivas comunes para todo el dominio. Entre
estas se puede fijar el plan de cuentas para el dominio, que fija propiedades de las
cuentas tales como la polı́tica de contraseñas, el plan de derechos de usuarios, que
permite asignar determinados permisos genéricos usuarios o grupos del dominio, o el
plan de auditoria, que permite activar los elementos del sistema de auditoria en el
dominio.
A.4.1.
Administración del plan de cuentas
Desde el menú Directivas\Cuentas podemos acceder al cuadro de diálogo “Plan
de cuentas”.
En este cuadro podemos fijar las limitaciones de las contraseñas y el sistema de
bloque de cuentas. Cuando se ha seleccionado caducidad para la contraseña de un
usuario, la contraseña utilizará las opciones elegidas en este cuadro de diálogo. Se
puede elegir:
Duración máxima de la contraseña, en dı́as.
Duración mı́nima de la contraseña, para que el usuario cambie dos veces su
contraseña y vuelva a usar la contraseña antigua.
Longitud mı́nima de la contraseña. Las contraseñas con más de 6 caracteres son
difı́ciles de saltar por métodos de asalto masivo (crackers), también llamados de
“fuerza bruta”. Esto es útil en redes conectadas a Internet.
Historia de la contraseña, que obliga al usuario a no repetir las últimas contraseñas.
Bloqueo de Cuentas El sistema de bloqueo de cuentas permite a los controladores
de dominio reaccionar frente a los intentos fallidos de iniciar sesión en el dominio.
Si se activa el bloque de cuentas entonces al alcanzarse el numero de intentos
especificado la cuenta es bloqueada. Si el número de intentos fallidos no alcanza
al especificado, el usuario puede esperar el tiempo fijado en “restablecer cuenta”
para poder volver a intentarlo. Fijando por ejemplo estos parámetros a 4 intentos
y 10 minutos suele bastar para disuadir de accesos no autorizados. Una vez
bloqueada la cuenta se puede elegir entre desbloqueo automático o manual, con
intervención del administrador del dominio.
r
GVA-ELAI-UPMPFC0075-2003
277
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
También en este cuadro de diálogo se puede seleccionar si los usuarios remotos
serán desconectados de los servidores al acabar su tiempo de conexión y si un usuario
debe iniciar sesión en una estación de trabajo para poder cambiar su contraseña.
A.4.2.
Administración del plan de derechos de usuarios
Los derechos de usuarios son una serie de permisos que no se aplican sobre un
objeto concreto, como un fichero, impresora o directorio, sino que se aplican al sistema
completo. Estos permisos tienen prioridad sobre los permisos asignados sobre los
objetos del sistema. Se pueden asignar a cada tipo de derecho de usuario los usuarios
o grupos de usuarios a los que se necesite otorgar ese derecho.
Los derechos de usuarios pueden ser modificados desde el cuadro de diálogo “Plan
de derechos de usuarios” accesible desde el menú Directivas\Derechos de usuarios. Ver figura A.10.
Figura A.10: Administrador de Usuario; directivas; plan de derechos de usuarios
Si se activa la casilla “Mostrar derechos de usuario avanzados” se pueden ver
algunos derechos de usuarios más especı́ficos. Normalmente los derechos de usuario
asignados por NT asignan derechos suficientes a los grupos de usuarios creados por
NT. Cuando se instalan algunos servicios, como servidores de correo, de Web y similares suele ser necesario cambiar algunos de estos derechos. Los más frecuentes suelen
ser:
Iniciar sesión como servicio. Permite asignar un usuario a un servicio. Suele
ser usuario en servidores de ficheros tipo FTP, Gopher y Web, ya que permite
asignar permisos a los ficheros para ese usuario, limitando el acceso a otros
ficheros del sistema. También lo usa el servicio de duplicación de directorios.
278
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.5. PERMISOS Y SEGURIDAD EN NT
Iniciar sesión como proceso por lotes. Este derecho está pensado para los servicios que atienden las peticiones de usuarios en forma de transacciones, como
por ejemplo servidores POP3 y otros. Actualmente no está implementado en
el sistema operativo, pero algunos servicios verifican que el usuario posea este
derecho antes de atender su petición.
A.5.
Permisos y seguridad en NT
El sistema de seguridad de NT se beneficia de la estructura orientada al objeto de
NT. En NT todos los elementos del sistema, como pueden ser archivos, directorios,
unidades de disco, impresoras,... se consideran “objetos”. Un objeto es un elemento
del sistema operativo dotado de una serie de propiedades comunes a todos los objetos
de su mismo tipo. En NT cada objeto del sistema tiene incorporada su seguridad de
manera que el sistema puede determinar para cada objeto los permisos y modo de
acceso permitidos a cada usuario.
En NT no existe una herramienta que centralice el sistema de seguridad, sino
que para cada tipo de objeto la herramienta que permite modificar sus propiedades
también modifica su seguridad. Las principales herramientas administrativas que fijan
la seguridad de los objetos son el administrador de usuarios, el administrador de
impresión y el administrador de servidores.
A.5.1.
Los perfiles de usuario en NT
Los perfiles de usuario de NT permiten especificar las opciones del entorno para
cada usuario de Windows NT. En Windows 3.x estas opciones habitualmente se guardaban en archivos .ini que eran archivos de texto normalmente compartidos por todos
los usuarios de la aplicación. En NT todas las opciones y configuraciones del sistema
y de las aplicaciones se guardan en el registro.
El registro es una base de datos jerarquizada donde se guarda toda la información
de configuración. En NT existe un registro completo para el sistema y uno para cada
uno de los usuarios que han iniciado sesión en el sistema, que son los llamados perfiles
de usuario.
Cuando un usuario inicia una sesión por primera vez en NT, el sistema crea un
registro personalizado para el usuario. Si no se ha definido previamente un perfil para
el usuario, el sistema utilizará una copia del perfil de usuario por defecto. Tanto los
perfiles de usuario como el perfil de usuario por defecto se puede editar para establecer
de antemano las opciones del entorno de usuario.
r
GVA-ELAI-UPMPFC0075-2003
279
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
A.5.2.
Perfiles de usuario frente a perfiles obligatorios
Cuando un usuario inicia sesión en un NT el sistema busca su perfil. Este perfil
existirá si el usuario ya ha iniciado anteriormente sesión en NT. En caso de que no
tenga perfil utiliza una copia del perfil de usuario por defecto. Las modificaciones que
realice el usuario en su entorno se guardarán en esta copia del perfil.
Se puede modificar este mecanismo para asignar un perfil concreto al usuario. Esto
se hace con el administrador de usuarios, que permite asignar un fichero de perfil,
creado con el editor de perfiles, al usuario. Se pueden elegir dos tipos de perfiles:
perfil de usuario. El sistema crea un perfil para el usuario basándose en este
fichero. Este proceso sólo se realiza la primera vez que el usuario inicio sesión
en la máquina.
perfil obligatorio. El sistema crea un perfil para el usuario basándose en este
fichero cada vez que el usuario inicia sesión en el sistema, de manera que el
usuario pierde la configuración. Esto permite que el usuario parta de un entorno
estándar cada vez que inicia sesión.
Se pueden eliminar perfiles antiguos de usuarios del sistema. Para ello, deberemos
abrir el menú Opciones/Eliminar perfil del icono Instalación de Windows
en la carpeta principal del administrador de programas.
A.5.3.
Tipos de perfiles de usuarios
En NT se pueden definir tres tipos de perfiles de usuario:
Local Este perfil es especı́fico del ordenador en el que se ha creado. El usuario sólo
puede acceder al perfil local al iniciar sesión interactiva en el ordenador en el
que reside el perfil.
Móvil Este tipo de perfil puede ser usado por el usuario en cualquier NT del dominio.
Es parecido al perfil móvil de Windows 95, pero es más completo.
Obligatorio Son perfiles móviles que el usuario no puede modificar. Normalmente
son asignados a un usuario o grupos de usuario por el administrador.
En el perfil de NT 4.0 se guardan opciones como:
280
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.5. PERMISOS Y SEGURIDAD EN NT
Todas las opciones definidas por el usuario en el explorador de NT
Las opciones de la barra de tareas.
Las opciones de impresión de red.
Las conexiones de red persistentes.
Algunas configuraciones de los accesorios y el sistema de ayuda.
Las opciones de las aplicaciones Win32
A.5.4.
El directorio de perfiles en NT
El directorio \Winnt\Profiles almacena los perfiles locales para cada usuario, en
directorios separados cuyo nombre se crea a partir del nombre del usuario. Este directorio contiene además un perfil por defecto, en Default User, que se aplica a todo
usuario que inicia sesión interactiva por primera vez y no dispone de perfil, y un directorio llamado All Users que es accesible dentro del elemento programas del menú de
inicio de todos los usuarios que inician sesión en el sistema. Esta carpeta guarda las
carpetas de programas comunes a todos los usuarios.
En el directorio del perfil se almacena:
Un fichero con las claves del registro correspondientes al usuario. Este fichero
se llama: Ntuser.dat
Un fichero log, que mantiene los cambios efectuados en el registro. Se llama
:NTuser.dat.log. Cuando el usuario cierra sesión, el fichero NTuser.dat se actualiza con los cambios introducidos en NTuser.dat.log. En el caso de que existan
problemas al actualizar el fichero NTuser.dat, los cambios se actualizarán en el
siguiente inicio de sesión.
Directorios de datos, enlaces directos y aplicaciones, como son el Escritorio,
carpeta Personal, carpeta Favoritos, carpeta Enviar a y otras carpetas ocultas.
Los perfiles móviles de NT 4.0 permiten mantener de forma centralizada y sincronizada las preferencias y opciones del entorno de un usuario. Cuando un usuario
inicia sesión en NT el sistema comprueba si el usuario dispone de un perfil móvil:
Esto lo averigua buscando en la información del usuario. Si el campo “Directorio del
perfil” tiene asignado un directorio, NT sabe que el usuario tiene un perfil móvil.
Una vez que NT ha identificado un perfil como móvil, copia el perfil completo desde el servidor hasta el directorio \Windir\profiles local. El usuario puede modificar
y usar su entorno. Al cerrar la sesión, el perfil central se actualiza con los cambios
introducidos por el usuario.
r
GVA-ELAI-UPMPFC0075-2003
281
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
A.5.5.
Creación de un perfil en NT 4.0
El método de creación de perfiles se realiza mediante el icono de sistema del panel
de control y por el editor de directivas del sistema POLEDIT.EXE.
Los pasos a seguir son sencillos:
Si vamos a mantener un gran grupo de perfiles conviene crear un recurso compartido de tipo unidad de red en un servidor adecuado. No es necesario que sea
el controlador de dominio. Por ejemplo:
\\servidor\perfiles
Configuramos la seguridad del recurso para que los usuarios tengan acceso a su
perfil.
Iniciamos sesión con una cuenta con privilegios de administrador.
Modificamos el entorno (opciones, accesos directos, etc).
Ahora se abre el icono Sistema del Panel de Control, en la pestaña Perfiles de
usuario. · Se selecciona el perfil del usuario actual y se pulsa “Copiar a ”. Ver
figura A.11.
Figura A.11: Panel de Control; Sistema; Perfiles de Usuario; Copiar a
El botón “permitir usar a” indica a los usuarios o grupos de usuarios que
se les permite usar el perfil. Este botón se usa con perfiles asignados a grupos
del tipo obligatorio, ya que si un usuario no pertenece a un grupo que tenga
permiso para usar el perfil, no podrá cargarlo.
282
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros HerranzA.6. EL EDITOR DE DIRECTIVAS POLEDIT.EXE
Se copia el perfil al servidor, indicando la ruta al directorio que contiene el perfil.
Por ejemplo:
\\servidor\Perfiles\NombreUsuario
Se abre el administrador de usuarios y se edita la propiedad Perfil del usuario.
En el directorio del perfil se escribe la ruta al perfil.
Se comprueba ahora en el Panel de Control\Sistema\Perfiles que se trata
de un perfil móvil.
Perfiles Obligatorios
Para asignar un perfil a un usuario de manera que el usuario no pueda actualizar
el perfil con los cambios introducidos se utiliza el perfil obligatorio. Los perfiles obligatorios ayudan al administrador a gestionar los perfiles, ya que aseguran que el usuario
cada vez que inicia la sesión encuentre un entorno coherente. Esto suele ser necesario
cuando los usuarios son inexpertos o por simples motivos de seguridad. Cuando el administrador debe mantener una gran cantidad de cuentas de usuarios, puede asignar
perfiles obligatorios a un grupo. Por ejemplo, puede crear un perfil para los usuarios
del grupo Neumática, de manera que todos ellos tengan el mismo perfil.
Para crear un perfil obligatorio hay que:
Renombrar el fichero NTuser.dat a NTuser.man.
Indicar la extensión man en el directorio del perfil.
\\servidor\Perfiles\NombreUsuario.man
Este último paso impide en NT 4.0 que el usuario pueda iniciar sesión con el perfil
cache si el perfil principal no está disponible (el servidor de perfiles está fuera de
servicio).
A.6.
El editor de directivas POLEDIT.EXE
Las directivas del sistema permiten a los administradores controlar la configuración y la capacidad de modificar el entorno por parte de los usuarios, o lo que es
lo mismo imponer ciertas reestricciones a los mismo. Esto puede ser realizado de una
forma centralizada para todo el dominio sobre:
r
GVA-ELAI-UPMPFC0075-2003
283
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
Ordenadores Se puede modificar la configuración predeterminada de los servidores
y estaciones de trabajo.
Usuarios Se puede eliminar la capacidad de un usuario para acceder a partes delicadas de la configuración del sistema, como es la configuración de red o partes
del escritorio de NT.
Grupos Se pueden asignar configuraciones para grupos de usuarios, lo que simplifica
notablemente la administración del dominio.
A.6.1.
Funcionamiento de las directivas
El modo de trabajo de las directivas del sistema consiste en modificar ciertas claves
del registro, que son las que cierran el paso a las partes del registro más sensibles.
Las herramientas de administración y el panel de control utilizan estas claves para
permitir o denegar el acceso del usuario para la modificación de estas partes. Cuando
se manejan directivas del sistema y perfiles de usuario hay que tener en cuenta que:
Las directivas del sistema complementan a los perfiles, ya que también añaden
claves al registro. El perfil del usuario normalmente almacena información de
configuración que no compromete la seguridad del sistema.
Las directivas del usuario se aplican añadiendo las claves después de haber
cargado el perfil de usuario. Esto permite que independientemente de la configuración almacenada en el perfil del usuario, se puedan aplicar las restricciones
de seguridad necesarios para el usuario. Las directivas del sistema por tanto se
aplican añadiendo o alterando las claves del registro tras la carga del perfil.
A.6.2.
Creación de las directivas del sistema para un dominio
La herramienta que permite modificar las directivas del sistema es el Editor de
Directivas del sistema POLEDIT.EXE (ver figura A.12). Las directivas del sistema se
pueden aplicar sobre el sistema actual, aunque cuando realmente se saca provecho de
las directivas del sistema es cuando se definen directivas para un dominio completo.
Crear y modificar directivas para un dominio completo es sencillo. Para ello se
deben seguir estos pasos:
Se crea una nueva directiva con el menú Archivo\nueva directiva del editor
de directivas.
284
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros HerranzA.6. EL EDITOR DE DIRECTIVAS POLEDIT.EXE
Figura A.12: El editor de directivas del sistema
Se modifica convenientemente la directiva, añadiendo usuarios, grupos y computadoras.
La directiva se guarda en el fichero ntconfig.pol. Este fichero se debe guarda en
el directorio de archivos de inicio de sesión (scripts) de todos los controladores
de dominio.
A.6.3.
Modo de funcionamiento de las directivas
El editor de directivas trabaja modificando las claves del registro. Para ello al crear
una nueva directiva el editor carga desde unas plantillas un conjunto de directivas.
Por defecto, el editor de directivas dispone de tres plantillas:
common.adm Contiene configuración común a NT 4.0 y Windows 95.
winnt.adm Contiene configuración sólo de Windows NT.
windows.adm Contiene configuración sólo de Windows 95. Esta plantilla debe añadirla
manualmente un administrador desde el subdirectorio \Windir\inf.
El árbol de directivas muestra conjuntos de directivas que se pueden activar. Cada
una de las directivas puede tener un estado:
Activado (casilla marcada). El editor de directivas modificará convenientemente las claves del registro para aplicar la directiva.
Desactivado (casilla en blanco). El editor de directivas modificará convenientemente las claves del registro para no aplicar la directiva.
Sin cambios (casilla en gris). Es editor de directivas no realizará ninguna
modificación en el registro.
r
GVA-ELAI-UPMPFC0075-2003
285
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
El ejemplo más sencillo es la directiva que indica el protector de pantallas que
debe usar un usuario. Por defecto el usuario utiliza el protector de pantallas que dicta
su perfil, que puede haber sido fijado por el propio usuario, residir en un perfil móvil,
en un perfil obligatorio o haber sido creado por defecto automáticamente. Al activar
esta directiva se puede modificar el comportamiento, obligando a un usuario a utilizar
otro protector de pantalla (quizás el que tiene el logotipo corporativo y obliga a usar
contraseña). En este caso de no activarse la directiva se utilizarı́a la del perfil. Figura
A.13.
Figura A.13: El Editor de Directivas del Sistema, Equipo
A.6.4.
Directivas para sistemas, usuarios y grupos
Se pueden crear tres tipos de directivas:
Directivas para sistemas Permiten gestionar fácilmente varios ordenadores, ya que
la información almacenada en las directivas del dominio son asumidas por todos
los sistemas cuando se incorporan al dominio al arrancar.
Usuarios Es el modo más sencillo de gestionar la seguridad de un usuario.
Grupos Cuando el número de usuarios es grande se puede dividir la configuración
en grupos.
286
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.7. EL PROTOCOLO TCP/IP
Hay que tener en cuanta que las directivas se aplican de modo acumulativo. Si un
usuario pertenece a varios grupos para los que se han fijado directivas, el orden de
aplicación se obtiene según se halla fijado en el cuadro de diálogo “directivas de
grupo”
A.7.
El protocolo TCP/IP
A.7.1.
Introducción
El protocolo TCP/IP nació de los trabajos del ARPA (Advanced Research Project
Agency)del Departamento de Defensa de los EEUU, durante las décadas de los 60 y
70. A través de las universidades y centros de investigación se trató de construir una
red que fuese capaz de resistir las caı́das parciales de la misma (por ejemplo en caso
de guerra). Ası́ surgió ARPANET, la primera red de intercambio de paquetes.
En 1974 V. Cerf y R. Kahn propusieron un nuevo conjunto de protocolos básicos
de red que solventaban gran parte de los problemas de los protocolos usados en
ARPANET. Ası́ se pusieron los cimientos de los protocolos IP (Internet Protocol) y
TCP (Transmission Control Protocol). En 1980 se comenzó la migración de los aproximadamente 100 servidores que formaban la red ARPANET a los nuevos protocolos.
En 1983 el Departamento de Defensa estandarizó el protocolo TCP/IP como protocolo básico de red. Rápidamente otras agencias del gobierno adoptaron el protocolo,
lo que obligó a las empresas proveedoras de equipos a implementarlo en sus sistemas
operativos y equipos de comunicaciones. Además el Departamento de Defensa impulsó el protocolo TCP/IP al recomendar a la Universidad de Berkeley la inclusión
del protocolo en la distribución BSD 4.2 del UNIX.
A.7.2.
El protocolo TCP/IP frente a otros protocolos
El sistema operativo NT da soporte directamente a tres protocolos de red: NETBEUI, usado en las redes de Microsoft e IBM principalmente, IPX/SPX, usado en
las redes Novell Netware y el TCP/IP, parte básica de las redes UNIX, y principal
protocolo de la Internet.
Cada uno de estos protocolos tiene sus propias ventajas e inconvenientes. De un
modo general se recomienda cada uno de estos protocolos:
Netbeui Para compartir ficheros e impresoras en redes sencillas. Para este tipo de
r
GVA-ELAI-UPMPFC0075-2003
287
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
redes se muestra muy eficaz, dada su prácticamente nula necesidad de configuración. No es encaminable.
IPX/SPX De aplicación en redes en las que existan servidores Novell Netware. Tiene
un buen rendimiento en ficheros e impresión y poca dificultad de administración.
TCP/IP Es el que peor rendimiento ofrece para uso en ficheros e impresión, pero es
el que presenta mayores herramientas para crear grandes redes de ordenadores.
Es encaminable y es imprescindible en Internet. Microsoft ha implementado
todas las caracterı́sticas de Netbios dentro del protocolo TCP/IP. Es el que
obliga al mayor esfuerzo administrativo.
A.7.3.
Elementos del protocolo TCP/IP
Una red de ordenadores está compuesta de dos partes: la red fı́sica en sı́ y el protocolo que utilizan los ordenadores para comunicarse entre sı́. La red fı́sica está compuesta normalmente de una serie de subredes, a las que se conectan los diferentes
equipos (ordenadores, impresoras...).
Esta red puede tener una topologı́a muy variada. Actualmente existen dos tipos
de topologı́as:
Ethernet, que es del tipo bus, Token Ring, que tiene topologı́a de testigo y utiliza topologı́a de bus con paso de testigo. El protocolo TCP/IP fue desarrollado
inicialmente para Ethernet , pero admite sin problemas las otras dos tecnologı́as.
Actualmente se está imponiendo la tecnologı́a Ethernet en las redes pequeñas, sobre todo sobre cableado de par trenzado (10 Base T), y por su bajo coste y buen
rendimiento.Normalmente una red tı́pica estará compuesta por una serie de ordenadores conectados entre sı́, además de impresoras y otros elementos de la red.
Cada ordenador tendrá al menos una tarjeta de red. Esta red se puede unir a otras
redes o al resto de la Internet a través de puentes, encaminadores y otros tipos de
enlaces.
El protocolo TCP/IP permite identificar cada elemento de la red y proporciona
los mecanismos para el intercambio de información entre estos elementos.
El protocolo TCP/IP está formado por un protocolo genérico de envı́o y recepción
de paquetes, llamado IP por ser el protocolo nativo de Internet (Internet Protocol),
sobre el que se construyen otros protocolos de mayor nivel. El más importante de
ellos, el protocolo TCP (Transmission Control Protocol), da nombre, junto con el IP,
al protocolo TCP/IP. A su vez estos protocolos pueden incluir subprotocolos dentro
de ellos. Esto se verá claramente en el protocolo TCP.
288
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.7. EL PROTOCOLO TCP/IP
Cada paquete enviado a través de la red tiene un formato especı́fico. Si usamos
el protocolo Ethernet de transmisión, cada paquete está compuesto de una cabecera
Ethernet y de un campo de datos. La cabecera Ethernet origen y la de destino. Las
direcciones Ethernet están compuestos por un número de 6 bytes. Este número es
asignado a cada tarjeta de manera única. Cuando dos ordenadores de la red deben
intercambiar paquetes Ethernet, deben escribir la dirección origen y destino en ellos.
Como en una red Ethernet los paquetes viajan por toda la red, las tarjetas de red sólo
atienden a aquellos paquetes cuya dirección destino coincide con su dirección Ethernet. Existe un método para que una tarjeta envı́e paquetes a todos los ordenadores.
Este mecanismo es conocido como difusión de paquetes (Broadcast). Cuando la dirección destino son 6 bytes a 0 [cerciorarse si son a 0 o a 255], todas las tarjetas procesan
el paquete. Este mecanismo es usado habitualmente por los protocolos de red para
comunicarse dentro de una red local, pero tiene el inconveniente de que sobrecarga la
re, por lo que debe ser evitado en la medida de lo posible.
Los protocolos token ring y token bus se comportan de modo análogo. El campo
de datos contiene el paquete IP. Cada paquete IP está compuesto de una cabecera y
un campo de datos.
En el origen del protocolo TCP/IP, el TCP era el protocolo usado, pero luego se
extendió el protocolo IP con nuevos protocolos como son el Protocolo de Control de
Mensajes de Internet (ICMP), los protocolos de resolución de direcciones directo e
inverso (ARP y RARP) y el protocolo de Datagramas de Usuario (UDP).
A.7.4.
El sistema de direcciones del protocolo IP
A cada servidor de la red TCP/IP se le asigna al menos una dirección IP, que
es un número de 4 octetos. En la red Internet no hay dos ordenadores con el mismo
número IP. En caso de necesidad se pueden asignar más números IP a ese ordenador.
Además cada dirección IP tiene un nombre asociado. Ese nombre está formado por el
nombre del servidor, que es único dentro de una subred, y por el nombre del dominio,
que identifica a la subred dentro del conjunto de las subredes de Internet. La forma
de asignar IP, nombres y nombres de dominio en Internet sigue una serie de criterios
que permiten el encaminamiento de los paquetes IP por la red y la traducción de
nombres de ordenadores en números IP.
En Internet hay tres tipos de organizaciones de IP:
Organizaciones tipo A El primer octeto del IP es el mismo para toda la organización. La organización asigna del IP es el mismo para toda la organización.
La organización asigna al resto de los octetos a cada IP de su organización. La
organización dispone de direcciones para asignar. Este tipo de organizaciones
r
GVA-ELAI-UPMPFC0075-2003
289
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
sólo se asignan a paı́ses.
Organización tipo B Los dos primeros octetos del IP están fijos. La organización
dispone de 65536 direcciones IP para asignar. Suelen ser organizaciones de
tamaño medio (universidades, grandes empresas).
Organización tipo C Se fijan los tres primeros octetos, dejando 256 posibles direcciones.Se utilizan en pequeños proveedores de servicios Internet (ISP).
Resolución de nombres en el protocolo IP
Cuando dos ordenadores se quieren comunicar mediante el protocolo IP, deben
conocer ambos sus respectivas direcciones IP. Por ejemplo, si se desea conectar desde
un ordenador a otro mediante un cliente del protocolo de transferencia de ficheros
(FTP), debemos suministrar al cliente la dirección IP de destino. Dado que los
números IP son difı́ciles de recordar, en Internet se dispone de un mecanismo que
permite asociar nombres significativos a cada IP. Por ejemplo, el servidor de FTP de
una organización podrı́a llamarse ftp.organizacion, donde “organización” es el nombre
del dominio de dicha organización. Se puede emplear el archivo HOSTS de cada servidor para incluir en él una lista de direcciones IP con su nombre correspondiente. De
esta manera se puede proporcionar al cliente FTP el nombre ftp.organizacion como
IP de destino, y el protocolo IP se encarga de obtener el número IP. A este mecanismo
se le llama resolución de nombres.
Dado que mantener una lista de direcciones IP y nombres es complicado (habrı́a
que duplicar los archivos HOSTS por todos los servidores), en Internet se ha creado un
mecanismo de resolución de nombres automático: el Servicio de Nombres de Dominio
(DNS). En cada dominio hay al menos un servidor de nombres de dominio, que
mantiene una lista de todas las direcciones IP del dominio y sus nombres asociados.
Incluso podemos incluir varios nombres para una misma direccion IP (por ejemplo
en los servidores de FTP y WWW de la organización residen en el mismo servidor,
podemos incluir los nombres ftp.organizacion y www.organizacion en el servidor de
nombres. Además en Internet, los servidores de nombres están organizados de una
forma jerárquica, de manera que si el nombre buscado no pertenece al dominio del
ordenador, el servidor DNS puede buscar en otros servidores DNS de otros dominios
hasta encontrar el servidor DNS del dominio destino, y de él recuperar la dirección IP
de destino. Este mecanismo es generalmente muy rápido (menor que unos 2 segundos
la búsqueda con éxito y unos 10 o 20 una búsqueda con resultado negativo), ya que
los servidores DNS poseen mecanismos de caché.
290
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.7.5.
A.7. EL PROTOCOLO TCP/IP
El mecanismo de difusión (broadcast) en el protocolo
IP
El protocolo IP al igual que el protocolo Ethernet también dispone de un mecanismo de difusión (broadcast), que permite enviar paquetes desde un ordenador a todos
los ordenadores de la red. Cada tipo de subred (A,B o C)tiene una máscara de subred
asociada (255.0.0.0 para la A, 255.255.0.0 para la B y 255.255.255.0 para la C) que
determina las direcciones IP que escuharan los paquetes de difusión. El protocolo de
difusión es ampliamente usado por Netbios sobre TCP/IP en la implementación de
Microsoft, lo que permite emular al protocolo TCP/Ipde Windows el comportamiento
del protocolo Netbeui.
El protocolo de difusión de paquetes tiene dos grandes desventajas: la primera
es que sobrecarga la red. Por ello en las redes basadas en Windows se introduce el
protocolo WINS, que intenta evitar en la medida de lo posible el envı́o de paquetes de
difusión. La segunda desventaja es que los puentes y encaminadores que comunican
las subredes, si entienden el protocolo IP, no permiten el paso de paquetes de difusión.
A.7.6.
Implementación del protocolo TCP/IP en NT
La implementación del protocolo TCP/IP en NT persigue dos metas: implementar completamente el protocolo TCP/IP en NT, tanto a nivel de protocolos
(IP,TCP;UDP,etc) como la inclusión de los servicios más habituales (FTP, TELNET
(Cliente sólo), SNMP y otros). Por otro lado permite utilizar el protocolo TCP/IP como único protocolo de la red, ya que los servicios de Netbios sobre TCP/IP permiten
la compartición de ficheros e impresoras en la red Windows.
La mayor parte de los clientes TCP/IP tienen versión para NT. Se está haciendo
un gran esfuerzo a su vez para dotar a NT de todos los servidores tı́picos de Internet.
Hay servidores de dominio público de FTP, DNS, Gopher, TELNET, SMTP, POP3
Y WEB, aparte de las propias incluidas en el NT Server. además existen versiones
comerciales de dichos servidores, normalmente más potentes y seguras.
A.7.7.
Configuración del protocolo TCP/IP en NT
Antes de proceder a la instalación del protocolo TCP/IP en NT hay que averiguar
una serie de parámetros, que deben ser suministrados por el administrador de la red.
Si en la red además existe un servidor DHCP probablemente no sea necesario conocer
ningún parámetro, ya que el protocolo se configurará automáticamente. Para añadir el
protocolo TCP/IP se pulsa el botón “Agregar software” dentro del cuadro de diálogo
r
GVA-ELAI-UPMPFC0075-2003
291
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
“Red” del Panel de Control (ver figura A.14).
Figura A.14: Panel de control. Red
En NT 3.51 debemos elegir la opción “Protocolo TCP/IP y elementos relacionados. En estecuadro de diálogo nos aparecen las opciones que se pueden instalar. En
Nt 4.0 se elige en Panel decontrol\Red\Protocolos\Agregar el Protocolo TCP/IP y
elementos relacionados. Figura A.15.
En este cuadro se pueden señalar las opciones a instalar. Las más comunes son
las utilidades de conectividad (clientes ftp, telnet, finger, etc.), y son básicamente las
únicas necesarias. En este cuadro de diálogo también se puede seleccionar la configuración automática vı́a el protocolo DHCP. En NT 4.0 el cuadro de diálogo se ha
modificado de manera que ahora la configuración del protocolo TCP/IP está organizada por bloques funcionales. En el caso de configuración manual debemos conocer
una serie de parámetros. El primero es la dirección IP del ordenador. En NT se puede
asignar una dirección IP a cada adaptador de red instalado, e incluso a un mismo
adaptador se le pueden asignar varias direcciones IP. Esto último se usa en Internet
para crear servidores “virtuales”. Luego se debe incluir una de las tres máscaras de
subred posibles, para redes de tipo A, B o C. Si la red en la que se halla conectado
el ordenador está conectada con otras redes vı́a una pasarela (gateway), que puede
292
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.7. EL PROTOCOLO TCP/IP
Figura A.15: Panel de control. Red. Protocolos. Agregar protocolo TCP/IP
ser un puente o encaminador, hay que incluir su dirección en la casilla para puerta
de enlace.
Si en la red hay servidores WINS, podemos incluir la dirección de un servidor
WINS primario y otro secundario.
Si en la red hay un servidor DNS (obligatorio en las redes conectadas a Internet)
podemos completar las opciones de DNS.
Como nombre de host, NT por defecto usa el de Windows, pero deberı́a coincidir
con el que se le ha asignado en el servidor de nombres. En la lista “Orden de búsqueda
del servicio de nombres de dominio” debemos proporcionar una lista con las direcciones IP de los servidores de nombres que debe usar. Se pueden incluir servidores
de nuestra red y de otras, aunque suelen ser más lentos. Debemos añadir a la casilla
“nombre de dominio” el nombre de dominio de la subred local. Si no se proporciona
un dominio, el protocolo TCP/IP usa por defecto el dominio local.
Podemos añadir otros dominios para que se usen por defecto, añadiendo entradas
a la lista “orden de búsqueda del sufijo de dominio”.
Se pueden configurar varias opciones avanzadas para cada adaptador de red o pulsando el botón avanzadas del cuadro de diálogo “Configuración de TCP/IP”,
en la sección Dirección IP (ver figura A.16).
También se puede activar el protocolo PPTP (Point to Point Tunneling Protocol)
r
GVA-ELAI-UPMPFC0075-2003
293
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
Figura A.16: Protocolo TCP/IP, Dirección IP, Avanzado
que es el Protocolo de Túnel Punto a Punto. Este protocolo permite construir redes
privadas seguras dentro de redes de transmisión públicas, siendo capaz de encapsular
los diferentes protocolos de red empleados en NT, como son NETBEUI, TCP/IP y
IPX/SPX. Este protocolo utiliza cifrado de los paquetes, y algoritmos de clave pública
que hacen muy difı́cil examinar los paquetes enviados a través de una red como puede
ser Internet. En este cuadro se pueden:
Asignar múltiples direcciones IP a un mismo adaptador. Esto se usa cuando
un mismo adaptador de red debe poseer varias direcciones IP. En Internet es
muy común el asignar múltiples direcciones IP a un adaptador. El mejor uso
de este mecanismo consiste en reservar una dirección IP y un nombre de ordenador para cada servicio Internet que se instale en el servidor. Si por ejemplo
se planea instalar un servidor FTP y un servidor WWW sobre el servidor, se
deben reservar dos direcciones separadas de la principal del servido, e instalar
cada uno de los servicios en cada dirección. De esta manera es muy fácil llevarse
294
r
GVA-ELAI-UPMPFC0075-2003
Fernando Ballesteros Herranz
A.7. EL PROTOCOLO TCP/IP
todo es servicio a un nuevo servidor cuando por sobrecarga del servidor no se
puede hacer frente a las solicitudes efectuadas por los clientes de este servicio.
Añadir nuevas pasarelas o puertas de enlace para ese adaptador. Ver figura
A.17.
Figura A.17: Protocolo TCP/IP, Dirección IP, Avanzadas
Activar el agente de Proxy WINS, para lo cual la red debe disponer de servidor
WINS. Un agente de proxy WINS es un equipo que permite que otros equipos
que no están configurados para acceder a un servidor WINS puedan acceder a
los nombres contenidos en ese servidor WINS. Normalmente esta situación se da
cuando el servidor WINS está en una red remota, por lo que los equipos de la red
local que no tienen activado el cliente WINS no pueden acceder a los nombres
registrados en ese servidor. Al activar el proxy WINS las peticiones de búsqueda
y registro de nombres Windows realizadas en modo local (vı́a broadcast) son
atendidas y redirigidas sobre el servidor WINS por el servidor proxy WINS.
Configurar los parámetros de red de Windows, que funcionan con el protocolo
Netbios sobre TCP/IP. El archivo En NT 4.0 se ha introducido el agente Relé de
DHCP. Normalmente el protocolo DHCP funciona sobre una red local, ya que
se trabaja siempre en modo de difusión de paquetes (broadcast). En este modo
los paquetes no pueden saltar los encaminadores, salvo que éstos soporten el
protocolo de reenvı́o de paquetes BOOTP. Si es necesario que en una red se
tenga acceso a un servidor DHCP remoto, se puede instalar un relé DHCP,
que es un servicio que se conecta con un servidor DHCP remoto para realizar la
configuración dinámica en la red local. Se pueden añadir en el cuadro de diálogo
de Relé DHCP varios servidores DHCP, ası́ como configurar los parámetros de
funcionamiento del relé.
r
GVA-ELAI-UPMPFC0075-2003
295
APÉNDICE A. ADMINISTRACIÓN DE SISTEMAS Fernando Ballesteros Herranz
En el cuadro de diálogo de Enrutamiento (encaminamiento) se puede activar
el encaminamiento IP, si se disponen de 2 o más direcciones IP en el ordenador. Esta
situación es habitual cuando se disponen de dos tarjetas de red, cada una conectada
a una red fı́sica diferente. Ver figura A.18.
Figura A.18: Protocolo TCP/IP, Enrutamiento
296
r
GVA-ELAI-UPMPFC0075-2003
Bibliografı́a
[ANDRE] Andrews, Mark. Aprenda Visual C++ Ya. McGraw-Hill, 1999.
[BARBA] Barba Mir, C. A propósito del estándar DICOM 3.0. Hospital Clı́nico
Universitario Lozano Blesa (Zaragoza).
http://www.hcu-lblesa.es/mane/noticia/didcom3.htm
[BATE] Bates, Jon. & Tompkins, Tim. Microsoft Visual C++ 6. 2000, Prentice
Hall.
[BOBA00] Bobadilla, Jesús. & Sancho ,Adela. Comunicaciones y Bases de
datos con Java a través de ejemplos. 2003, Ra-Ma
[BOBA01] Bobadilla, Jesús. Java a través de ejemplos. 2003, Ra-Ma
[CASCA] Cascales, B. & Lucas, P. & Mira, JM. & Pallarés, A. &
Sanchez-Pedreño, S. LATEXuna imprenta en sus manos. 2000, ADI
[CEBAL99] Ceballos, F. Javier. Visual C++. Aplicaciones para Win32. RAMA, 1999. ISBN: 84-7897-350-8
[CEBAL00] Ceballos, F. Javier. Visual C++. Programación avanzada en Win32.
RA-MA, 1999. ISBN: 84-7897-344-3
[DICOM] DICOM Standard . School of Psychology, University of Nottingham, University Park, Nottingham, NG7 2RD, UK,2003.
http://www.psychology.nottingham.ac.uk/staff/cr1/dicom.html
[ENCRI] Encriptación en Java.
http://www3.uji.es/~vcholvi/teaching/java/cap.12.1/Cap.12.1.html
[GUNT] Gunter, D. & Burnett, S. Guı́a de integración de Windows NT y Unix.
McGraw-Hill, 1998.
[HORI] Hori, S. & Prior, F. & Dean Bidgood, W. & Parisot, C. & Claeys,
G. DICOM: An introduction to the standard.
http://www.dicomanalyser.co.uk/html/introduction.htm
297
BIBLIOGRAFÍA
Fernando Ballesteros Herranz
[JDK] API 1.4.1 .
http://java.sun.com/j2se/1.4.1/docs/api/
[KRUG] Krugglinski, David J. & Shepher, G. & Wingo, S. Programación
avanzada con Microsoft Visual C++. 2002, McGraw-Hill
[KURA] Offis Dicom. Kuratorium OFFIS e.V, 2003.
http://dicom.offis.de/index.php.en
[LEBLA] LeBlanc, Dee-Ann. Administración de sistemas Linux (La Biblia). 2000,
Anaya
[LEMA] Lemay, Laura. & L. Perkins, Charles. Aprendiendo Java 1.1 en 21
dı́as. 1997, Prentice Hall
[NEMA] DICOM . NEMA, Suite 1847, 2003.
http://medical.nema.org/
[PAJ] Pajares, G. & de la Cruz, JM. & Molina, JM. & Cuadrado, J. &
López, A. Imágenes Digitales. Procesamiento práctico con Java. 2003, Ra-Ma
[PASCU00] Pascual, J. & Charte, F. & J. Segarra, M. & De Antonio, A.
& A. Clavijo, J. Programación avanzada en Windows 2000 con Visual C++
y MFC. 2000, McGraw-Hill ISBN: 84-481-2532-0
[REVET97] Revet, B. DICOM Cook Book for implementation in Modalities.
Philips Medical Systems, Versión 1.1., 1997.
ftp://ftp-wjq.philips.com/medical/interoperability/out/DICOM_
Information/CookBook.pdf
ftp://ftp.philips.com/pub/ms/dicom/DICOM_Information/CookBook.pdf
[RUSSE97] Russel, C. & Crawford, S. Guı́a completa de Microsoft Windows
NT 4.0 Server. McGraw-Hill, 1997. ISBN: 1-57231-333-1
[SOFT] SoftLink . SoftLink, 2002.
http://www.softlink.be/
[STIN] Stinson, C. & Siechert, C. Running Microsoft Windows 2000 Profesional.
2000, McGraw-Hill
[TIANI] Tiani Pacs. JDicom: JavaTM DICOM Tools,2003.
http://www.tiani.com/JDicom/
[TJAND99] Tjandra, D. & Wong, S. A Digital Library for Biomedical Imaging
on the Internet. IEEE Communications Magazine, 1999.
http://www.comsoc.org/pubs/free/private/1999/jan/Tjandra.html
298
r
GVA-ELAI-UPMPFC0075-2003
Descargar