Descargar MetaTrader 5

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

14 septiembre 2015, 09:37
Vladimir Karputov
0
345

Í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 vertical_line  Línea vertical  No repinta
 OBJ_HLINE horizonal_line  Línea horizontal No repinta
 OBJ_TREND  trend_line  Línea de tendencia No repinta
 OBJ_TRENDBYANGLE trend_line)by_angle   Línea de tendencia por ángulo  No repinta
 OBJ_CYCLES  cycle_lines  Líneas cíclicas No repinta
 OBJ_ARROWED_LINE  arrowed_line  Objeto "Línea con flecha" No repinta
 OBJ_CHANNEL  equidistance_channel  Canal equidistante No repinta
 OBJ_STDDEVCHANNEL  stddeviation_channel  Canal de desviación estándar  No repinta
 OBJ_REGRESSION  regression_channel  Canal de regresión lineal. No repinta
 OBJ_PITCHFORK  andrewspitchfork  Tridente Andrews No repinta
 OBJ_GANNLINE  gann_line  Línea de Gann No repinta
 OBJ_GANNFAN  gann_fan  Abanico de Gann No repinta
 OBJ_GANNGRID  gann_grid  Retícula de Gann No repinta
 OBJ_FIBO  fibonacci_levels  Retrocesos de Fibonacci No repinta
 OBJ_FIBOTIMES  fibonacci_time_zones   Zonas temporales de Fibonacci No repinta
 OBJ_FIBOFAN  fibo_fan  Abanico de Fibonacci No repinta
 OBJ_FIBOARC fibo_arc  Arcos de Fibonacci No repinta
 OBJ_FIBOCHANNEL  fibo_channel  Canal de Fibonacci No repinta
 OBJ_EXPANSION  fibo_expansion  Expansiones de Fibonacci No repinta
 OBJ_ELLIOTWAVE5  elliot_impuls  Onda de impulso de Elliott No repinta
 OBJ_ELLIOTWAVE3  elliot_correction  Onda correctiva de Elliott. No repinta
 OBJ_RECTANGLE  rectangle  Rectángulo Sin relleno, no repinta,
Con relleno, repinta
 OBJ_TRIANGLE  triangle  Triángulo Sin relleno, no repinta,
Con relleno, repinta
 OBJ_ELLIPSE  ellipse  Elipse Sin relleno, no repinta,
Con relleno, repinta
 OBJ_ARROW_THUMB_UP  THUMB_UP  Signo "Bien" (pulgar hacia arriba) No repinta
 OBJ_ARROW_THUMB_DOWN  THUMB_DOWN  Signo "Mal" (pulgar hacia abajo) No repinta
 OBJ_ARROW_UP  arrow_up  Signo "Flecha hacia arriba" No repinta
 OBJ_ARROW_DOWN  arrow_down  Signo "Flecha hacia abajo" No repinta
 OBJ_ARROW_STOP  stop_signal  Signo "Stop" No repinta
 OBJ_ARROW_CHECK  check_signal  Signo "Palomita" (visto) No repinta
 OBJ_ARROW_LEFT_PRICE  left_price_label  Etiqueta izquierda de precio No repinta
 OBJ_ARROW_RIGHT_PRICE right_price_label   Etiqueta derecha de precio No repinta
 OBJ_ARROW_BUY  buy_sign_icon  Signo "Buy" No repinta
 OBJ_ARROW_SELL sell_sign_icon   Signo "Sell" No repinta
 OBJ_ARROW  arrow_symbol  Objeto "Flecha" No repinta
 OBJ_TEXT text_object   Objeto "Texto" No repinta
 OBJ_LABEL  label_object  Objeto "Etiqueta de texto" No repinta
 OBJ_BUTTON  button_object  Objeto "Botón" No repinta
 OBJ_CHART chart_object   Objeto "Gráfico" No repinta
 OBJ_BITMAP  picture_object  Objeto "Dibujo" No repinta
 OBJ_BITMAP_LABEL  bitmap_object  Objeto "Etiqueta gráfica" No repinta
 OBJ_EDIT  edit_object  Objeto "Campo de edición" No repinta
 OBJ_EVENT  obj_event  Objeto "Evento", que corresponde a un evento en el calendario económico No repinta
 OBJ_RECTANGLE_LABEL  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 Software Corp.
Artículo original: https://www.mql5.com/ru/articles/1341

Archivos adjuntos |
xor.mq5 (6.99 KB)
Illusion.mq5 (5.88 KB)
Crear aplicación interactiva para visualizar los canales RSS en MetaTrader 5 Crear aplicación interactiva para visualizar los canales RSS en MetaTrader 5

En este artículo se describe cómo crear la aplicación que visualiza los canales RSS. Además, hablaremos sobre los aspectos del uso de la Biblioteca estándar durante la creación de los programas interactivos en MetaTrader 5.

Líneas de tendencia basadas en los fractales usando MQL4 y MQL5 Líneas de tendencia basadas en los fractales usando MQL4 y MQL5

En este artículo se describe la solución de automatización del proceso de la construcción de las líneas de tendencia a base del indicador Fractals usando MQL4 y MQL5. La estructura del artículo está representada como la comparación en el marco de la solución del problema planteado desde las posiciones de dos lenguajes. La construcción de las líneas de tendencia se realiza usando dos últimos fractales conocidos.

Introducción a la teoría de la Lógica difusa Introducción a la teoría de la Lógica difusa

La lógica difusa extiende los límites habituales de la lógica matemática y teoría de conjuntos. En este artículo se muestran principales principios de esta teoría, así como se describen dos sistemas de inferencia lógica difusa tipo Mamdani y Sugeno. Se dan los ejemplos de implementación de los modelos difusos a base de estos dos sistemas usando los medios de la biblioteca FuzzyNet para MQL5.

Recetas MQL5 - órdenes ОСО Recetas MQL5 - órdenes ОСО

En el comercio, el trader usa diferentes mecanismos e interacciones, también entre órdenes. En este artículo se propone una solución para procesar las órdenes OCO. Además, implica las clases de la Biblioteca Estándar, y también se crean los nuevos tipos de datos.