Die Betrachtung der CCanvas-Klasse. Wie man transparente Objekte zeichnet
Inhaltsangaben
- Einleitung
- 1 Transparenz (Alpha-Kanal)
- 2 ARGB-Farbwiedergabe
- 3 Schema der Objektzeichnung im Terminal
- 4 Farben mischen - Entstehende Farbe
- 5 Die Illusion der Transparenz
- Fazit
Einleitung
In MetaTrader 5 zu zeichnen, geht ganz einfach. Sie müssen dazu nur ein paar Feinheiten wissen. Eine davon hängt damit zusammen, wie der Terminalbildschirm angelegt ist. Genauer gesagt, sind wir daran interessiert, wie Grafiken auf diesem Bildschirm ausgegeben werden. So kann z.B. ein Chart im Vorder- oder im Hintergrund angezeigt werden. Die Farbwiedergabe auf dem Bildschirm hängt dann von der Anzeige des Charts ab. Einige grafische Objekte können ihre Farbe in überlappenden oder kreuzenden Bereich verändern.
Bevor wir uns direkt mit dem Zeichnen unter Verwendung der CCanvas-Klasse beschäftigen, sehen wir uns zunächst einige Definitionen im Zusammenhang mit Farbbearbeitung genauer an. Wir wollen z.B. herausfinden, was der Alpha-Kanal für eine Bedeutung hat.
Meiner Meinung nach ist die Implementierung von Transparenz die wichtigste Technologie, denn durch Farben wird jedes Bild erst richtig lebendig. So kann Transparenz z.B. zur Umsetzung einer attraktiveren Schnittstelle mit glatten Farbübergängen oder Schattierungen verwendet werden. Schattierungen oder Schatten geben einem Grafikobjekt mehr Dimension und glätten die Objektkanten für den Betrachter.
1 Transparenz (Alpha-Kanal)
Wir leben in einer dreidimensionalen Welt und nehmen alles um uns herum dreidimensional wahr. Diese Dreidimensionalität haben wir sogar mal tatsächlich gesehen oder gefühlt. In der dreidimensionalen Welt erkennen und verstehen wir, welches Objekt näher an uns dran ist.
Einige Objekte sind durchsichtig, z.B. ein klares Glas mit einer durchsichtige Flüssigkeit vor blauem Hintergrund. Der blaue Hintergrund ist durch das Glas samt seiner Flüssigkeit erkennbar, wobei seine Details vom Grad der Durchsichtigkeit oder Transparenz abhängen.
Abb. 1 Allgemeine Sichtweise der Dimensionalität
In diesem Beispiel ist die Transparenz nicht virtuell und auch nicht illusionär. Transparenz wird in diesem Fall als etwas ganz Normales, Selbstverständliches angesehen.
Doch wird ein Bild auf einem Computermonitor angezeigt, sieht alles komplett anders aus: Die Pixel-Matrix ist zweidimensional, d.h. das von der Matrix gezeigte Bild hat eine Höhe und eine Breite, jedoch fehlt im die dritte Dimension - seine Tiefe. Es ist daher nicht möglich, ein Pixel über ein anderes zu platzieren und die Situation zu simulieren, das untere Pixel wäre ein gelber Hintergrund und das obere Pixel eben ein durchsichtiges Glas. Jedes Bild eines dreidimensionalen und realistischen Objekts auf dem Computerbildschirm ist eine Illusion, die man durch den Einsatz von Farbe und Schatten erzeugt.
Als Beispiel kann ein Bild so betrachtet werden, dass es in zwei Schichten aufgeteilt werden kann: die untere Schicht - ein blauer Hintergrund, und die obere Schicht - ein Glas mit einer undurchsichtigen Flüssigkeit. Auf dem Bildschirm sieht das dann so aus:
Abb. 2 Undurchsichtiges Glas
Auf dem entstandenen Bild ist das Glas komplett undurchsichtig. Um Transparenz hinzuzufügen (oder zu verändern), müssen wir alle Farben des Bildes in die ARGB-Farbwiedergabe übersetzen.
2 ARGB-Farbwiedergabe
Keine Angst, ich habe die Transparenz des Glases nicht vergessen. Dazu kommen wir aber erst im zweiten Teil dieses Beitrags.
Die ARGB-Farbwiedergabe ist ein uint Type aus vier Bytes, in dem die folgenden Werte aufgezeichnet werden: ein Alpha-Kanal, Rot, Grün und Blau. Um also der Farbe im RGB-Format Transparenz zu verleihen, wird ein extra Byte mit dem Wert 'Transparenz' hinzugefügt - nämlich der sog. Alpha-Kanal.
Abb. 3 ARGB
Der Wert eines Alpha-Kanals wird von 0 (die Farbe eines Vordergrund-Pixels ändert die Anzeige eines darunter liegenden nicht) bis 255 (die Farbe eines darunter liegenden Pixels wird komplett durch die Farbe des Vordergrund-Pixels ersetzt) eingestellt. Die Farbtransparenz wird in Prozentwerten folgendermaßen berechnet:
Mit anderen Worten: je kleiner der Wert des Alpha-Kanals ist, umso transparenter wird die Farbe. Wenn wir die gewünschte Transparenz kennen, kann der Alpha-Wert folgendermaßen berechnet werden:
Die Umwandlung von Farbe in ARGB erfolgt mit Hilfe der ColorToARGB-Funktion (Farbe, alpha).
3 Schema der Objektzeichnung im Terminal
Zum besseren Verständnis, wie Farbe bearbeitet wird, betrachten wir uns das Schema der gegenseitigen Anordnung von Grafikobjekten mit zwei unterschiedlich eingerichteten Charts - eins im Hintergrund und eins im Vordergrund.
3.1 Chart im Hintergrund
Für diese Option, auf das Chart klicken und dann aus dem Dropdown-Menü "Eigenschaften..." auswählen und zur Registerkarte "Allgemein" gehen.
Abb. 4 Chart im Hintergrund
Ein Chartfenster im Terminal besteht aus vier Schichten. Auf den zwei extremen Schichten ("Hintergrund" und "Vordergrund") kann gezeichnet werden:
Abb. 5 Schema des Chartfensters
Im Hintergrund, sowie auch im Vordergrund, wird ein gezeichnetes Objekt durch ein anderes in Übereinstimmung mit den Zeiten ihrer Zeichnung überlagert.
Das bedeutet: das älteste Objekte befindet sich ganz weit hinten, auf der hintersten Schicht des "Hintergrunds" und auf der hintersten Schicht des "Vordergrunds". Jüngere Objekte erscheinen weiter vorne.
Abb. 6 Position von Objekten nach Zeit ihrer Zeichnung
Nicht alle Objekte können sich, ohne Neuzeichnung der zugrunde liegenden Grafikobjekten in dem Feld (oder Feldern) wo sie überlappen, komplett überlappen .
Die Tabelle fasst die Charakteristika der Grafikobjekte zusammen, gefolgt von einer Erklärung der Überlappung der Objekte, die in den überlappenden Bereichen neu gezeichnet werden müssen.
ID | Objekt | Beschreibung | Überlappung mit einem darunter liegenden Objekt |
---|---|---|---|
OBJ_VLINE | Senkrechte Linie | Keine Neuzeichnung | |
OBJ_HLINE | Waagrechte Linie | Keine Neuzeichnung | |
OBJ_TREND | Trendlinie | Keine Neuzeichnung | |
OBJ_TRENDBYANGLE | Trendlinie nach Winkel | Keine Neuzeichnung | |
OBJ_CYCLES | Kreislinien | Keine Neuzeichnung | |
OBJ_ARROWED_LINE | Bepfeilte Linie | Keine Neuzeichnung | |
OBJ_CHANNEL | Abstandsgleicher Kanal | Keine Neuzeichnung | |
OBJ_STDDEVCHANNEL | Standardabweichungskanal | Keine Neuzeichnung | |
OBJ_REGRESSION | Linearer Regressionskanal | Keine Neuzeichnung | |
OBJ_PITCHFORK | Andrews’ Pitchfork | Keine Neuzeichnung | |
OBJ_GANNLINE | Gann-Line | Keine Neuzeichnung | |
OBJ_GANNFAN | Gann-Fächer | Keine Neuzeichnung | |
OBJ_GANNGRID | Gann-Raster | Keine Neuzeichnung | |
OBJ_FIBO | Fibonacci-Retracement | Keine Neuzeichnung | |
OBJ_FIBOTIMES | Fibonacci-Zeitzonen | Keine Neuzeichnung | |
OBJ_FIBOFAN | Fibonacci-Fächer | Keine Neuzeichnung | |
OBJ_FIBOARC | Fibonacci-Bögen | Keine Neuzeichnung | |
OBJ_FIBOCHANNEL | Fibonacci-Kanal | Keine Neuzeichnung | |
OBJ_EXPANSION | Fibonacci-Expansion | Keine Neuzeichnung | |
OBJ_ELLIOTWAVE5 | Elliott Waves - 5 | Keine Neuzeichnung | |
OBJ_ELLIOTWAVE3 | Elliott Waves - 3 | Keine Neuzeichnung | |
OBJ_RECTANGLE | Rechteck | Keine Neuzeichnung, wenn ohne Füllung; bei Füllung Neuzeichnung | |
OBJ_TRIANGLE | Dreieck | Keine Neuzeichnung, wenn ohne Füllung; bei Füllung Neuzeichnung | |
OBJ_ELLIPSE | Ellipse | Keine Neuzeichnung, wenn ohne Füllung; bei Füllung Neuzeichnung | |
OBJ_ARROW_THUMB_UP | Daumen hoch | Keine Neuzeichnung | |
OBJ_ARROW_THUMB_DOWN | Daumen nach unten | Keine Neuzeichnung | |
OBJ_ARROW_UP | Pfeil nach oben | Keine Neuzeichnung | |
OBJ_ARROW_DOWN | Pfeil nach unten | Keine Neuzeichnung | |
OBJ_ARROW_STOP | Stopp | Keine Neuzeichnung | |
OBJ_ARROW_CHECK | Häkchen | Keine Neuzeichnung | |
OBJ_ARROW_LEFT_PRICE | Linke Kurskennzeichnung | Keine Neuzeichnung | |
OBJ_ARROW_RIGHT_PRICE | Rechte Kurskennzeichnung | Keine Neuzeichnung | |
OBJ_ARROW_BUY | Kaufen-Markierung | Keine Neuzeichnung | |
OBJ_ARROW_SELL | Verkaufen-Markierung | Keine Neuzeichnung | |
OBJ_ARROW | Pfeilobjekt | Keine Neuzeichnung | |
OBJ_TEXT | Textobjekt | Keine Neuzeichnung | |
OBJ_LABEL | Textbeschriftungsobjekt | Keine Neuzeichnung | |
OBJ_BUTTON | Schaltflächenobjekt | Keine Neuzeichnung | |
OBJ_CHART | Chartobjekt | Keine Neuzeichnung | |
OBJ_BITMAP | Bitmap-Objekt | Keine Neuzeichnung | |
OBJ_BITMAP_LABEL | Bitmap-Label-Objekt | Keine Neuzeichnung | |
OBJ_EDIT | Bearbeitungsobjekt | Keine Neuzeichnung | |
OBJ_EVENT | Das Ereignis-Objekt, das zu einem Ereignis im Wirtschaftskalender passt | Keine Neuzeichnung | |
OBJ_RECTANGLE_LABEL | Das Rechteck-Kennzeichnungsobjekt, mit dem die individuell angepasste Grafikschnittstelle erzeugt und designed wurde | Keine Neuzeichnung |
Tabelle 1 Überlagerung und Transparenz von Grafikobjekten
Sehen wir uns das Beispiel von drei Objekten des Typs OBJ_RECTANGLE (Rechtecke) an und besprechen den Algorithmus zur Neuzeichnung in den Überlappungsbereichen der Objekte, die neu gezeichnet werden sollten (xor.mq5 Datei).
Das Script (xor.mq5 Datei) richtet die weiße Hintergrundfarbe ein (0xFFFFFF) und zeichnet die gefüllten Rechtecke Nr. 1 und Nr. 2 in Blau (0x0000FF), Rechteck Nr. 3 ist Rot (0xFF0000) und gefüllt.
Abb. 7 Neuzeichnung. Chart im Hintergrund
Wir haben zwei Kreuzungsbereiche, in denen sich die Farbe veränderte:
- Bereich Nr. 1 – die entstandene Farbe (0x000000) ist komplett transparent, sodass wir im Bereich Nr. 1 den Hintergrund und das Chart unverändert sehen können;
- Bereich Nr. 2 – die entstandene Farbe (0x00FF00).
Wenn sich Grafikobjekte wie z.B. Rechtecke überlappen, werden sie vom Algorithmus des Bitwise OR neu gezeichnet.
Abb. 6 unten zeigt ein Beispiel der Neuzeichnung von Farben für beide Bereiche:
Buchstäbliche Darstellung | Ganzzahlige Darstellung | Binäre Darstellung | Anmerkung |
---|---|---|---|
C’0,0,255’ | 0x0000FF | 0000 0000 0000 0000 1111 1111 | Blau |
XOR | |||
C’0,0,225’ | 0x0000FF | 0000 0000 0000 0000 1111 1111 | Blau |
= | |||
C’0,0,0’ | 0x000000 | 0000 0000 0000 0000 0000 0000 | Transparent |
XOR | |||
C’255,255,255’ | 0xFFFFFF | 1111 1111 1111 1111 1111 1111 | Weiß (Hintergrund) |
= | |||
C’255,255,255’ | 0xFFFFFF | 1111 1111 1111 1111 1111 1111 | Weiß |
Tabelle 2 Bitwise OR für Blau + Blau + Weiß
Buchstäbliche Darstellung | Ganzzahlige Darstellung | Binäre Darstellung | Anmerkung |
---|---|---|---|
C’0,0,255’ | 0x0000FF | 0000 0000 0000 0000 1111 1111 | Blau |
XOR | |||
C’255,0,0’ | 0xFF0000 | 1111 1111 0000 0000 0000 0000 | Rot |
= | |||
С’255,0,255’ | 0xFF00FF | 1111 1111 0000 0000 1111 1111 | |
XOR | |||
C’255,255,255’ | 0xFFFFFF | 1111 1111 1111 1111 1111 1111 | Weiß (Hintergrund) |
= | |||
С’0,255,0’ | 0x00FF00 | 1111 1111 1111 0000 0000 0000 |
Tabelle 3 Bitwise OR für Blau + Rot + Weiß
3.2 Chart im Vordergrund
Ist der Parameter 'Chart im Vordergrund' aktiviert, unterscheidet sich die Anordnung der Ebenen des Chartfensters von der des Charts im Hintergrund:
Abb. 8 Schema des Chartfensters. Chart vorne
Ist die 'Chart im Vordergrund' Option aktiviert, verschmelzen die zwei Zeichnungsebenen 'Vordergrund' und 'Hintergrund' zu einer gemeinsamen Ebene. Diese gemeinsame Ebene befindet sich unter den Ebenen mit den Balken und Rastern.
3.3 Neuzeichnung für "obersten Chart"
Wie schon in Abb. 7, betrachten wir uns nun auch den Algorithmus zur Neuzeichnung an den Überlappungen der Objekte, die neu gezeichnet sind (xor.mq5 Datei).
Das Script (xor.mq5 Datei) richtet die weiße Hintergrundfarbe ein (0xFFFFFF) und zeichnet die gefüllten Rechtecke Nr. 1 und Nr. 2 in Blau (0x0000FF), Rechteck Nr. 3 ist Rot (0xFF0000) und gefüllt.
Abb. 9 Neuzeichnung. Chart im Vordergrund
Vergleichen wir jetzt Abbildungen 7 und 9 miteinander, erkennen wir schnell, dass die sich überlappenden Bereiche gleich neu gezeichnet wurden.
4 Farben mischen - Entstehende Farbe
Wie bereits erwähnt, ist Transparenz auf dem Bildschirm eine Illusion. Farbmanipulationen. Um Abb. 2 auf dem Bildschirm zu simulieren, müssen wir nur verstehen, wie man eine Farbe mit Transparenz auf dem Bildschirm anzeigt, d.h. wir müssen die entstehende Farbe des Pixels berechnen.
Angenommen, wir wollen Rot mit Alpha-Kanal 128 auf einer Leinwand vor weißem Hintergrund zeichnen (Chart-Hintergrund im "Schwarz-auf-Weiß" Farbschema). Im ARGB-Format ist die Farbe 0x80FF0000. Zur Berechnung der entstehenden Farbe, müssen wir die Farbe jeder der Kanäle berechnen (Rot, Grün und Blau).
Und dies ist die Formel zur Berechnung der entstehenden Farbe mit einem, auf Farbe angewendeten und auf "1" normalisierten, Alpha-Kanal:
wobei:
- Ergebnis der Ergebniswert der Farbkanal-Intensität ist. Ist dieser Wert > 255, wird 255 geliefert.
- Hintergrund der Wert des Hintergrund-Farbkanals ist.
- Vordergrund der Wert des Farbkanals des überlappenden Bildes ist.
- alpha ein Alpha-Wert ist, der auf "1" normalisiert wurde.
Berechnen wir nun die entstehende Farbe gemäß der Formel (1.3):
Alpha-Kanal | Alpha-Kanal, auf "1" normalisiert | R | G | B | Anmerkung |
---|---|---|---|---|---|
255 | 255 | 255 | Weiß | ||
128 | 0,5 | 255 | 0 | 0 | Rot mit Alpha 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 |
Tabelle 4 Ergebnis der Berechnung mit Hilfe der Formel (1.3)
Die auf dem Bildschirm entstehende Farbe ist folgende:
Abb. 10 Entstehende Farbe
4.1 Methoden zur Farbbearbeitung. ENUM_COLOR_FORMAT
Bei der Erzeugung einer Leinwand kann man eine der drei Methoden zur Farbbearbeitung festlegen (ENUM_COLOR_FORMAT):
ID | Beschreibung |
---|---|
COLOR_FORMAT_XRGB_NOALPHA | Die Alpha-Komponente wird ignoriert |
COLOR_FORMAT_ARGB_RAW | Farb-Komponenten werden vom Terminal nicht verarbeitet (sie sollten vom Benutzer exakt spezifiziert werden) |
COLOR_FORMAT_ARGB_NORMALIZE | Farb-Komponenten werden vom Terminal verarbeitet |
Tabelle 5 Methoden zur Farbbearbeitung zur Leinwand-Erzeugung
Wenn man die exakte Überlagerung der RGB-Komponenten berücksichtigt, liefert COLOR_FORMAT_ARGB_NORMALIZE ein noch schöneres Bild. Die entstandene Farbe bei der Anwendung von Farbe mit einem Alpha-Kanal, wird gemäß der Formel berechnet (1.3).
COLOR_FORMAT_ARGB_RAW kontrolliert das 'Überlaufen' von RGB-Komponenten einer Farbe nicht, daher ist COLOR_FORMAT_ARGB_RAW im Vergleich zu COLOR_FORMAT_ARGB_NORMALIZE die schnellere Methode.
Hier ist die Formel zur Berechnung für die COLOR_FORMAT_ARGB_RAW Methode der entstandenen Farbe, mit einem auf die Farbe angewendeten Alpha-Kanal, der auf "1" normalisiert wurde:
wobei:
- Ergebnis der Ergebniswert der Farbkanal-Intensität ist. Ist dieser Wert > 255, wird 255 geliefert.
- Hintergrund der Wert des Hintergrund-Farbkanals ist.
- Vordergrund der Wert des Farbkanals des überlappenden Bildes ist.
- alpha ein Alpha-Wert ist, der auf "1" normalisiert wurde.
5 Die Illusion von Transparenz
Jetzt kommen wir endlich zur praktischen Implementierung von Transparenz.
Zeichnen wir also eine Anzahl gefüllter Rechtecke (Script "xor.mq5"). Zur Veranschaulichung der Unterschiede in den Methoden zur Farbbearbeitung, versuchen wir, drei sich nicht überlappende waagrechte Leinwände ganz oben auf dem Chart anzubringen.
Die erste wird mit Hilfe von COLOR_FORMAT_XRGB_NOALPHA verarbeitet, die zweite mit Hilfe von COLOR_FORMAT_ARGB_RAW, und die dritte mit Hilfe von COLOR_FORMAT_ARGB_NORMALIZE. Danach verändern wir die Transparenz schrittweise von 255 (komplett undurchsichtig) auf 0 (komplett transparent). Unser Script nennen wir der Einfachheit halber "Illusion.mq5".
Und das Video zeigt, wie "Illusion.mq5" funktioniert:
Abb. 11 So funktioniert das Script 'Illusion.mq5'
5.1 Erstellung des Scripts"Illusion.mq5"
Alle neuen oder veränderten Teile des Codes sind hervorgehoben.
Das leere Script-Template:
//+------------------------------------------------------------------+ //| 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() { //--- }
Dieses ergänzen wir mit der Script-Beschreibung, einer Option zur Eingabe von Parametern während des Starts des Scripts und verknüpfen es mit der CCanvas-Klasse, die das Zeichnen ermöglicht:
#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>
Für den Script-Ablauf brauchen wir einige Variablen - Höhe und Breite des Charts, Höhe und Breite der Leinwand sowie Hilfsvariablen zum Zeichnen der Leinwand-Koordinaten:
#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; //coordinatesDie Breite und Höhe des Charts bekommen wir mit Hilfe der Standard-Funktionen:
//+------------------------------------------------------------------+ //| 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); }
Direkt zu OnStart() gehen.
Zur besseren Übersichtlichkeit zeigt Abb. 12 das Layout der Leinwände auf dem Chart und die Hilfsvariablen für die Leinwand-Koordinaten:
Abb. 12 Koordinaten auf dem Chart
Holen wir uns nun die Höhe und Breite des Charts und berechnen die Hilfsvariablen für die Leinwand-Koordinaten:
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; }
Mit der berechneten Breite und Höhe der Leinwand und den Hilfsvariablen können wir bereits zu zeichnen beginnen.
Als nächstes ändern wir den 'leeren' Typ der OnStart() Funktion auf 'int' und zeichnen auf der ersten Leinwand ein gefülltes Rechteck, einen Text mit dem Namen der die Farbe der Leinwand bearbeitenden Methode und einen gefüllten Kreis:
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); }
Noch einige weitere Details zum zuletzt hinzugefügten Code-Teil.
canvas_XRGB_NOALPHA.CreateBitmapLabel("canvas_XRGB_NOALPHA",can_x1,can_y1,can_width-1,can_height,COLOR_FORMAT_XRGB_NOALPHA)
canvas_XRGB_NOALPHA.CreateBitmapLabel - Hier erzeugen wir eine Grafikressource, die an ein Chart-Objekt gebunden ist.
Die Farbbearbeitungsmethode bei der ersten Leinwand ist COLOR_FORMAT_XRGB_NOALPHA - die Alpha-Komponente wird ignoriert.
canvas_XRGB_NOALPHA.Erase(ColorToARGB(colr,alpha));
Füllt die gesamte Leinwand mit einer Farbe im ARGB-Format mit der Alpha-Transparenz.
Beim Füllen der Leinwand wird der Alpha-Kanal deswegen ignoriert, die hier ja die COLOR_FORMAT_XRGB_NOALPHA Methode zur Farbbearbeitung verwendet wird.
canvas_XRGB_NOALPHA.TextOut((can_width)/2,can_height/2,"canvas_XRGB_NOALPHA",ColorToARGB(clrBlue,255),TA_CENTER|TA_VCENTER);
Textausgabe - die Art der Bildverarbeitung für die Leinwand. Die Textfarbe ist im ARGB-Format und der Alpha-Kanal = 255, d.h., die Farbe des angezeigten Texts ist komplett undurchsichtig.
Der angezeigte Text ist waagrecht (TA_CENTER) und senkrecht (TA_VCENTER) zur Mitte des Rechtecks zugeschnitten.
canvas_XRGB_NOALPHA.FillCircle((can_width)/2,can_height/2+50,25,ColorToARGB(clr_Circle,255));
Zeichnung eine gefüllten Kreises. Den Kreis zeichnen wir über die Farbe, die die Leinwand füllt (canvas_XRGB_NOALPHA.Erase(ColorToARGB(colr, alpha));).
Damit soll gezeigt werden, dass eine auf die Leinwand (oder einen Bereich/Punkt) gezeichnete Form jedes auf der Leinwand darunter liegende Bild komplett bedeckt. D.h. es gibt auf der Leinwand keine Neuzeichnung, da die letzte Zeichnung den darunter liegenden Bereich komplett bedeckt.
canvas_XRGB_NOALPHA.Update();
Um alle gezeichneten Objekte auch auf dem Bildschirm anzeigen zu können, müssen wir den Bildschirm aktualisieren.
Auf ganz ähnliche Weise werden auch die beiden anderen Leinwände gezeichnet - die zweite Leinwand mit dem Anzeige-Modus COLOR_FORMAT_ARGB_RAW und die dritte mit 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); }
Die Leinwand und die Grafikobjekte innerhalb der Leinwände sind gezeichnet worden.
Fügen wir jetzt die Schleife hinzu, die die Transparenz der gesamten Leinwand ändern wird:
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); }
Die Transparenz für alle Leinwände wird verändert mit Hilfe der Codezeilen:
.TransparentLevelSet(transparent)
Nach Ende der Zeichnung müssen wir 'aufräumen' - also Grafik-Ressourcen entfernen.
Da wir die Grafik-Ressourcen mit Verweis auf das Chart-Objekt erzeugt haben (die CreateBitmapLabel Methode), entfernen wir die Ressource nun mittels der Destroy() Methode, die zudem auch das Chart-Objekt (Bitmap-Label) vernichtet:
canvas_XARGB_NORMALIZE.Update(); Sleep(6000); //--- finish canvas_XRGB_NOALPHA.Destroy(); canvas_ARGB_RAW.Destroy(); canvas_XARGB_NORMALIZE.Destroy(); return(0); }
Das Script, das die Transparenz ganz weich verändert, funktioniert.
Der Unterschied zwischen dem COLOR_FORMAT_ARGB_RAW und COLOR_FORMAT_ARGB_NORMALIZE Modus wird besser sichtbar, wenn man das Script zuerst im weißen Chart-Hintergrund laufen lässt und dann erst im schwarzen.
Fazit
Dieser Beitrag hat sich mit den Grundlagen der Arbeit mit Farben beschäftigt. Wir haben erfahren, wie man Objekte in einem Chart-Fenster zeichnen kann. Außerdem wurden auch die Grundlagen der Arbeit mit der CCanvas-Klasse der Standard Library und dem ARGB-Format der Farbwiedergabe mit Transparenz besprochen.
Das sind allerdings wirklich nur die Grundlagen - es gibt noch einige ganze Menge mehr zu entdecken, wie man verschiedenste grafische Effekte im MetaTrader 5 Terminal erzeugen kann. Dieser Beitrag hat sich mit Transparenz beschäftigt - und die wohl schönste Form zur Umfassung von Grafikobjekten erhält man mit der teilweisen Transparenz. Aufgrund der zweidimensionalen Natur des Monitor, ist die Transparenz im Chart eine Illusion, die mit Hilfe der Bearbeitung von Pixel erreicht werden kann.
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/1341
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.