Capítulo9

21
Capítulo 9 Descubriendo las Posibilidades Resumen del capítulo El propósito de este capítulo es más ambiciosa que la mayoría. A pesar de que IDL es una lenguaje de programación, es imposible de encontrar en cualquier parte documentación IDL oficial de cómo escribir un programa IDL. No pretendo sugerir que hay una sola manera correcta. Pero cualquiera que haya mirado por encima del hombro de tantos programadores de IDL como se sabe definitivamente hay una diferencia entre un buen programa IDL y uno que no es tan bueno. Como alguien que pasa mucho tiempo con personas que están tratando de aprender IDL, por primera vez, veo un montón de programas not_so_good. Estoy convencido de que el problema es la falta de información. La mayoría de las personas que usan IDL son, después de todo, los científicos, no los informáticos. Ellos son brillantes y están tratando de conseguir su trabajo. Ellos no están tratando de escribir programas de ordenador elegantes. Pero, aun así... Si se siguiera sólo un par de sencillos principios, sus programas serían mucho mejor y mucho más útiles para ellos. Este capítulo es un intento de especificar lo que estos principios podrían ser, mientras que al mismo tiempo se muestra cómo montar y utilizar muchas de las técnicas que se han discutido en este libro. La tarea que me he impuesto es mostrar cómo escribir un programa de razonable complejidad para mostrar gráficas que se puede utilizar desde la línea de comandos de IDL. Pero yo quiero escribir este programa de tal manera que la salida se puede visualizar en una ventana de gráficos redimensionable, imprimirse directamente desde la línea de comandos de IDL, o hecho en un Archivo PostScript con poco o ningún esfuerzo. El programa debe utilizar colores de una inteligente manera que no depende de la profundidad visual o color de estado de descomposición y salida, por último, debe ser simple para añadir una interfaz gráfica de usuario para su programa, de modo que pueda ser utilizado por alguien no familiarizado con ella. La mayoría de los programadores saben que la mejor manera de aprender a programar es mediante la comprensión del código que se ha escrito por otros. Pero la mayoría de las veces esto es una tarea de enormes proporciones, dado la general falta de documentación en el código y la ausencia de un mentor que puede explicar los elementos desconocidos del código para usted. Mi propósito aquí no es sólo para mostrarle cómo escribir un programa, sino para explicar por qué el programa está escrito en esa manera particular. La escritura de programas siempre implica hacer decisiones. Las decisiones que hacemos juegan un papel fundamental en la utilidad de este programa para nosotros, y lo fácil es mantener y ampliar el programa a través del tiempo. En otras palabras, podemos hacer útiles ambas y las opciones non_helpful. Al final del capítulo, usted debe ser bueno en su manera para comprender la distinción. El Programa de Histolmage El programa que quiero escribir se llamará HistoImage. Es muy simple. Será mostrar una imagen con los ejes alrededor. Por encima de la imagen será una barra de colores que se indicar los valores de la imagen. Y por encima de la barra de colores aparecerá un histograma de los valores de los píxeles de la imagen. En otras palabras, el histograma muestra el número de píxeles en la imagen correspondiete a un valor de la imagen en particular. Usted ve una ilustración de cómo el programa

Transcript of Capítulo9

Page 1: Capítulo9

Capítulo 9

Descubriendo las Posibilidades

Resumen del capítulo

El propósito de este capítulo es más ambiciosa que la mayoría. A pesar de que IDL es una lenguaje de programación, es imposible de encontrar en cualquier parte documentación IDL oficial de cómo escribir un programa IDL. No pretendo sugerir que hay una sola manera correcta. Pero cualquiera que haya mirado por encima del hombro de tantos programadores de IDL como se sabe definitivamente hay una diferencia entre un buen programa IDL y uno que no es tan bueno. Como alguien que pasa mucho tiempo con personas que están tratando de aprender IDL, por primera vez, veo un montón de programas not_so_good. Estoy convencido de que el problema es la falta de información. La mayoría de las personas que usan IDL son, después de todo, los científicos, no los informáticos. Ellos son brillantes y están tratando de conseguir su trabajo. Ellos no están tratando de escribir programas de ordenador elegantes. Pero, aun así... Si se siguiera sólo un par de sencillos principios, sus programas serían mucho mejor y mucho más útiles para ellos. Este capítulo es un intento de especificar lo que estos principios podrían ser, mientras que al mismo tiempo se muestra cómo montar y utilizar muchas de las técnicas que se han discutido en este libro. La tarea que me he impuesto es mostrar cómo escribir un programa de razonable complejidad para mostrar gráficas que se puede utilizar desde la línea de comandos de IDL. Pero yo quiero escribir este programa de tal manera que la salida se puede visualizar en una ventana de gráficos redimensionable, imprimirse directamente desde la línea de comandos de IDL, o hecho en un Archivo PostScript con poco o ningún esfuerzo. El programa debe utilizar colores de una inteligente manera que no depende de la profundidad visual o color de estado de descomposición y salida, por último, debe ser simple para añadir una interfaz gráfica de usuario para su programa, de modo que pueda ser utilizado por alguien no familiarizado con ella. La mayoría de los programadores saben que la mejor manera de aprender a programar es mediante la comprensión del código que se ha escrito por otros. Pero la mayoría de las veces esto es una tarea de enormes proporciones, dado la general falta de documentación en el código y la ausencia de un mentor que puede explicar los elementos desconocidos del código para usted. Mi propósito aquí no es sólo para mostrarle cómo escribir un programa, sino para explicar por qué el programa está escrito en esa manera particular. La escritura de programas siempre implica hacer decisiones. Las decisiones que hacemos juegan un papel fundamental en la utilidad de este programa para nosotros, y lo fácil es mantener y ampliar el programa a través del tiempo. En otras palabras, podemos hacer útiles ambas y las opciones non_helpful. Al final del capítulo, usted debe ser bueno en su manera para comprender la distinción.

El Programa de Histolmage El programa que quiero escribir se llamará HistoImage. Es muy simple. Será mostrar una imagen con los ejes alrededor. Por encima de la imagen será una barra de colores que se indicar los valores de la imagen. Y por encima de la barra de colores aparecerá un histograma de los valores de los píxeles de la imagen. En otras palabras, el histograma muestra el número de píxeles en la imagen correspondiete a un valor de la imagen en particular. Usted ve una ilustración de cómo el programa

Page 2: Capítulo9

aparecerá en la Figura 94. La lista completa del código fuente del programa se puede encontrar en la página 409 "Programa HistoImage". Y el archivo histoimage.pro esta entre los archivos de programa que ha descargado para su uso con este libro.

Figura 94: El programa HistoImage consta de histograma, una barra de colores, y una imagen rodeado de ejes. Escribiendo la Declaración de Definición de Procedimiento El programa HistoImage será un procedimiento, para empezar por definir la declaración de definición de procedimiento. Aquí es donde todos los parámetros de posición y las palabras clave son declarados. Una regla de oro para los parámetros es que cualquier parámetro requerido para el programa a ejecutar será un parámetro de posición, y todo lo demás parámetros serán palabras claves. Esto significa, por supuesto, que se tendrá que definir valores por defecto para todos los parámetros mediante palabras clave. También significa que rara vez se tienen en cuenta todos los parámetros claves que se necesitará cuando empiece la codificación del programa. La mayoría de las veces empiezo con algunas obvias y añadiré otras cuando los necesite. Yo trato de dar a los usuarios mis programas con la mayor flexibilidad posible. En particular, me gusta darles tanto controlar lo que pueda sobre cómo las cosas se van a ver, ya que los usuarios casi siempre tienen un sentido de la estética diferente que yo. Así que casi siempre tienen palabras claves que permitirá al usuario elegir colores. Aquí está lo que la declaración de definición de procedimiento se parecerá a:

Page 3: Capítulo9

PRO HistoImage, $ imagen, $ AxisColorName = axisColorName, $ BackColorName = backcolorName, $ Binsize = binsize, $ ColorTable=colortable, $ DataColorName = datacolorName, $ Depurar = debug, $ _Extra=extra, $ ImageColors=imagecolors, $ Max_Value=max_value, $ NoLoadCT=noloadct, $ XScale=xscale, $ YScale=yscale El primer y único parámetro posicional, imagen, son los datos de la imagen que se pasarán en el programa. Voy a tener que comprobar si se trata de un array 2D, ya que no tiene mucho sentido para calcular el histograma de una imagen 24_bit o 3D, pero lo haré retrasar esto por un momento. Verás tres nombres "colores" en la lista de palabras clave: AxisColorName, BackColorName, y DataColorName. Estos serán los nombres de los colores a utilizar para los ejes y otras anotaciones, los antecedentes y los datos, respectivamente. Voy a usar nombres de los colores de estos, porque uno de mis objetivos para el programa es utilizar colores que sean independientes del estado de descomposición del color o la profundidad de la pantalla. Sé que el programa GetColor. Que figura en el apartado en la página 87 "Obtención de dispositivos independientes de Colores" tiene la capacidad de darme un color tal cual si le pregunto por uno de los 16 colores que conocen por sus nombres. Al permitir que el usuario seleccione sus colores propios, les doy un poco de control sobre cómo se ven las cosas en la pantalla. También le permito al usuario especificar el número índice de la tabla de colores con la palabra clave Colortable. Los datos de las imágenes se pueden ampliar en índices cargados por la tabla de colores. Los Colores de las imágenes casi siempre presentan un dilema para mí. Por un lado, tengo muchas ganas de ajustar los colores de la imagen de forma correcta, especialmente si estoy llamando este programa desde la Línea de comandos de IDL. Pero por otro lado, a menudo prefiero que la manipulación del color sea hecho fuera del código del programa. Por ejemplo, en el programa de colores de imagen widget que son a menudo controladas por una herramienta cambiadora de color como XLoadCT o XColors. Carga una tabla de colores dentro de un programa de visualización de gráficos a menudo interfieren con los colores que están siendo manipulados en otros lugares. Me comprometo en este programa mediante la definición de dos parámetros clave adicionales: NoLoadCT y ImageColors. NoLoadCT será un indicador de que si se establece evitará que el programa se cargue la tabla de colores especificada por la palabra clave ColorTable. Es decir, voy a tener una manera de convertir la tabla de colores cargados desde fuera del programa, si esto es lo que yo quiero hacer. ImageColors será una palabra de salida que me permita aprender desde fuera del programa la cantidad de colores deben ampliarse a los datos de la imagen. Esta información es esencial si voy a manejar los colores fuera del programa. (Aquí voy a cargar los colores de la imagen a partir de un vector índice de color 0. Si no fuera el caso, también puede definir una palabra clave, por ejemplo BottomIndex, que indicaría la parte inferior de los índices de color de la imagen.) La palabra clave BinSize es una palabra clave que usa el comando Histogram. Usaré el comando Histogram dentro de este programa para calcular el histograma y es posible que quiera el usuario ser capaz de configurar las propiedades de este comando. Tenga en cuenta que no proporciono todas las palabras clave que están disponibles para Histogram, sólo aquellos usuarios que quieran específicamente usuario manipularlo. Del mismo modo, la palabra clave es una

Page 4: Capítulo9

palabra clave Max_Value es una palabra clave del comando Plot y que a menudo se encuentran utilidad en los histogramas, por lo defino aquí. Es muy posible (sobre todo con el comando Plot) querer manipular las palabras claves Histogran, Plot o TVImage que no se definen aquí. Por ejemplo, puede querer diferentes ejes de anotaciones o marcas. Por esta razón, incluir una palabra clave _Extra, para tomar ventaja de la herencia de palabras claves, que se describe en el "Pasando Palabras Claves No Definidas de la Herencia de Palabras Clave" en la página 216. Hay dos palabras claves, XScaIe y YScale, que se utilizarán para definir el rango y escala de los ejes que rodean la imagen. Estas palabras claves de entrada serán matrices de dos elementos que definen la extensión mínima y máxima de los ejes. Por último, hay una palabra clave Debug, que tengo la intención de utilizar en la parte del controlador de errores del código para forzar un rastreo del lugar donde se produjo el error. Normalmente a mí no me gusta escribir errores en la ventana de registro de comandos a menos que el usuario solicite expresamente lo contrario. Utilizando una palabra clave Debug me da una manera fácil de depurar mi código, sin que los usuarios no familiarizados se aterroricen con aterradoras largas líneas de texto de error. Escribir el código de control de errores El siguiente paso para escribir un programa consiste en agregar un código de control de errores. Como yo no tengo un montón de pensamiento para los tipos de errores que pueden ocurrir en el programa, y como yo sé que los usuarios podrán descubrir los errores que no anticipé, de todos modos, voy a escribir un propósito general para manejar el error de captura. (El controlador de errores Catch se describe en "La declaración de capturas de control" en la página 230.). Puedes utilizar el programa ERROR_MESSAGE, que es uno de los programas que ha descargado para su uso con este libro y se describe en la página 234, porque quiero aprovechar su naturaleza de dispositivo independiente. ERROR_MESSAGE utiliza Dinlog_Message para informar del error si se está ejecutando en una salida del dispositivo compatible con widgets y Messages si el dispositivo no es compatible con widgets. ERROR_MESSAGE también puede proporcionar una buena información del rastreo de errores si es necesario. El código es el siguiente: Catch, theError if theError NE 0 then begin Catch, /Cancel ok = ERROR_MESSAGE(!Error_State.Msg + 'Returning ...', $ traceback = Keyword_Set(debug)) RETURN ENDIF Tenga en cuenta que cancelo el controlador de errores de captura como el primer paso en la parte de control de errores del código. Hago esto porque hago muchos errores de escritura durante el desarrollo y tienen a veces errores en mi código de gestión de errores. Esto hará que IDL haga un bucle infinito. Llame a esto una buena programación defensiva si no puede pensar en una más suave explicación. Tenga en cuenta que estoy añadiendo un poco más de información (la cadena de retorno…) respecto al normal mensaje de error. Sólo quiero que el usuario sepa lo que estoy haciendo con el error. Y fíjense que la palabra clave Traceback está configurado para Error_Message sólo si el usuario establece la palabra clave Debug cuando él o ella llaman

Page 5: Capítulo9

al programa HistoImage. Puesto que la palabra clave Debug o bien puede estar encendido o apagado, puse su valor con Keyword_Set, que sólo devuelve un 0 ó 1. Comprobación de los parámetros de posición y de palabras claves Inmediatamente después de que el código de control de errores, va el código que comprueba todo los parámetros obligatorios y opcionales. La comprobación resulta esencial (por lo menos para los parámetros de entrada) porque usted va a utilizar las variables en algún lugar del código para seguir y no es posible usar variables no definidas en las expresiones IDL. (Métodos para el control de parámetros de posición y la palabra clave se discuten en "Escribiendo procedimientos en IDL" en la página 209.) Comprobación de la imagen de parámetro posicional He mencionado antes que mi regla de oro es que cualquier parametro requerido es un parámetro de posición, y cualquier parámetro opcional es un parámetro clave. Yo no puedo hacer mucho en un programa que calcula el histograma de una imagen y la muestra por encima de la imagen sin imagen. Por lo tanto, image debe ser el parámetro posicional requerido por el argumento. Pero yo nunca he sido una persona que se preocupaba mucho por reglas arbitrarias, y yo voy a elegir romper esto de inmediato por ser un poco más amable con el usuario y que le permite a este parámetro posicional ser un parámetro opcional. ¿Por qué? Porque no creo que los usuarios deben ser penalizados con demasiada dureza si no saben cómo utilizar un programa. Mi trabajo consiste en explicar a ellos. Así que voy a seleccionar y utilizar una imagen para ellos. Si quieren otra imagen, se puede leer la documentación del programa (quien escribió esto, no lo hizo) para ver cómo utilizar su propia imagen. El código se verá así: IF N_Element(image) EQ 0 THEN image=LoadData(7) Tenga en cuenta que he usado N_Elemens para comprobar el parámetro de la imagen, en lugar de N_Params, se podría haber esperado que utilice un parámetro posicional. Hay que recordar que N_Elemens me dice si el parámetro imagen es definida o no, mientras que N_Params me cuenta el número de parámetros posicionales del procedimiento de llamada. (Consulte "Definición de Parámetros opcionales u posicionales obligatorios "en la página 212 para obtener más información.)Algunos usuarios inexpertos están seguros de llamar al rograma HistoImage con un solo parámetro de posición que es una variable no definida. Mediante el uso de N_Elements te informo de esta eventualidad. Si no se proporciona un parámetro de imagen, simplemente cargar los datos de elevación mundiales establecidos con el programa LoadData que ha descargado para su uso con este libro. Ahora que tengo un parámetro de imagen, voy a comprobar para asegurarse de que es un array 2D, ya que es también un requisito para los datos del histograma para que tenga sentido. Puedo usar el comando Size con la palabra clave N_Dimensions configurado para determinar el número de dimensiones de la imagen. (Tenga en cuenta que la palabra clave N_Dirnensions para el comando Size es bastantemente reciente a la Introducción del lenguaje de programación IDL. Si está utilizando una versión de IDL posterior a IDL 5.2, se puede obtener la misma información del comando Size directamente. Ver su ayuda On_Line para más detalles). ndim = size(image,/N_Dimensions) if ndim NE 2 then $

Page 6: Capítulo9

Message,'2D Variable imagen requerida.',/NoName El comando message será un error, que será manejada por mi Catch manejo de errores de código. Tenga en cuenta que la palabra clave NoName se establece para evitar ERROR_MESSAGE que informe el nombre del programa de dos veces. Comprobación de parámetros de palabra claves Ahora estoy listo para comprobar los parámetros de palabras claves opcionales. Reviso las dos palabras clave, BinSize y MAX_VALUE Estoy pensando en usar el histograma de la imagen en primer lugar. Espero la mayor parte de las imágenes utilizadas en este programa será de bytes de datos, pero no se puede confiar en él para ser el caso. Tampoco quiero restringir al usuario los datos de imagen de bytes. Pero yo no quiero que el histograma se muestre en bytes, por ejemplo, datos flotantes de imagen en el mismo lugar. Por lo tanto, voy a usar 128 contenedores al menos que el usuario me diga algo diferente. Esto me dará una buen parecido grafico casi siempre. Voy a tener que calcular el tamaño del bin apropiadamente para esto. El código se verá así: IF N_elementos(binsize) EQ 0 then begin

range = Max(image) - Min(image) binsize = 2.0>(rango / 128.0)

ENDIF IF N_Elementos(max_value) EQ 0 THEN max_value = 5000.0 El tamaño de bin o biene ser 2, o será el rango de datos de imagen dividido por 128, si esta última cifra es mayor. Estoy haciendo la suposición aquí que yo no voy a tener datos de imagen de punto flotante, que oscila de 0,0 a 1,0, por ejemplo. Mi programa se verá mal con esos datos, pero las posibilidades parecen tan baja de este acontecimiento que estoy dispuesto a correr el riesgo. Y, de todos modos, si el usuario tienen datos de imagen de esa manera, que siempre podría especificar un tamaño del bin adecuado para la visualización del histograma. Observe el uso del IDL "mayor que" (>). Este operador devuelve el mayor de los dos valores que se comparan. Tenga en cuenta, también, los paréntesis alrededor del valor que quiere comparar a la derecha del operador. Sin los paréntesis, 2.0 se compararía con el registro, y luego el valor that se divide por 128. ¡No es lo que yo quiero para todos! Esto sucede debido a que el mayor operador tiene el mismo orden de precedencia como el operador de división. Este es un tipo común de error en los programas de IDL. Otro error común se produce dentro de los paréntesis. Fíjate que he hecho el número 128.0 un número de punto flotante mediante la adición de un punto decimal en el número. Es posible caer fácilmente en el error de escribir este número como un número entero (por ejemplo, 128). Entonces, un byte o que los datos de imagen sean enteros, se divide un valor entero (el rango) por otro valor entero. Esto puede fácilmente darle un tamaño bin coherente de 0. Un grave error. La palabra clave Max_Value se le asigna un valor de 5,000, un valor que funciona con la mayor parte de los datos de imagen de ejemplos se establece con la distribucion IDL. A continuación, puede poner a prueba los valores de palabra clave XScaIe y YScale. Si éstos no se suministran,utilizen las dimensiones de la imagen para los valores de la escala. También voy aprobar para asegurarme que los valores de sean dos conjuntos de elementos. Si no es así, voy a difundir los mensajes de error. El código se verá así: S = Size(image,/Dimensions) IF N_Elements(xscale) EQ 0 THEN xscale = [0, S[0]]

Page 7: Capítulo9

IF N_Elements(xscale) NE 2 THEN $ Message,'XSCALE must be 2-elementos array', /noname IF N_Elements(ysca1e) EQ 0 THEN yscale = [0, S[1]] IF N_Elements(ysca1e) NE 2 THEN $ Message, 'YSCALE must be 2-elementos array', /noname Fíjese una nueva palabra clave para el comando Size aquí: Dimensions. A diferencia de la palabra clave N_Dimensions, devuelve el tamaño con el número de dimensiones de su argumento, la palabra clave Dimensions devuelve un vector que contiene el tamaño de cada una de sus dimensiones. En otras palabras, con una serie de imágenes 2D, voy a tener una matriz de dos elementos de tamaño X y tamaño Y para la imagen, respectivamente. Por último, puedo comprobar la palabra clave Color. Porque quiero escribir un dispositivo de estado de descomposición con códigos independientes, voy a utilizar el programa de GetColor para especificar los colores de dibujo. (GetColor se discute en " Obtención de Dispositivos Independientes de Colores "en la página 87.) GetColor" sabe "los nombres de los 16 colores de dibujo que utiliza con frecuencia y puede obtener esos colores para mí de una forma independiente del dispositivo. (Puede fácilmente añadir más colores a GetColor) revise las palabras clave como esto: IF N_Elements(dataCo1orName) EQ 0 THEN $

dataColorName = 'Red' IF N_Elements(axisColorName) EQ 0 THEN $

axisColorName = 'Navy' IF N_Elements(backcolorName) EQ 0 THEN $

backcolorName = 'White' Pude comprobar para asegurarse de que los nombres de los colores aprobados en el programa son las variables de cadena, pero GetColor va a hacer de todos modos. Y sé que va a regresar al llamado del programa que lo llamó. Por lo tanto, voy a ser capaz de atrapar a ese error en mi controlador de errores cuando se trata de volver de GetColor: Por lo tanto, no hay necesidad de comprobar si hay posibles errores aquí. Tenga en cuenta que yo hago el color de fondo blanco de forma predeterminada. Esto no es, sin duda necesario, y más a menudo que no me gusta tener un color de fondo carbón o gris. Elijo blanco aquí, porque a veces es más fácil de visualizar los resultados que va a parecer cuando hago un archivo PostScript desde este programa. Recuerde que usted puede tener cualquier color de fondo que le guste en PostScript, por mientras es de color blanco. (Este problema se discute en "Problema: Los dispositivos PostScript uso de fondo y Trazado de colores de forma diferente "en la página 189.) Lo más importante es que necesito alguna manera de cambiar los colores de los dibujos, porque es casi seguro que tengo que cambiarlos al enviar el resultado a un Impresor de PostScript. Al hacer que los colores por defecto adecuados para la impresión en un archivo impresión PostScript, ahora no tendrá que preocuparse acerca de cómo restablecer los colores. Voy a llamar al programa HistoImage para dibujar los gráficos en sus colores por defecto cuando quiero hacer un archivo Postscript. Si el usuario no proporciona un número de índice de la tabla de colores, elijo tabla de colores 4. IF N_Elements(colortab1e) EQ 0 THEN colortable = 4 colortable = 0> colortable <40 Tenga en cuenta que sólo hay 41 tablas de colores suministrados con IDL (aunque los usuarios podrían modificar este número, por cierto). Aquí puede ver un poco de la comprobación para forzar la tabla de colores valores entre un número entre 0 y 40.

Page 8: Capítulo9

En IDL el operadores mayor que y menor que se utilizan para forzar el rango correcto de los números. (En otras palabras, 0 es comparado con tabla de colores y el valor más grande es el de retorno. Entonces que valor se compara con 40 y el más pequeño de los dos valores es devuelto en la variable de la tabla de colores.) Este tipo de comprobación de errores proactivo puede evitar problemas más adelante. A continuación, le ofreceremos la palabra clave ImageColors con un valor. Tenga en cuenta que voy a usar tres colores de dibujo en este programa. Prefiero cargar mis colores dibujo en la parte superior de la tabla de colores, aunque otras personas prefieren para cargarlos en la parte inferior de la tabla de colores. No importa mucho donde se los carga, siempre y cuando usted sabe lo que está haciendo al manipular la tabla de colores. Pero si bien me gusta cargar colores de dibujo en la parte superior de la tabla de colores, no me gusta utilizar el número de índice de la parte superior de la tabla de colores. La razón por la que no lo es que muy a menudo este índice, se utiliza para la Variable del sistema !P.Color. Y muchos programas están escritos asumiendo este color que va a ser blanco o negro. No me gusta romper estos programas, si puedo evitarlo. Así que dejo este índice solo. Cómo cargo mis tres colores de dibujo y el cuarto índice de la parte superior. Esto significa que los índices de color que tengo para los rangos de visualización de imágenes son desde 0 hasta el quinto índice a partir de la parte superior de la tabla de colores. Esto es -4 colores en total !D.Table_Size . Esto es lo que Asigno la palabra clave ImageColors como valor en el programa. imagecolors =!D.Table_Size -4 Tenga en cuenta que no tengo que comprobar la palabra clave output. Si el usuario desea que el valor de él o ella puede ser recuperado con palabras claves. Si ellos no quieren que el valor, bueno. Esto no le cuesta mucho para asignarlo a una variable. (Y yo necesito el valor más adelante en el programa de todos modos) No hay necesidad de usar algo como Arg_Present en este caso: IF Arg_Present(imageco1ors) THEN $ imagecolors =!D.Table_Size -4 Esto es un exceso y los resultados en la variable imagecolors sólo están definiendo si el usuario aprueba en una referencia de variables con la palabra clave. La construcción más simple es mucho más fácil de escribir y creo que hace que el programa sea más fácil de leer, también. Recuerde que la variable imagecolors está diseñado para ayudar a alguien fuera del programa de control de los colores de la imagen. No tengo ninguna necesidad en este momento, pero puedo usarlo más tarde y quiero estar preparado para la eventualidad. Cargando los colores del programa Los tres colores de dibujo van a ser cargado a partir de la cuarto índice en la parte superior de la tabla de colores. Yo siempre uso !DTableSize para indicar el tamaño de la tabla de colores. Entonces !DTableSize es el índice más alto en la tabla de colores. El código es el siguiente: axiscolor = GetColor(axisColorName,!D.Table_Size-2) Datacolor = GetColor(dataColorName,!D.Table_Size-3) backcolor = GetColor(backcolorName,!D.Table_Size-4) Las variables BackColor, dataColor, y axisColor ahora contienen el correcto número de índice de color para la carga del color apropiados (si el dispositivo de descomposición está apagado o si este es un dispositivo de 8 bits), o un valor de 24 bits que se pueden descomponer en el color

Page 9: Capítulo9

adecuados (Si este dispositivo de descomposición está encendido). En cualquier caso, no tiene que preocuparse en absoluto sobre el estado actual de descomposición del color de los gráficos con estos colores. Los colores correctos van a aparecer de forma casi automática. A continuación se carga los colores para los datos de la imagen. Yo sólo hago esto si la variable de la palabra clave NoLoadCT no se ha establecido. IF NOT Keyword_Set(noloadct) THEN $ LoadCT, colortable, NColors=imagecolors, /Silent Nótese que uso la palabra clave Silent al comando LondCT. Realmente no me gusta el mensaje informativo LondCT que imprime en la ventana de registro de comandos cada vez que se carga una tabla de colores. Esta palabra clave suprime el mensaje. Tenga en cuenta, también, que puedo restringir, con la palabra clave NColors, el número de colores cargados en los índices utilizados por la imagen. Quiero tener cuidado de no sobre grabar los colores de dibujo que acabo de cargar. Sólo los índices de la tabla de colores cargados por este comando !D.Table_Size pueden ser de 0 a -5. Preparación para dibujar los gráficos El siguiente paso en la redacción del programa de HistoImage es preparar los dibujos gráficos. Yo tengo tres elementos separados para dibujar, el histograma, la barra del color y la imagen en sí. Cálculo de posiciones en la ventana de gráficos Así que lo primero que hago es calcular las posiciones de la ventana donde yo quiero que estos artículos pudan ir. Estas posiciones serán arrays de cuatro elementos que contiene la ventana de coordenadas normalizadas del tipo que se pueden utilizar con la palabra clave Position en la mayoría de los comandos gráficos. (Consulte "Colocación de salida gráfica en la ventana de visualización" en la página 44 para más detalles de coordenadas normalizadas cómo se hace esto.) se utilizan para que los gráficos puedan ir en una ventana de cualquier tamaño. El código se verá así: histoPos =[0.15, 0.675, 0.95, 0.95] colorbarPos=[0.15, 0.500, 0.95, 0.55] imagePos =[0.15, 0.100, 0.95, 0.40] Cambiando el tamaño del carácter según el tamaño de la ventana Uno de los requisitos de este programa es que puede mostrar sus gráficos en la ventana de gráficos redimensionado. O dicho de otra manera, que puede mostrar gráficos en unas ventanas de cualquier tamaño. En otras palabras, si la ventana es grande el histograma debe ser grande y la visualización de la imagen debe ser igual de grande. Si la ventana es pequeña, la trama y la imagen en la pantalla deben ser pequeñas, etc. Esto es realizado, obviamente, por la posición de diversos componentes en la ventana de coordenadas normalizadas, como se describió anteriormente. Pero a menudo esta forma de pensar no nos lleva a la anotación de las pantallas gráficas. La mayoría de los programadores utilizar un tamaño de la fuente de 1 y lo llaman bueno. Pero si le gustaría ver un gran tamaño de los caracteres utilizados en las ventanas grandes y un tamaño pequeño de caracteres utilizado en las pequeñas ventanas. Una palabra clave que se puede utilizar es CharSize con los comandos gráficos para cambiar el tamaño de la fuente, pero ¿cómo se puede hacer esto de una manera que sea consistente con el tamaño de la ventana? La respuesta, al igual que muchas de las respuestas que han descubierto

Page 10: Capítulo9

hasta el momento, es expresar el tamaño de los caracteres en unidades normalizadas. Por desgracia, esto es imposible en IDL. El tamaño del carácter es siempre expresado en unidades de carácter. Pero aun así ... debe haber una manera! En realidad. Resulta que con el comando XYOutS puede obtener el width de una cadena de texto en unidades normalizadas. Y si utiliza un valor negative con la palabra clave CharSize, entonces XYOutS no será realmente escrita como cadena para mostrase en la ventana, sólo se calcula el ancho de la cadena. Por ejemplo, suponga que desea conocer el ancho de la cadena de texto "Una cadena de ejemplo". Usted puede escribir lo siguiente: IDL> thisSize = -1 IDL> XYOutS, 0.5, 0.5, 'Una muestra cadena', /Normal, $

Width=thisWidth, Charsize=thisSize Ahora, supongamos que comparó el valor de thisWidth con cierta anchura de objetivo. Digamos, por ejemplo, que la anchura objetivo era 0,25. Otra forma de decir esto es que la cadena debe ser lo suficientemente amplia como para extenderse a través de 25 por ciento de la ventana de visualización. Si el ancho del objetivo era mayor que el valor de thisWidth puede aumentar el tamaño de la fuente en una pequeña cantidad, y probar de nuevo, y así sucesivamente hasta que el tamaño de la fuente sea adecuado para darle el ancho de texto que querías. El código podría tener este aspecto: IDL> IF thiswidth LT 0.25 THEN thissize = thissize + 0.01 IDL> XYOutS, 0,5, 0,5,'a simple string', /Normal, $

width = thisWidth, Charsize = thisSize

Finalmente, thisWidth pueda ser dentro de un pequeño valor delta de la anchura del objetivo. El algoritmo similar se puede emplear si thiswidth es mayor que la anchura del objeto. Este tipo de algoritmo ha sido desarrollado para que la forma del programa Str-Size descargado con los archivos de programa para utilizalo en este libro. El parámetros Str-Size son una cadena y un ancho de objetivo, en coordenadas normalizadas. Se encontro que la cadena "Una cadena de ejemplo" y un ancho blanco de 0,20 produce muy bien caracteres de tamaño en la mayoría de las parcelas en las ventanas de gráficos que suelen utilizar. IDL> ThisSize = Str_Size ('Una muestra String', 0.20) Este es un tamaño de carácter de aproximadamente 1,4 para una ventana de tamaño normal en una máquina Windows, por ejemplo. En este programa, voy a escribir el tamaño de la fuente del código de selección de la siguiente manera: ThisCharSize = Str_Size('Una muestra String', 0.20) Cálculo del histograma de la imagen El siguiente paso es calcular el histograma de la imagen. (Recordemos que un histograma es simplemente un contador del número de entidades en cada bin del histograma. Normalmente, tomamos el número de píxeles con cada valor de la imagen.) Yo simplemente uso el comando Histogran, pasándole el tamaño de bin que quiero usar, así: histdata = histogram(imagen,Binsize=binsize, $ Min=Min(imagen), Max=Max(imagen))

Page 11: Capítulo9

Note que puse las palabras clave Min y Max explícitamente para la función Histogram a valor mínimo y máximo de la imagen. La documentación IDL afirma que esto es la función Histogram por defecto, pero no he encontrado que este sea el caso. Más bien, me parece que toma el valor mínimo de 0 y un valor máximo de 255 para imágenes bytes, independientemente de los valores de datos reales en la imagen. Dibujar los gráficos Hay tres elementos gráficos que desea dibujar: un histograma, un bar de color para que indican los valores de imagen, y la imagen misma. Dibujar el histograma IDL me da varias opciones para dibujar el histograma, pero me parece que no me gustan las dos más obvias. Voy a explicar lo que quiero decir con un ejemplo sencillo para que pueda escribir en la línea de comandos de IDL. Supongamos que tengo cinco contenedores de datos, cada bin en 5 unidades de tamaño, y un vector que me dice cuántos "objetos" son en cada bin. Los datos y los vectores bins se podrían crear como esto: IDL> data = [4, 6, 3, 8, 2] IDL> bins = , [0, 5, 10, 15, 20] El método más obvio es simplemente representar los datos con el comando Plot, de esta manera: IDL> plot,bins,data,YRange=[0,10] El resultado, que no se parece mucho a la definición del comando plot "histograma", es ilustrado en la Figura 95.

Figura 95: Una trama muy simple de un funcion histograma. Teniendo en cuenta que no se ve igual que un histograma. El segundo enfoque es obvio para establecer la palabra clave PSym a 10, lo que resultará el tipo "escalón" de la trama que se espera de un histograma. Puedo probar esto: IDL> Plot,bins,data,YRange=[0,10],PSym=10

Page 12: Capítulo9

Los resultados se ven mejor, como se muestra en la Figura 96, pero que todavía no están bien. En particular, los bins están representados incorrectamente. La primera bandeja va de 0 a 5, el segundo bin desde 5 a 10, y así sucesivamente. Pero en la ilustración, la primera bandeja parece ir de 0 a 2,5, y el segundo bin parece que van desde los 2,5 a 7,5, y así sucesivamente. Parece como si cada bin fuese medio tamaño.

Figura 96: Esta parcela se parece más a una parcela histograma, pero todavía no está bien. Notar que los contenedores parecen ser de un tamaño medio fuera de bin. Podría tratar de solucionar el problema mediante la adición de un tamaño medio bin a cada uno de los contenedores, así: IDL> Plot,bins+2.5,data,YRange=[0,10],PSym=10 Verá los resultados en la Figura 97. De nuevo, está cerca de ser correcta, pero tengo problemas en cada extremo de la trama, donde las líneas deben extenderse hasta el final de la ventana gráfica. Para dibujar realmente esta trama correctamente, debería duplicar los valores del primero y último, de los datos del histograma y los valores de bin.

Figura 97: Esta parcela ha tenido la mitad de un tamaño de bin añadido a los valores de ubicación. Es preciso, pero las líneas de la trama no se extienden a los extremos de la ventana de dibujo

Page 13: Capítulo9

Por ejemplo, puedo hacer algo como esto: Plot, [bins[0], bins + 2.5, bins[4] + 2.5 * 2], $ [data [0] , data, data [4]], YRange= [0,10], PSym=10

Por último, tengo el tipo de histograma que espero, como se ilustra en la Figura 98.

Figura 98:. El histograma que esperaba conseguir Sería fácil y suficiente añadir líneas verticales con el comando PlotS para crear cajas de histograma para cada bin. Este es exactamente el tipo de enfoque que voy a tener en el programa HistoImage. El código para esquivar los bins y el vectore histodata para tener un trazado correcto de esta manera: npts = N_Elements(histdata) halfbinsize = binsize / 2.0 bins = Findgen(N_Elements(histdata)) * binsize + Min(image) binsToPlot = [bins[0] , bins + halfbinsize, $ bins [npts-1] + binsize] histdataToPlot = [histdata[0] , histdata, histdata [npts-1]] xrange = [Min(binsToPlot ) , Max(binsToPlot)] El código para trazar el diagrama de histograma en el color de eje, seguido de los datos del histograma dibujado en el color de los datos se verá así: Plot, binsToPlot, histdataToPlot, $ Background=backColor, $ Charsize=thisCharsize, $ Color=axiscolor, $ Max_Value=max_value, $ NoData=1, $ Position=histoPos, $ Title='Irnage Histogram', $ XRange=xrange, $ XStyle=1, $ XTickformat= '(I6)' , $ XTitle='Image Value', $ YMinor=1, $ YRange= [0, max_value], $

Page 14: Capítulo9

YStyle=1, $ YTickformat= '(I6)', $ YTitle='Pixel Density', $ _Extra=extra OPlot, binsToPlot, histdataToPlot, PSym=10, Color=dataColor FOR j =1L,N_Elements(bins)-2 DO BEGIN Plots, Color=dataColor, [bins[j] , bins [j]] , $ [!Y.CRange[0], histdata[j] < max_value] ENDFOR Tenga en cuenta que yo uso el comando PlotS para dibujar líneas verticales en cada límite bin. Esto da el histograma en una caja que me guste más asi que sólo usar el histograma trazado con símbolo (Psym = 10) con el comando Plot. Me parece que al poner las palabras clave en orden alfabético cuando yo uso un comando que requiere el establecimiento de un número de palabras clave de un estilo de utilidad. Esto hace que sea mucho más fácil de ver las palabras claves que he fijado explícitamente. Esto ahorra tiempo y esfuerzo si tengo que añadir o eliminar una palabra clave más adelante en el desarrollo del programa. Dibujando la barra de colores El dibujo de la barra de color es fácil. Yo simplemente uso el programa Colorbar descargado para el uso con este libro. Como TVImage (ver "Un alternativo comando para mostrar Imagenes" en la página 62), el programa de descomposición Colorbar es independiente del dispositivo y se puede utilizar en cualquier dispositivo de gráficos compatible con IDL. Los comandos se parecen a esto: cbarRange = [Min(binsToPlot) , Max(binsToPlot)] Colorbar, $ Charsize=thisCharsize, $ Color=axisColor, $ Divisions=0, $ NColors=imagecolors, $ Position=colorbarPos, $ Range=cbarRange, $ XTicklen=-0.2, $ _Extra=extra Observe que la barra de color se limita al mismo número de colores de la imagen, y que la gama de colores que se toma de la variable binsToPlot . Al establecer la palabra clave XTickLen a un valor negativo, produce hacia afuera marcas de graduación. Ajuste la palabra clave Divisions a 0, permite que el programa para elija divisiones de anotación de la misma manera que el comando plot. Esto hará que el Colorbar sea una anotación idéntica a las anotaciones del histograma directamente por encima de ella y reforzará el propósito de las anotaciones. Dibujo del diagrama de imagen Todo lo que queda por hacer es dibujar la imagen, con sus ejes alrededor. Yo usare el comando TVImage para ver la imagen (véase "Un comando alternativo para mostrar Imagenes" en la página 62) y el comando plot para dibujar los ejes, utilizando los valores dados por las palabras claves XScale y Yscale como el rango de la parcela. El código final se verá así: TVImage, BytScl(image,Top=imagecolors-1), $ Position=imagePos, _Extra=extra PLOT, xscale, yscale, $

Page 15: Capítulo9

Charsize=thisCharsize, $ Color=axisColor, $ NoData=1, $ NoErase=1, $ Position=imagePos, $ XStyle=1, $ XTicklen=-0.025, $ YStyle=1, $ YTicklen=-0.025, $ _Extra=extra END Tenga en cuenta que yo escalo los datos de la imagen en el número de colores de la imagen y que la posición tanto la imagen y los ejes sobre la imagen con la variable imagePos. Trabajar en un error de dispositivo de impresora Hay un pequeño dispositivo Printer en las versiones de IDL a través de IDL 5.3.1 (la versión oficial en el momento en que está escrito) que causa un problema cuando el código es enviado directamente a una impresora PostScript. (Consulte "Carga de colores en el dispositivo de impresión" en la página 204 para obtener más información.) Resulta que cuando se carga un solo color en la tabla de color (en este programa que se realiza con el comando GetColor ) en cualquier índice en absoluto, entonces ese mismo color se utiliza para mostrar cualquier píxel de la imagen que tiene un valor de 0. (Se trata de un strage !). Por ejemplo, si escribe estos comandos, y su impresión por defecto es en una impresora PostScript (PCL parecen ser afectados), entonces es posible ver la salida que se parece a la ilustración de la figura 99. IDL> thisDevice = !D.Name IDL> Set_Plot, 'PRINTER' IDL> LoadCT, 0, NColors=!D.Table_Size-4 IDL> HistoImage, /NoLoadCT IDL> Device, /Close_Document IDL> Set_Plot, thisDevice El trabajo en torno a este error, lo que hará que el código completo del dispositivo independiente, es simplemente llegar y volver a cargar los vectores de la tabla de colores después de que el último color solo se carga en la tabla de colores. En el código HistoImage , busque esta línea: IF NOT Keyword_Set(noloadct) THEN $ LoadCT, colortable, NColors=imagecolors, /Silent La línea anterior debe ser reemplazada con este código: IF NOT Keyword_Set(no1oadct) THEN BEGIN LoadCT, colortable, NColors=imagecolors, /Silent ENDIF ELSE BEGIN IF !D.NAME EQ 'PRINTER' THEN BEGIN TVLCT, r, g, b, /Get TVLCT, r, g, b ENDIF ENDELSE Esto hará que los colores correctos se cargen cuando el programa se envía al dispositivo de impresión(printer).

Page 16: Capítulo9

Compilación y prueba del programa Para compilar y probar el programa, escriba lo siguiente: IDL> .Compile histoimage IDL> HitoImage Si el programa no compila, o si tiene errores cuando se ejecuta, elimine el programa desde la pantalla con el ratón, tipee RETALL en la línea de comandos de IDL, y corregir los errores. No se olvide de volver a compilar el programa antes de ejecutarlo de nuevo. Intente ejecutar el programa con una imagen diferente:

Figura 99: Un error de dispositivo de impresión que se traduce en todos los píxeles con valor 0 aparecer el último de un solo color cargado en la tabla de colores (el color background, en este caso). La solución alternativa es llegar y volver a cargar los vectores de la tabla de colores cargando un solo color. image = LoadData(5) HistoImage, image Pruebe establecer algunas de las palabras claves. Por ejemplo, pruebe algunas de las palabras clave de color: IDL> HistoImage, image, $ AxisColorName='beige', $ BackColorName='gray', $

Page 17: Capítulo9

ColorTable=33, $ DataColorName='yellow' Trate de poner diferentes escalas en la imagen: IDL> HistoImage, xScale=[0,1],scale=[-1,1] ¿Qué pasa con el establecimiento de palabras clave que no están definidos para Histolmage, sino que se recoge por el mecanismo de herencia de palabras clave? Pruebe, por ejemplo, el establecimiento de la palabra clave Keep_Aspect_Ratio del comando TVIrnage y la palabra clave Divisions del comando Colorbar así: IDL> HistoImage, /Keep_Aspect_Ratio, Divisions=8 Revisión del Programa de Ventajas Histolmage Vamos a repasar algunos de las ventajas del programa HistoImage. Y yo quiero señalar un pocos que puede no ser evidente para usted, incluso aún. En primer lugar, el programa ha sido escrito de tal manera que no importa si usted está en una pantalla de 8-bit o 24-bit, el programa funcionará de forma idéntica. Ni tampoco importa si usted tiene el color descomposición dentro o fuera de si usted está en una pantalla de 24-bit. Esto se debe a que hemos utilizado programas de color consistentes como GetColor y TVImage cargar colores de dibujo y mostrar la imagen. Hemos escrito el programa HistoImage con palabras claves _Extra definida para ello. Esto nos permite pasar palabras claves "extra" en los comandos plot, Colorbar, y TVImage dentro del programa. Pero también hace algo mucho más útil. Esto nos permite escribir un programa que puede automáticamente volver a mostrar el gráfico en pantallas de 24 bits cuando cambiar las tablas de colores. (Consulte "Actualización automática de gráficos Cuando el color las tablas están cargados "en la página 66 para obtener más información.) Por ejemplo, abra un editor de texto y crear el archivo simple, que se puede nombrar histoimage_redisplay.pro. (Este programa es uno de los programas que ha descargado para utilizar con este libro, si usted prefiere no escribirlo.) PRO HistoImage_Redisplay, Image=image, _Extra=extra IF N_Elements(image) EQ 0 THEN image=LoadData(7) HistoImage, image, /NoLoadCT,_Extra=extra END Este programa nos permitirá cambiar la tabla de colores asociada a HistoImage y ver los efectos inmediatamente. (Esto sólo será necesaria en las pantallas de 24 bits, recordar. En pantallas de 8 bits, los colores se actualizan automáticamente.) Tenga en cuenta que la palabra clave NoLondCT se establece. Esto es necesario, para una entidad externa para controlar los colores. Si no se establece esta palabra clave, HistoImage siempre cargaba su propia tabla de colores en lugar de utilizar los colores de la tabla de colores actual. En primer lugar, llame al programa normalmente y averiguar cuántos colores de imagen hay. La palabra clave de salida ImageColors se utiliza para este propósito. IDL> image = LoadData(13) IDL> HistoImage, image, ColorTable=33, ImageColors=ncolors A continuación, llame a XColors para cargar diferentes tablas de colores. (XColors es un programa que se ha descargado para su uso con este libro. Utilizo exclusivamente en su lugar XLondCT, que es suministrado por IDL, por razones que usted aprenderá acerca de las

Page 18: Capítulo9

siguientes secciones de este capítulo. Tiene muchas ventajas para XLoadCT, uno de los cuales es que yo creo que tiene un mayor sintaxis natural para la actualización automática de pantallas gráficas en un dispositivo de 24 bits.) IDL> XColors, NColors=ncolors, Image=image, $ NotifyPro='HistoImage_Redisplay' Si usted tiene ambos XColors y su ventana gráfica abierta en la pantalla, para que pueda ver a los dos, te darás cuenta de que, al seleccionar las tablas de colores de la lista de tablas colores en XColors, los colores se actualizan automáticamente en la ventana de visualización. Tenga en cuenta que si está ejecutando IDL en un dispositivo de 8 bits, sólo necesita llamar a XColors como esto: IDL> XColors, NColors = ncolors Ahora, cierra su ventana XColors si aún está en la pantalla. El programa XColors trabajará con el programa HistoImage_Redisplay no importa las palabras clave que se utilizan con HistoImage. Por ejemplo, puede escribir lo siguiente: HistoImage, image, BackColorName='gray', $ AxisColorName='yellow', ImageColors=ncolors XColors, Image=image, NColors=ncolors, $ BackColorName='gray', AxisColorName='yellow', $ NotifyPro='HistoImage_Redisplay' El Programa HistoImage es independiente del dispositivo Hemos visto que el programa HistoImage es la profundidad visualización independiente y deconposicion independiente del Color, pero lo que puede no ser inmediatamente obvio es que también es independiente del dispositivo. Es decir, no importa qué dispositivo de pantalla gráfica haya seleccionado para mostrar gráficos,el programa HistoImage funciona correctamente en el dispositivo. Esto incluye dispositivos tales como el dispositivo PostScript (PS), el dispositivo de impresión (printer), y el dispositivo de memoria intermedia Z-gráficos (Z). Por ejemplo, para imprimir esto en la impresora predeterminada, puede escribir lo siguiente: IDL> thisDevice = !D.Name IDL> Set_Plot, 'PRINTER', /Copy IDL> Device, XSize=5, YSize=5, /Inches, XOffset=1.75,YOffset=3.0 IDL> HistoImage ,image IDL> Device, /close_Document IDL> Set_Plot, thisDevice O bien, para crear un archivo PostScript, puede escribir lo siguiente: IDL> thisDevice = !D.Name IDL> Set_Plot,'PS' IDL> Device, XSize=5, YSize=5, /Inches, XOffset=1.75,YOffset=3.0 IDL> HistoImage,image IDL> Device, /close_File IDL> Set_Plot , thisDevice Recordemos que puse el color de fondo blanco de forma predeterminada sólo con el propósito de ser capaz de enviar la salida gráfica a una impresora o al dispositivo PostScript. Si no lo está blanco en la pantalla, se debe cambiar a blanco antes de enviarlo a la impresora o crear un archivo PostScript. Las palabras claves de colores hacen que sea fácil de hacer este interruptor cuando están utilizando este tipo de dispositivos de salida gráfica.

Page 19: Capítulo9

Lo que hace el programa HistoImage independiente del dispositivo es la ausencia de comandos que sólo funcionan en un dispositivo en particular. Por ejemplo, usted no ve ningún comando Window en este programa, ya que un comando Window sólo es apropiado en los dispositivos de visualización y no, por ejemplo, en el dispositivo PostScript. Los gráficos se han escrito para entrar en cualquier ventana que pasa a ser abierto. Si el dispositivo de gráficos es un dispositivo de visualización (es decir, WIN, MAC o X), y una ventana no está actualmente abierta, una ventana por defecto será abierto cuando se ejecuta el primer comando de gráficos. Si quería tener un comando Window en el programa (y casi nunca lo hago, sobre todo si tengo planes para usar el programa en un programa Widget), entonces usted debe asegúrese de que el dispositivo es compatible con Windows. Esto se puede hacer con flags del sistema variable !D . El campo flags es un mapa de bits y queremos ver si el bit corresponde a el valor 256 se establece (ventanas son compatibles con este dispositivo) o no (Las ventanas no son compatibles con este dispositivo). El código se verá así para una posible Ventana de comandos: IF (!D.Flags AND 256) NE 0 THEN Window Otra orden común que no se ve en este programa es un dispositivo, comando Decomposed =0. Normalmente se requiere este comando para mostrar imágenes 2D en color. Nosotros no tienen que incluirlo porque los comandos Colorbar y TVIrnage han sido escrito con esta inteligencia integrada en ellos. Sin embargo, tendríamos que utilizar un comando como este si íbamos a usar el comando TV para mostrar la barra de color y la imagen. De hecho, probablemente tenga que usar varios comandos para comprobar la profundidad visual, el tipo de dispositivo, etc Para más detalles, examinar el código, ya sea en los programas TVImage o Colorbar. En el programa Colorbar de 12 líneas de código presedidos por el comando TV y otras 12 líneas que siguen, sólo para la trabajar con el comando TV correctamente en todos los dispositivos! Usando Histolmage en un Redimencionable Ventana Gráfica "Smart" El programa HistoImage también cumple con los criterios de visualización de gráficos para que se muestren con un programa de ventana gráfica redimensionable, nombrado por el FSC_Window, que fue descargado para ser utilizado con este libro. El programa FSC_window es un ventana gráfica "inteligente", ya que puede cambiar el tamaño de su contenido, al crear BMP, GIF, JPEG, PICT, PNG, TIFF y archivos PostScript de su ventana de contenido , y enviar su contenido directamente a la impresora. Además, si su programa de visualización gráfica ha sido escrita correctamente, también puede cambiar los colores en su programa con una tabla de colores cambio de herramienta. Los cinco cripterios FSC_Windows que se impone en un programa de visualización son los siguientes:

1. El progama se debe escribir como un procedimiento. 2. No debe haber más de tres argumentos posicionales. 3. Puede haber un número ilimitado de argumentos de palabra clave. 4. El programa debe estar escrito de manera que el contenido entre en cualquier ventana de

tamaño. 5. No debe haber comandos específicos del dispositivo en el programa (por ejemplo, el

comandos Windows). Muchos comandos de visualización de gráficos cumplen este criterio. Por ejemplo, el comando Shade_surf . Escriba los siguientes comandos: IDL> peak = LoadData (2) IDL> LoadCT, 22 IDL> FSC_Window, 'Shade_Surf1', peak, Charsize=1.5

Page 20: Capítulo9

Usted ve un ejemplo del programa FSC_windows de la figura 100. Observe los controles bajo el archivo de la barra de menú. Usted puede tomar el borde de la ventana con el ratón y cambiar el tamaño de la ventana. El contenido de la ventana cambia de tamaño para adaptarse a ellos. Usted puede tener tantos programas FSC_windows funcionando como usted lo desea. Por ejemplo, vamos a mostrar una imagen en un programa FSC_windows, pero también vamos a establecer la capacidad de los programas para cargar las tablas de colores diferentes. Escriba lo siguiente: image = BytScl(LoadData(7) , Top=!D.Table_Size-l) FSC_Window, 'TVImage', image, /WColors Observe que ahora hay un menú de elemento de Colores en el archivo y un botón en la barra de menús. Haciendo clic en este botón para acceder al XColors herramienta para cambiar de color. XColors es un programa que fue descargado para su uso con este libro. Una de sus grandes ventajas es que no utiliza bloques comunes para almacenar sus tablas de colores. Lo que significa que no puede haber múltiples programas XCo1ors en la pantalla a la vez. Algo que es imposible con XLondCT, y el IDLsupplied , herramienta del cambio de la tabla de color. Por ejemplo, vamos a obtener el programa HistoImage en la pantalla también. Recuérdese, sin embargo, que usted no desea utilizar todos los colores en la tabla de colores. Reservamos los cuatro primeros colores para otras cosas. Y recuerdan que si queremos que los colores sean manipuladas externamente, tenemos que estar seguro de no cargar la tabla de colores en HistoImage. Esto se logra estableciendo la palabra clave NoLondCT . Escriba lo siguiente: IDL> image = BytScl(LoadData(5),Top=!D.Table_Size-1) IDL> FSC_Window,'HistoImage',image,/NoLoadCT, $ wcolors= !D.Table_Size-4 Ahora usted puede conseguir la herramienta de tabla de colores de ambos programas en la pantalla al mismo tiempo. Si está ejecutando IDL en una pantalla de 8 bits, las cosas se ven un poco caótico, sin duda, ya que cada vez que se cambia la tabla de colores, los gráficos de salida cambian automáticamente.

Figura 100: El programa FSC_Window de la ventana grafica redimensionable con el comando Shade_Surf. Note que el menú pull-dowiz le permitirá imprimir y guardas los contenidos de una variedad de formatos de archivos.

Page 21: Capítulo9

En una pantalla de 24-bit, por supuesto, todo esto sucede de forma independiente. Lo que se nota en pantallas de 8 bits, sin embargo, es que el color será correcto para la ventana que tiene el foco del teclado actual. En otras palabras, cada ventana "sabe", que colores deben ser cargados y los carga cuando tiene el foco. Tenga en cuenta que en una pantalla 8 bit, el programa FSC_Window no puede tener un botón Print y el archivo PostScript como se muestra en la Figura 100. Cuando el dispositivo de visualización no tiene tantos colores como los dispositivos PostScript o una impresora, es imposible obtener siempre los colores correctos para PostScript y la salida de la impresora. Demasiados factores están involucrados y depende mucho de cómo se escribe el símbolo gráfico que se ejecuta. Por ejemplo, no es posible obtener una salida PostScript correcto de nuestro programa HistoImage cuando se ejecuta en una pantalla de 8 bits con la tabla de colores carga apagado, al igual que el caso actualmente. Usted aprenderá más acerca de cómo solucionar este tipo de problemas en los capítulos que siguen, pero por ahora usted debe saber que usted puede conseguir tanto un boton print y un botón de Archivo PostScript del programa FSC_windowl en una pantalla de 8 bits, pero usted tiene que fijar explícitamente. Por ejemplo, usted puede hacer esto: IDL> FSC_Window, TVImage , LoadData(7) , /WColors, $ /WPostS0cript,/WPrint Pero incluso este comando no se imprimirá correctamente o hacer un archivo PostScript correcto en una pantalla de 8 bits. Para hacer que la salida sea correcta, los datos de imagen tendrán que ser escalados correctamente tanto para la pantalla y para los dispositivos Postscript y la impresora. La única manera de hacer esto es lograr que para llevar a cabo el escalado justo en el comando TVImage, como esto: IDL> image = LoadData(7) IDL> FSC_Window , 'TVImage ' , $ BytScl(image, Top=!D.Table_Size-1), /WColors, $ /WPostScript/,WPrint