
Estudiamos la clase CCanvas. Implementación de la transparencia de los objetos gráficos
Índice
- Introducción
- 1. Transparencia (canal alfa)
- 2. Representación del color ARGB
- 3. Esquema de dibujado de los objetos en el terminal
- 4. Mezcla de colores. Color resultante
- 5. Ilusión de transparencia
- Conclusión
Introducción
Dibujar en el terminal MetaTrader 5 no es complicado, solo hay que conocer unos cuantos matices. Por ejemplo, cómo está construida la propia pantalla del terminal. Para ser más exactos, nos interesa en qué forma se muestran los gráficos en la pantalla del terminal. Y es que en la pantalla, el propio gráfico puede aparecer en el fondo o en primer plano. De dicha ubicación dependerá cómo se muestre el color en la pantalla. Ciertos objetos gráficos, al ser mostrados en la pantalla, pueden cambiar su color en la zona donde se cruzan.
Antes de pasar directamente al dibujo con ayuda de la clase CCanvas, hay que familiarizarse con varias definiciones relacionadas con el procesamiento del color. Por ejemplo, qué es la transparencia y qué es el canal alfa.
La implementación de la transparencia es algo que considero dentro de la tecnología principal, con ayuda de la cual se puede animar una imagen. Por ejemplo, con ayuda de la transparencia, se puede conseguir un interfaz más bonito, con un suave fluir hacia la luz o la sombra. La sombra transmitirá volumen al objeto gráfico y suavizará visualmente los bordes del objeto.
1. Transparencia (canal alfa)
Vivimos en un mundo en tridimensional y percibimos con volumen todos los objetos que nos rodean. El volumen de los objetos que nos rodean estamos acostumbrados a verlo e incluso a sentirlo. En el mundo tridimensional debemos distinguir cuál de los objetos está situado más cerca o más lejos de nosotros.
Además, algunos objetos pueden ser semitransparentes. Tomaremos como ejemplo un vaso de vidrio transparente con un cierto líquido semitransparente en su interior, sobre un fondo azul. A través del vaso con el líquido se ve el fondo azul que hay detrás. Además, la cantidad de detalles del fondo depende del nivel de transparencia del líquido.
Fig. 1. Punto de vista habitual sobre el volumen
La transparencia en este ejemplo no es virtual, ni tampoco ilusoria. La transparencia, en este caso, se percibe como algo que se da por sentado.
Al mostrar las imágenes en el monitor del ordenador, todo resulta de otra forma, la matriz de píxeles de los monitores es bidimensional: la imagen representada por la matriz tiene altura y anchura, pero carece del tercer parámetro, la profundidad. Por eso precisamente no hay posibilidad de situar los píxeles los unos sobre los otros, para simular la situación, el píxel inferior es del fondo amarillo, y el píxel superior es del vaso semitransparente. Cualquier imagen de un objeto tridimensional y realista en el monitor es una ilusión que se logra mediante un juego de luz y sombra.
Veamos el ejemplo de una imagen que se puede dividir en dos capas: la capa inferior es el fondo azul, y la superior, un vaso con un líquido opaco. Qué aspecto tiene en el monitor:
Fig. 2. Vaso opaco
En la imagen resultante, el vaso es totalmente opaco. Pero para añadir (cambiar) transparencia hay que pasar todos los colores de la imagen a una representación de color ARGB.
2. Representación del color ARGB
No me he olvidado de la transparencia del vaso. Veremos esta cuestión en profundidad en la segunda parte.
La representación del color ARGB es un tipo de 4 bytes uint, en el que están fijados en orden los siguientes valores: canal alfa, rojo, verde, azul. Es decir para transmitir transparencia al color en formato RGB, añaden un byte adicional con el valor de transparencia, el canal alfa.
Fig. 3. ARG
El valor del canal alfa se establece desde 0 (el color del píxel superpuesto de la capa superior no cambia en absoluto la imagen del píxel que tiene debajo en la capa inferior) hasta 255 (el color se superpone por completo y tapa el color del píxel que tiene debajo). La transparencia del color, expresada en tanto por ciento, se calcula según la fórmula:
Es decir, cuanto menor sea el valor del canal alfa, más transparente será el color. Significa que si se conoce la transparencia que queremos alcanzar, entonces el valor de alpha se puede calcular de la forma siguiente:
Para transformar el color en una representación ARGB, sirve la función ColorToARGB(color, alpha).
3. Esquema de dibujado de los objetos en el terminal
Para comprender mejor cómo tiene lugar el procesamiento del color, veamos el esquema de ubicación mutua de los objetos gráficos con las dos variantes de ajustes del gráfico: con el gráfico en el plano posterior y con el gráfico arriba.
3.1. Gráfico en el plano posterior
Es posible comprobar este ajuste de la siguiente forma: pulsar el botón derecho del ratón en el gráfico, después elegir del menú desplegable el punto "Propiedades..." y pasar a la pestaña "Varios".
Fig. 4. Gráfico en el plano posterior
La ventana del gráfico en el terminal consta de cuatro capas. En las dos capas de los extremos ("Plano posterior" y "Primer plano") se puede dibujar:
Fig. 5. Esquema de la ventana del gráfico
En el plano (fondo) posterior y en el primer plano, los objetos gráficos, al dibujar, se suporponen el uno al otro de acuerdo con el momento en el que fueron creados.
Es decir, en la parte más baja, en la capa "Plano posterior" y en la capa "Primer plano" se encontrarán los objetos gráficos "viejos". Por encima se superpondrán los objetos gráficos más "jóvenes".
Fig. 6. Ubicación de los objetos de acuerdo con su momento de creación
No todos los objetos gráficos pueden superponerse por completo sin repintar los sitios (o zonas) donde se cruzan con los objetos gráficos que hay debajo.
En el recuadro de abajo tenemos las características de los objetos gráficos, y después del recuadro viene la explicación sobre cómo se superponen los objetos que se repintan en las zonas de cruce.
Identificador | Objeto | Descripción | En el lugar de cruce con el objeto que hay debajo |
---|---|---|---|
OBJ_VLINE | Línea vertical | No repinta | |
OBJ_HLINE | Línea horizontal | No repinta | |
OBJ_TREND | Línea de tendencia | No repinta | |
OBJ_TRENDBYANGLE | Línea de tendencia por ángulo | No repinta | |
OBJ_CYCLES | Líneas cíclicas | No repinta | |
OBJ_ARROWED_LINE | Objeto "Línea con flecha" | No repinta | |
OBJ_CHANNEL | Canal equidistante | No repinta | |
OBJ_STDDEVCHANNEL | Canal de desviación estándar | No repinta | |
OBJ_REGRESSION | Canal de regresión lineal. | No repinta | |
OBJ_PITCHFORK | Tridente Andrews | No repinta | |
OBJ_GANNLINE | Línea de Gann | No repinta | |
OBJ_GANNFAN | Abanico de Gann | No repinta | |
OBJ_GANNGRID | Retícula de Gann | No repinta | |
OBJ_FIBO | Retrocesos de Fibonacci | No repinta | |
OBJ_FIBOTIMES | Zonas temporales de Fibonacci | No repinta | |
OBJ_FIBOFAN | Abanico de Fibonacci | No repinta | |
OBJ_FIBOARC | Arcos de Fibonacci | No repinta | |
OBJ_FIBOCHANNEL | Canal de Fibonacci | No repinta | |
OBJ_EXPANSION | Expansiones de Fibonacci | No repinta | |
OBJ_ELLIOTWAVE5 | Onda de impulso de Elliott | No repinta | |
OBJ_ELLIOTWAVE3 | Onda correctiva de Elliott. | No repinta | |
OBJ_RECTANGLE | Rectángulo | Sin relleno, no repinta, Con relleno, repinta | |
OBJ_TRIANGLE | Triángulo | Sin relleno, no repinta, Con relleno, repinta | |
OBJ_ELLIPSE | Elipse | Sin relleno, no repinta, Con relleno, repinta | |
OBJ_ARROW_THUMB_UP | Signo "Bien" (pulgar hacia arriba) | No repinta | |
OBJ_ARROW_THUMB_DOWN | Signo "Mal" (pulgar hacia abajo) | No repinta | |
OBJ_ARROW_UP | Signo "Flecha hacia arriba" | No repinta | |
OBJ_ARROW_DOWN | Signo "Flecha hacia abajo" | No repinta | |
OBJ_ARROW_STOP | Signo "Stop" | No repinta | |
OBJ_ARROW_CHECK | Signo "Palomita" (visto) | No repinta | |
OBJ_ARROW_LEFT_PRICE | Etiqueta izquierda de precio | No repinta | |
OBJ_ARROW_RIGHT_PRICE | Etiqueta derecha de precio | No repinta | |
OBJ_ARROW_BUY | Signo "Buy" | No repinta | |
OBJ_ARROW_SELL | Signo "Sell" | No repinta | |
OBJ_ARROW | Objeto "Flecha" | No repinta | |
OBJ_TEXT | Objeto "Texto" | No repinta | |
OBJ_LABEL | Objeto "Etiqueta de texto" | No repinta | |
OBJ_BUTTON | Objeto "Botón" | No repinta | |
OBJ_CHART | Objeto "Gráfico" | No repinta | |
OBJ_BITMAP | Objeto "Dibujo" | No repinta | |
OBJ_BITMAP_LABEL | Objeto "Etiqueta gráfica" | No repinta | |
OBJ_EDIT | Objeto "Campo de edición" | No repinta | |
OBJ_EVENT | Objeto "Evento", que corresponde a un evento en el calendario económico | No repinta | |
OBJ_RECTANGLE_LABEL | Objeto "Etiqueta rectangular", para crear y componer un interfaz gráfico personalizado | No repinta |
Recuadro 1. Superposición y transparencia de objetos gráficos
Tomando como ejemplo tres objetos del tipo OBJ_RECTANGLE (rectángulo) , veremos el algoritmo para repintar en los lugares donde se cruzan los objetos que son susceptibles de ser pintados de nuevo (archivo xor.mq5).
El script (archivo xor.mq5) establece el color blanco del fondo (0xFFFFFF) y dibuja los rectángulos №1 y №2 de color azul (0x0000FF) con relleno, el rectángulo №3 se representa en color rojo (0xFF0000) con relleno.
Fig. 7. Repintado. Gráfico en el plano posterior
En el dibujo hemos obtenido dos zonas de cruce, en las cuales el color ha sido repintado:
- Zona №1 – el color resultante (0x000000) es totalmente transparente, por eso en la zona №1 se ven el fondo y el gráfico sin repintar;
- Zona №2 – color resultante (0x00FF00).
Los objetos gráficos del tipo rectágulo, al cruzarse se repintan según el algoritmo Operaciones a nivel de bits OR.
Para la fig. 6, más abajo, se da un ejemplo de repintado de colores para ambas zonas:
Representación literal | Representación de número entero | Representación binaria | Observación |
---|---|---|---|
C’0,0,255’ | 0x0000FF | 0000 0000 0000 0000 1111 1111 | Color azul |
XOR | |||
C’0,0,225’ | 0x0000FF | 0000 0000 0000 0000 1111 1111 | Color azul |
= | |||
C’0,0,0’ | 0x000000 | 0000 0000 0000 0000 0000 0000 | Transparente |
XOR | |||
C’255,255,255’ | 0xFFFFFF | 1111 1111 1111 1111 1111 1111 | Color blanco (fondo) |
= | |||
C’255,255,255’ | 0xFFFFFF | 1111 1111 1111 1111 1111 1111 | Color blanco |
Recuadro 2. Operación excluyente OR para Azul + Azul + Blanco
Representación literal | Representación de número entero | Representación binaria | Observación |
---|---|---|---|
C’0,0,255’ | 0x0000FF | 0000 0000 0000 0000 1111 1111 | Color azul |
XOR | |||
C’255,0,0’ | 0xFF0000 | 1111 1111 0000 0000 0000 0000 | Color rojo |
= | |||
С’255,0,255’ | 0xFF00FF | 1111 1111 0000 0000 1111 1111 | |
XOR | |||
C’255,255,255’ | 0xFFFFFF | 1111 1111 1111 1111 1111 1111 | Color blanco (fondo) |
= | |||
С’0,255,0’ | 0x00FF00 | 0000 0000 1111 1111 0000 0000 |
Recuadro 3. Operación excluyente OR para Azul + Rojo + Blanco
3.2. Gráfico en el primer plano
Cuando para el gráfico está activado el ajuste "Gráfico arriba", la ubicación de las capas de la ventana del gráfico se distingue de la ubicación con la cual el gráfico se encuentra en plano posterior:
Fig. 8. Esquema de la ventana del gráfico. Gráfico arriba
Cuando está activado para el gráfico el ajuste "Gráfico arriba", las dos capas para dibujar el "Primer plano" y el "Plano posterior" se unen en una capa común. Esta capa común se encuentra abajo del todo, debajo de las capas con la barra y la retícula.
3.3. Repintar para el "Gráfico arriba"
Igual que para la fig. 7, veremos el algoritmo de repintado en los lugares de cruce de los objetos que se repintan (archivo xor.mq5).
El script (archivo xor.mq5) establece el color blanco del fondo (0xFFFFFF) y dibuja los rectángulos №1 y №2 de color azul (0x0000FF) con relleno, el rectángulo №3 se dibuja en color rojo (0xFF0000) con relleno.
Fig. 9. Repintado. Gráfico en el primer plano
Si comparamos la fig. 7 y la fig. 9, entonces se nota que las zonas de cruce se repintan igual.
4. Mezcla de colores. Color resultante
Como ya he dicho más arriba, la imagen de transparencia en la pantalla del monitor es una ilusión. Juego de colores. Para modelar la fig. 2 en el monitor queda aún aclararse un poquito, pero, ¿cómo representar propiamente el color con transparencia en el monitor? Es decir, ¿cómo calcular el color resultante del píxel?
Aunque sea en un fondo blanco (es el fondo del gráfico en el esquema de color "Black On White") queremos dibujar en el canvas color rojo con un canal alfa igual a 128. En el formato ARGB, este color tendrá la anotación 0x80FF0000. Para calcular el color resultante, hay que calcular el color de cada uno de los canales (Red, Green, Blue).
La fórmula de cálculo del color resultante al solaparse el color con el canal alfa, se normaliza hasta la unidad:
donde:
- result - es el valor resultante de la intensidad del canal de color. Si el valor obtenido es superior a 255, entonces se retorna 255.
- background - valor del canal de color de fondo.
- foreground - el valor del canal de color de la imagen superpuesta.
- alpha - valor del canal alfa normalizado hasta la unidad.
Calculamos el color resultante de acuerdo con la fórmula (1.3):
Canal alfa | Canal alfa, normalizado hasta "1" | R | G | B | Observación |
---|---|---|---|---|---|
255 | 255 | 255 | Color blanco | ||
128 | 0,5 | 255 | 0 | 0 | Rojo con un canal alfa 128 |
255*(1-0.5)+255*0.5=255 | 255*(1-0.5)+0*0.5=127 | 255*(1-0.5)+0*0.5=127 |
Recuadro 4. Resultados del cálculo según la fórmula (1.3)
Como resultado, en el monitor obtendremos el siguiente color:
Fig. 10. Color final
4.1. Métodos de procesamiento del color. ENUM_COLOR_FORMAT
Al crear un canvas, se puede establecer uno de los tres métodos de procesamiento del color (ENUM_COLOR_FORMAT):
Identificador | Descripción |
---|---|
COLOR_FORMAT_XRGB_NOALPHA | Ignorar el componente del canal alfa |
COLOR_FORMAT_ARGB_RAW | Los componentes de color no son procesados por el terminal (deberén ser correctamente indicados por el usuario) |
COLOR_FORMAT_ARGB_NORMALIZE | Los componentes de color son procesados por el terminal |
Recuadro 5. Métodos de procesamiento del color al crear un canvas
COLOR_FORMAT_ARGB_NORMALIZE permite obtener una imagen más bonita, gracias a que se tiene en cuenta la superposición correcta de los componentes RGB. El cálculo de color resultante al superponer un color con el canal alfa tiene lugar según la fórmula (1.3).
COLOR_FORMAT_ARGB_RAW no efectúa control alguno sobre la sobrecarga de los componentes RGB de los colores, y por eso COLOR_FORMAT_ARGB_RAW es un método más rápido en comparación con COLOR_FORMAT_ARGB_NORMALIZE.
Fórmula de cálculo del color resultante al superponer un color con el canal alfa normalizado hasta la unidad, para el método COLOR_FORMAT_ARGB_RAW:
donde:
- result - es el valor resultante de la intensidad del canal de color. Si el valor obtenido es superior a 255, entonces se retorna 255.
- background - valor del canal de color de fondo.
- foreground - el valor del canal de color de la imagen superpuesta.
- alpha - valor del canal alfa normalizado hasta la unidad.
5. Ilusión de transparencia
Ahora podemos proceder a la implementación práctica de la transparencia.
Dibujamos en el gráfico varios rectángulos con relleno (script "xor.mq5"). Para que la diferencia entre los métodos de procesamiento de color sea más palpable, por encima del gráfico superponemos en horizontal tres canvas sin que se cubran mútuamente.
El primero tiene el método de procesamiento COLOR_FORMAT_XRGB_NOALPHA, el segundo, COLOR_FORMAT_ARGB_RAW, y el tercero, COLOR_FORMAT_ARGB_NORMALIZE. A continuación, cambiamos paulatinamente la transparencia de 255 (opacidad total) a 0 (transparencia total). Llamaremos a nuestro script "Illusion.mq5".
Vídeo del funcionamiento del script "Illusion.mq5":
Fig. 11. Funcionamiento del script illusion.mq5
5.1. Crear el script "Illusion.mq5"
Los fragmentos de código añadidos o modificados serán destacados con colores.
Plantilla del script vacía, por el momento:
//+------------------------------------------------------------------+ //| Illusion.mq5 | //| Copyright © 2015, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2015, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #property version "1.0" //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- }
Añadimos la descripción del script, la posibilidad de agregar parámetros al inciar el script y conectamos la clase CCanvas, la clase gracias a la cual, precisamente, vamos a dibujar:
#property version "1.0" #property description "The illusion of transparency" //--- show the window of input parameters when launching the script #property script_show_inputs #include <Canvas\Canvas.mqh>
Para que funcione el script, serán necesarios ciertas variables, la de altura y anchura del gráfico, altura y anchura del canvas, así como las variables auxiliares para dibujar las coordenadas del canvas:
#include <Canvas\Canvas.mqh> //+------------------------------------------------------------------+ //| inputs | //+------------------------------------------------------------------+ input color colr=clrRed; input color clr_Circle=clrBlue; //--- variable width and height of the chart. int ChartWidth=-1; int ChartHeight=-1; //--- uchar alpha=0; //alpha channel managing color transparency int can_width,can_height; //width and height of the canvas int can_x1,can_y1,can_x2,can_y2,can_y3,can_x3; //coordinatesPara obtener la anchura y altura del gráfico, utilizaremos las funciones estándar:
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- } //+------------------------------------------------------------------+ //| Chart property width | //+------------------------------------------------------------------+ int ChartWidthInPixels(const long chart_ID=0) { //--- prepare the variable to get the property value long result=-1; //--- reset the error value ResetLastError(); //--- receive the property value if(!ChartGetInteger(chart_ID,CHART_WIDTH_IN_PIXELS,0,result)) { //--- display the error message in Experts journal Print(__FUNCTION__+", Error Code = ",GetLastError()); } //--- return the value of the chart property return((int)result); } //+------------------------------------------------------------------+ //| Chart property height | //+------------------------------------------------------------------+ int ChartHeightInPixelsGet(const long chart_ID=0,const int sub_window=0) { //--- prepare the variable to get the property value long result=-1; //--- reset the error value ResetLastError(); //--- receive the property value if(!ChartGetInteger(chart_ID,CHART_HEIGHT_IN_PIXELS,sub_window,result)) { //--- display the error message in Experts journal Print(__FUNCTION__+", Error Code = ",GetLastError()); } //--- return the value of the chart property return((int)result); }
Pasemos directamente a OnStart().
Para que se vea mejor, en la fig. 12 se muestra el esquema de ubicación de los canvas en el gráfico, así como la designación de las variables auxiliares para las coordenadas del canvas:
Fig. 12. Coordenadas en el gráfico
Obtenemos la altura y anchura del gráfico, y asimismo calculamos las variables auxiliares para las coordenadas del canvas:
void OnStart() { //--- width and height of the chart ChartWidth=ChartWidthInPixels(); ChartHeight=ChartHeightInPixelsGet()-50; //--- can_width=ChartWidth/3; can_height=ChartHeight; can_x1=0; can_y1=0; can_x2=can_width; can_y2=0; can_x3=can_width*2; can_y3=0; }
Una vez tenemos calculadas la altura y anchura del canvas, así como las variables auxiliares, podemos proceder a dibujar.
A continuación, cambiamos el tipo void de la función OnStart() a int, y dibujamos en el primer canvas un rectángulo coloreado, el texto con el nombre del método de procesamiento del color en este canvas y el entorno coloreado:
int OnStart() { //--- width and height of the chart ChartWidth=ChartWidthInPixels(); ChartHeight=ChartHeightInPixelsGet()-50; //--- can_width=ChartWidth/3; can_height=ChartHeight; can_x1=0; can_y1=0; can_x2=can_width; can_y2=0; can_x3=can_width*2; can_y3=0; //--- create canvas COLOR_FORMAT_XRGB_NOALPHA CCanvas canvas_XRGB_NOALPHA,canvas_ARGB_RAW,canvas_XARGB_NORMALIZE; if(!canvas_XRGB_NOALPHA.CreateBitmapLabel("canvas_XRGB_NOALPHA",can_x1,can_y1,can_width-1,can_height,COLOR_FORMAT_XRGB_NOALPHA)) { Print("Error creating canvas: ",GetLastError()); return(-1); } canvas_XRGB_NOALPHA.Erase(ColorToARGB(colr,alpha)); canvas_XRGB_NOALPHA.TextOut((can_width)/2,can_height/2,"canvas_XRGB_NOALPHA",ColorToARGB(clrBlue,255),TA_CENTER|TA_VCENTER); canvas_XRGB_NOALPHA.FillCircle((can_width)/2,can_height/2+50,25,ColorToARGB(clr_Circle,255)); canvas_XRGB_NOALPHA.Update(); return(0); }
Voy a detenerme con más detalle en el último código pegado.
canvas_XRGB_NOALPHA.CreateBitmapLabel("canvas_XRGB_NOALPHA",can_x1,can_y1,can_width-1,can_height,COLOR_FORMAT_XRGB_NOALPHA)
canvas_XRGB_NOALPHA.CreateBitmapLabel - Aquí hemos creado un recurso gráfico enlazado a un objeto del gráfico.
El primer canvas ha sido creado con el modo de procesamiento COLOR_FORMAT_XRGB_NOALPHA, los componentes del canal alfa al dibujar serán ignorados.
canvas_XRGB_NOALPHA.Erase(ColorToARGB(colr,alpha));
Rellenamos el canvas por completo con color en fomato ARGB con transparencia alpha.
Dado que para este canvas se ha establecido el modo de procesamiento de imágenes COLOR_FORMAT_XRGB_NOALPHA, el canvas será rellenado de color sin tener en cuenta el canal alfa.
canvas_XRGB_NOALPHA.TextOut((can_width)/2,can_height/2,"canvas_XRGB_NOALPHA",ColorToARGB(clrBlue,255),TA_CENTER|TA_VCENTER);
Mostramos el texto el tipo de porcesamiento de la imagen para este canvas. El color del texto en formato ARGB y el canal alfa es igual a 255, es decir, el color del texto mostrado es totalmente opaco.
El texto mostrado se enlaza tanto en horizontal (TA_CENTER) como en vertical (TA_VCENTER), según el centro del rectángulo que delimita.
canvas_XRGB_NOALPHA.FillCircle((can_width)/2,can_height/2+50,25,ColorToARGB(clr_Circle,255));
Dibujamos un círculo coloreado. El círculo se dibujará por encima del color con el que hemos rellenado el canvas (canvas_XRGB_NOALPHA.Erase(ColorToARGB(colr,alpha));).
Esto se hace para demostrar que la figura dibujada en el canvas (o la zona/punto) borra por completo el dibujo que yace bajo él en el canvas. Es decir, no habrá ningún repintado en el canvas, ya que la última muestra del dibujo borra por completo la zona debajo de ella.
canvas_XRGB_NOALPHA.Update();
Si queremos que todo lo dibujado se represente en la pantalla, hay que refrescar de nuevo la pantalla.
De forma análoga se dibujan los dos canvas restantes: el segundo con el modo de representación COLOR_FORMAT_ARGB_RAW, y el tercer canvas, con el modo de representación COLOR_FORMAT_ARGB_NORMALIZE:
canvas_XRGB_NOALPHA.Update(); //--- create canvas COLOR_FORMAT_ARGB_RAW if(!canvas_ARGB_RAW.CreateBitmapLabel("canvas_ARGB_RAW",can_x2,can_y2,can_width-1,can_height,COLOR_FORMAT_ARGB_RAW)) { Print("Error creating canvas: ",GetLastError()); return(-1); } canvas_ARGB_RAW.Erase(ColorToARGB(colr,alpha)); //clrNONE,0)); canvas_ARGB_RAW.TextOut((can_width)/2,can_height/2,"canvas_ARGB_RAW",ColorToARGB(clrBlue,255),TA_CENTER|TA_VCENTER); canvas_ARGB_RAW.FillCircle((can_width)/2,can_height/2+50,25,ColorToARGB(clr_Circle,255)); canvas_ARGB_RAW.Update(); //--- create canvas COLOR_FORMAT_ARGB_NORMALIZE if(!canvas_XARGB_NORMALIZE.CreateBitmapLabel("canvas_XARGB_NORMALIZE",can_x3,can_y3,can_width-1,can_height,COLOR_FORMAT_ARGB_NORMALIZE)) { Print("Error creating canvas: ",GetLastError()); return(-1); } canvas_XARGB_NORMALIZE.Erase(ColorToARGB(colr,alpha)); canvas_XARGB_NORMALIZE.TextOut((can_width)/2,can_height/2,"canvas_XARGB_NORMALIZE",ColorToARGB(clrBlue,255),TA_CENTER|TA_VCENTER); canvas_XARGB_NORMALIZE.FillCircle((can_width)/2,can_height/2+50,25,ColorToARGB(clr_Circle,255)); canvas_XARGB_NORMALIZE.Update(); return(0); }
Los canvas y gráficos dentro del canvas ya han sido dibujados.
Ahora vamos a hacer un ciclo en el que se cambiará la transparencia de todo el canvas:
canvas_XARGB_NORMALIZE.FillCircle((can_width)/2,can_height/2+50,25,ColorToARGB(clr_Circle,255)); canvas_XARGB_NORMALIZE.Update(); //--- transparent from 255 to 0 uchar transparent; for(transparent=255;transparent>0;transparent--) { canvas_XRGB_NOALPHA.TransparentLevelSet(transparent); canvas_XRGB_NOALPHA.Update(); canvas_ARGB_RAW.TransparentLevelSet(transparent); canvas_ARGB_RAW.Update(); canvas_XARGB_NORMALIZE.TransparentLevelSet(transparent); canvas_XARGB_NORMALIZE.Update(); Sleep(50); } canvas_XRGB_NOALPHA.TransparentLevelSet(transparent); canvas_XRGB_NOALPHA.Update(); canvas_ARGB_RAW.TransparentLevelSet(transparent); canvas_ARGB_RAW.Update(); canvas_XARGB_NORMALIZE.TransparentLevelSet(transparent); canvas_XARGB_NORMALIZE.Update(); Sleep(6000); return(0); }
El cambio de transparencia para todo el canvas se efectúa con la ayuda de líneas de tipo:
.TransparentLevelSet(transparent)
Después de terminar de dibujar, hay que ordenar un poco, es decir, eliminar los recursos gráficos.
Dado que hemos creado un recurso gráfico enlazado a un objeto del gráfico (método CreateBitmapLabel), entonces eliminaremos el recurso con ayuda del método Destroy(), y de paso se eliminará también el objeto del gráfico (Bitmap Label):
canvas_XARGB_NORMALIZE.Update(); Sleep(6000); //--- finish canvas_XRGB_NOALPHA.Destroy(); canvas_ARGB_RAW.Destroy(); canvas_XARGB_NORMALIZE.Destroy(); return(0); }
El script, que cambia suavemente de transpariencia, funciona.
Hago notar que la diferencia entre los modos de representación COLOR_FORMAT_ARGB_RAW y COLOR_FORMAT_ARGB_NORMALIZE se nota especialmente bien si el script se inicia al principio sobre el fondo blanco del gráfico, y después sobre el fondo negro.
Conclusión
En el artículo se han estudiado las bases del trabajo con los colores, y nos hemos familiarizado con cómo dibujar en la ventana del gráfico. Asimismo, hemos estudiado las bases del trabajo con la clase CCanvas de la Biblioteca Estándar, y nos hemos familiarizado con el formato de representación del color con transparencia ARGB.
Esto es solo el comienzo del camino hacia la creación de efectos realmente bonitos para los objetos gráficos en el terminal MetaTrader 5. Quiero detenerme de nuevo en la transparencia: es precisamente la transparencia parcial lo que transmite una forma bonita a los bordes de los objetos gráficos. Debido a que los monitores son bidimensionales, la transparencia en el gráfico es una ilusión conseguida mediante el procesamiento del píxel superpuesto.
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/1341





- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso