English Русский 中文 Deutsch 日本語 Português 한국어 Français Italiano Türkçe
Estudiamos la clase CCanvas. Implementación de la transparencia de los objetos gráficos

Estudiamos la clase CCanvas. Implementación de la transparencia de los objetos gráficos

MetaTrader 5Ejemplos | 14 septiembre 2015, 09:37
1 175 0
Vladimir Karputov
Vladimir Karputov

Índice


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

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

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. ARGB

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:

fórmula 1.1

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:

fórmula 1.2

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

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

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

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

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:

  1. 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;
  2. 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

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

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:

fórmula 1.3

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

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:

fórmula 1.4

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;   //coordinates

Para 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

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

Archivos adjuntos |
xor.mq5 (6.99 KB)
Illusion.mq5 (5.88 KB)
Sistema de Trading Mecánico "Horquilla de Chuvashov" Sistema de Trading Mecánico "Horquilla de Chuvashov"
Este artículo señala el breve informe sobre el código de método y programa del sistema mecánico de trading basado en la técnica propuesta por Stanislav Chuvashov. El análisis de mercado considerado en el artículo tiene algo en común con el enfoque de Thomas DeMark para dibujar líneas de tendencia en el último intervalo de tiempo más cercano, Fractales, siendo los puntos de referencia en la construcción de líneas de tendencia.
Análisis fractal de los movimientos de la moneda común Análisis fractal de los movimientos de la moneda común
¿Cómo de independientes son las cotizaciones de la moneda? ¿Son sus movimientos coordinados o ningún movimiento de una de las monedas sugiere el movimiento de la otra? El artículo describe un intento de abordar esta cuestión mediante la dinámica no lineal y los métodos de geometría fractal.
Barras sintéticas - una nueva dimensión de la visualización de información gráfica de los precios Barras sintéticas - una nueva dimensión de la visualización de información gráfica de los precios
El principal inconveniente de los métodos tradicionales para la visualización de información de precios usando barras y velas japonesas es que están limitados al período de tiempo. Tal vez fue óptima en el momento que se crearon estos métodos pero hoy cuando los movimientos del mercado son a veces demasiado rápidos, los precios que se muestran en un gráfico de esta manera no contribuyen a una pronta respuesta al nuevo movimiento. El método de visualización gráfico del precio propuesto no tiene este inconveniente y ofrece un diseño bastante familiar.
Sobre los Métodos de Análisis Técnico y Pronósticos de Mercado Sobre los Métodos de Análisis Técnico y Pronósticos de Mercado
El artículo muestra las capacidades y el potencial de un método matemático bien conocido juntado con el pensamiento visual y una perspectiva del mercado "fuera de caja". Por un lado, sirve para atraer la atención de un público más amplio ya que puede hacer que las mentes creativas reconsideren el paradigma del traqading como tal. Y por otro lado, puede dar lugar a desarrollos alternativos i implementaciones de código de programa con respecto a una amplia gama de herramientas para el análisis y predicción.