Изучаем класс CCanvas. Реализация прозрачности графических объектов
Оглавление
- Введение
- 1. Прозрачность (альфа-канал)
- 2. ARGB-представление цвета
- 3. Схема рисования объектов в терминале
- 4. Смешивание цветов. Результирующий цвет
- 5. Иллюзия прозрачности
- Заключение
Введение
Рисовать в терминале MetaTrader 5 несложно, нужно знать только несколько нюансов. Например, как устроен сам экран терминала. Точнее, нас будет интересовать, каким образом происходит вывод графики на экран терминала. Ведь на экране сам график может отображаться на заднем фоне, а может отображаться и на переднем плане. От такого расположения будет зависеть вывод цвета на экран. Некоторые графические объекты при выводе на экран могут изменять цвет в области пересечения.
Прежде чем приступить к непосредственному рисованию с помощью класса CCanvas, нужно узнать некоторые определения, связанные с обработкой цвета. Например, что такое прозрачность и что такое альфа-канал.
Реализация прозрачности я вообще считаю самой главной технологией, с помощью которой можно оживить картинку. Например, с помощью прозрачности можно реализовать более красивый интерфейс – с плавным перетеканием цвета или с тенью. Тень придаст объем графическому объекту и визуально смягчит края объекта.
1. Прозрачность (альфа-канал)
Мы живем в трехмерном мире и воспринимаем все предметы вокруг нас объемными. Объем окружающих нас предметов мы привыкли видеть или даже ощущать. В трехмерном мире мы можем различать, какой из объектов расположен ближе или дальше от нас.
При этом некоторые предметы могут быть полупрозрачными. Для примера возьмем прозрачный стеклянный стакан с налитой в него полупрозрачной жидкостью на синем фоне. Через стакан с жидкостью просматривается задний синий фон. Причем от степени прозрачности жидкости зависит детализация фона.
Рис. 1. Привычный взгляд на объем
Прозрачность в данном примере не виртуальная и не иллюзорная. Прозрачность в данном случае воспринимается как само собой разумеющееся.
При отображении изображения на компьютерном мониторе все иначе – пиксельная матрица мониторов двухмерная: изображение, отображаемое матрицей, имеет высоту и ширину, но не имеет третьего параметра – глубины. Именно поэтому нет возможности располагать пиксели один над другим – как бы имитировать ситуацию: нижний пиксель – это желтый фон, верхний пиксель – полупрозрачный стакан. Любое изображение трехмерного и реалистичного объекта на мониторе – это иллюзия, которая достигается игрой цвета и тени.
Рассмотрим пример изображения, которое можно разделить на два слоя: нижний слой – это синий фон и верхний слой - стакан с непрозрачной жидкостью. Как это выглядит на мониторе:
Рис. 2. Непрозрачный стакан
На результирующем изображении стакан совершенно непрозрачный. А вот для добавления (изменения) прозрачности нужно все цвета изображения перевести в ARGB-представление цвета.
2. ARGB-представление цвета
Про прозрачность стакана я не забыл. Подробно этот вопрос будет рассмотрен во второй части.
ARGB представление цвета – это 4 байтовый тип uint, в котором записаны по порядку следующие значения: альфа-канал, красный, зеленый, голубой. То есть, для придания прозрачности к цвету в формате RGB добавляют дополнительный байт со значением прозрачности - альфа-канал.
Рис. 3. ARG
Значение альфа-канала задается значением от 0 (цвет накладываемого пикселя из верхнего слоя совсем не меняет отображения нижележащего пикселя нижнего слоя) до 255 (цвет накладывается полностью и перекрывает собой цвет нижележащего пикселя). Прозрачность цвета в процентном выражении вычисляется по формуле:
То есть, чем меньше значение альфа-канала, тем более прозрачен цвет. Значит, если известна прозрачность, которую мы хотим достичь, то значение alpha можно рассчитать так:
Для преобразования цвета в ARGB представление служит функция ColorToARGB(цвет, alpha).
3. Схема рисования объектов в терминале
Чтобы лучше понимать, как происходит обработка цвета, рассмотрим схему взаимного расположения графических объектов при двух вариантах настройки графика: график на заднем плане и график сверху.
3.1. График на заднем плане
Проверить эту настройку можно так: правый клик мышкой на графике, дальше выбрать в выпадающем меню пункт "Свойства..." и перейти на вкладку "Общие".
Рис. 4. График на заднем плане
Окно графика в терминале состоит из четырех слоев. На двух крайних слоях ("Задний план" и "Передний план") можно рисовать:
Рис. 5. Схема окна графика
На заднем плане (фоне) и на переднем плане графические объекты при рисовании накладываются друг на друга в соответствии с временем своего создания.
То есть, в самом низу на слое "Задний план" и на слое "Передний план" будут находится самые "старые" графические объекты. Поверх будут накладываться более "молодые" графические объекты.
Рис. 6. Расположение объектов в зависимости от времени создания
Не все графические объекты могут накладываться полностью, без перекрашивания в местах (или областях) пересечения с нижележащими графическими объектами.
В таблице ниже собраны характеристики графических объектов, а после таблицы будет разъяснение, как накладываются объекты, которые перекрашиваются в местах пересечения.
Идентификатор | Объект | Описание | В месте пересечения с нижележащим объектом |
---|---|---|---|
OBJ_VLINE | Вертикальная линия | Не перекрашивает | |
OBJ_HLINE | Горизонтальная линия | Не перекрашивает | |
OBJ_TREND | Трендовая линия | Не перекрашивает | |
OBJ_TRENDBYANGLE | Трендовая линия по углу | Не перекрашивает | |
OBJ_CYCLES | Циклические линии | Не перекрашивает | |
OBJ_ARROWED_LINE | Объект "Линия со стрелкой" | Не перекрашивает | |
OBJ_CHANNEL | Равноудаленный канал | Не перекрашивает | |
OBJ_STDDEVCHANNEL | Канал стандартного отклонения | Не перекрашивает | |
OBJ_REGRESSION | Канал на линейной регрессии | Не перекрашивает | |
OBJ_PITCHFORK | Вилы Эндрюса | Не перекрашивает | |
OBJ_GANNLINE | Линия Ганна | Не перекрашивает | |
OBJ_GANNFAN | Веер Ганна | Не перекрашивает | |
OBJ_GANNGRID | Сетка Ганна | Не перекрашивает | |
OBJ_FIBO | Уровни Фибоначчи | Не перекрашивает | |
OBJ_FIBOTIMES | Временные зоны Фибоначчи | Не перекрашивает | |
OBJ_FIBOFAN | Веер Фибоначчи | Не перекрашивает | |
OBJ_FIBOARC | Дуги Фибоначчи | Не перекрашивает | |
OBJ_FIBOCHANNEL | Канал Фибоначчи | Не перекрашивает | |
OBJ_EXPANSION | Расширение Фибоначчи | Не перекрашивает | |
OBJ_ELLIOTWAVE5 | 5-волновка Эллиота | Не перекрашивает | |
OBJ_ELLIOTWAVE3 | 3-волновка Эллиота | Не перекрашивает | |
OBJ_RECTANGLE | Прямоугольник | Без заливки не перекрашивает, с заливкой перекрашивает | |
OBJ_TRIANGLE | Треугольник | Без заливки не перекрашивает, с заливкой перекрашивает | |
OBJ_ELLIPSE | Эллипс | Без заливки не перекрашивает, с заливкой перекрашивает | |
OBJ_ARROW_THUMB_UP | Знак "Хорошо" (большой палец вверх) | Не перекрашивает | |
OBJ_ARROW_THUMB_DOWN | Знак "Плохо" (большой палец вниз) | Не перекрашивает | |
OBJ_ARROW_UP | Знак "Стрелка вверх" | Не перекрашивает | |
OBJ_ARROW_DOWN | Знак "Стрелка вниз" | Не перекрашивает | |
OBJ_ARROW_STOP | Знак "Стоп" | Не перекрашивает | |
OBJ_ARROW_CHECK | Знак "Птичка" (галка) | Не перекрашивает | |
OBJ_ARROW_LEFT_PRICE | Левая ценовая метка | Не перекрашивает | |
OBJ_ARROW_RIGHT_PRICE | Правая ценовая метка | Не перекрашивает | |
OBJ_ARROW_BUY | Знак "Buy" | Не перекрашивает | |
OBJ_ARROW_SELL | Знак "Sell" | Не перекрашивает | |
OBJ_ARROW | Объект "Стрелка" | Не перекрашивает | |
OBJ_TEXT | Объект "Текст" | Не перекрашивает | |
OBJ_LABEL | Объект "Текстовая метка" | Не перекрашивает | |
OBJ_BUTTON | Объект "Кнопка" | Не перекрашивает | |
OBJ_CHART | Объект "График" | Не перекрашивает | |
OBJ_BITMAP | Объект "Рисунок | Не перекрашивает | |
OBJ_BITMAP_LABEL | Объект "Графическая метка" | Не перекрашивает | |
OBJ_EDIT | Объект "Поле ввода" | Не перекрашивает | |
OBJ_EVENT | Объект "Событие", соответствующий событию в экономическом календаре | Не перекрашивает | |
OBJ_RECTANGLE_LABEL | Объект "Прямоугольная метка"для создания и оформления пользовательского графического интерфейса | Не перекрашивает |
Табл. 1. Наложение и прозрачность графических объектов
На примере трех объектов типа OBJ_RECTANGLE (прямоугольники) рассмотрим алгоритм перекрашивания в местах пересечения объектов, которые перекрашиваются (файл xor.mq5).
Скрипт (файл xor.mq5) устанавливает белый цвет фона (0xFFFFFF) и рисует прямоугольники №1 и №2 синим цветом (0x0000FF) с заливкой, прямоугольник №3 отображается красным цветом (0xFF0000) с заливкой.
Рис. 7. Перекрашивание. График на заднем плане
На рисунке получились две области пересечения, в которых цвет был перекрашен:
- Область №1 – результирующий цвет (0x000000) полностью прозрачный, поэтому в области №1 видно неперекрашенные фон и график;
- Область №2 – результирующий цвет (0x00FF00).
Графические объекты типа прямоугольников при пересечении перекрашиваются по алгоритму Побитовая операция ИЛИ.
Для рис. 6 ниже дан пример перекрашивания цветов для обоих областей:
Литеральное представление | Целочисленное представление | Бинарное представление | Примечание |
---|---|---|---|
C’0,0,255’ | 0x0000FF | 0000 0000 0000 0000 1111 1111 | Синий цвет |
XOR | |||
C’0,0,225’ | 0x0000FF | 0000 0000 0000 0000 1111 1111 | Синий цвет |
= | |||
C’0,0,0’ | 0x000000 | 0000 0000 0000 0000 0000 0000 | Прозрачный |
XOR | |||
C’255,255,255’ | 0xFFFFFF | 1111 1111 1111 1111 1111 1111 | Белый цвет (фон) |
= | |||
C’255,255,255’ | 0xFFFFFF | 1111 1111 1111 1111 1111 1111 | Белый цвет |
Табл. 2. Побитовое исключающее ИЛИ для Синий + Синий + Белый
Литеральное представление | Целочисленное представление | Бинарное представление | Примечание |
---|---|---|---|
C’0,0,255’ | 0x0000FF | 0000 0000 0000 0000 1111 1111 | Синий цвет |
XOR | |||
C’255,0,0’ | 0xFF0000 | 1111 1111 0000 0000 0000 0000 | Красный цвет |
= | |||
С’255,0,255’ | 0xFF00FF | 1111 1111 0000 0000 1111 1111 | |
XOR | |||
C’255,255,255’ | 0xFFFFFF | 1111 1111 1111 1111 1111 1111 | Белый цвет (фон) |
= | |||
С’0,255,0’ | 0x00FF00 | 0000 0000 1111 1111 0000 0000 |
Табл. 3. Побитовое исключающее ИЛИ для Синий + Красный + Белый
3.2. График на переднем плане
Когда для графика включена настройка "График сверху", расположение слоев окна графика отличается от расположения, при котором график находится на заднем плане:
Рис. 8. Схема окна графика. График сверху
Когда включена настройка для графика "График сверху" два слоя для рисования "Передний план" и "Задний план" соединяются в один общий слой. Этот общий слой находится в самом низу под слоями с барами и сеткой.
3.3. Перекрашивание для "График сверху"
Как и для рис. 7, рассмотрим алгоритм перекрашивания в местах пересечения объектов, которые перекрашиваются (файл xor.mq5).
Скрипт (файл xor.mq5) устанавливает белый цвет фона (0xFFFFFF) и рисует прямоугольники №1 и №2 синим цветом (0x0000FF) с заливкой, прямоугольник №3 рисуется красным цветом (0xFF0000) с заливкой.
Рис. 9. Перекрашивание. График на переднем плане
Если сравнить рис. 7 и рис. 9, то видно, что области пересечения перекрашиваются одинаково.
4. Смешивание цветов. Результирующий цвет
Как я говорил выше, изображение прозрачности на экране монитора – это иллюзия. Игра цвета. Чтобы смоделировать рис. 2 на мониторе, осталось чуть-чуть – разобраться, а как собственно цвет с прозрачностью отобразить на мониторе? То есть, как рассчитать результирующий цвет пикселя?
Пусть на белом фоне (это фон графика в цветовой схеме "Black On White") мы хотим нарисовать на канвасе красный цвет c альфа-каналом, равным 128. В формате ARGB этот цвет будет иметь запись 0x80FF0000. Для расчета результирующего цвета нужно рассчитать цвет каждого из каналов (Red, Green, Blue).
Формула расчета результирующего цвета при наложении цвета с альфа-каналом, нормализованным к единице:
где:
- result - результирующее значение интенсивности цветового канала. Если полученное значение больше 255, то возвращается 255.
- background - значение цветового канала фона.
- foreground - значение цветового канала налагаемой картинки.
- alpha - значение альфа-канала, нормализованное к единице.
Рассчитаем результирующий цвет согласно формуле (1.3):
Альфа-канал | Альфа-канал, нормализован к "1" | R | G | B | Примечание |
---|---|---|---|---|---|
255 | 255 | 255 | Белый цвет | ||
128 | 0,5 | 255 | 0 | 0 | Красный с альфа-каналом 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 |
Табл. 4. Результаты расчета по формуле (1.3)
В результате на мониторе получится следующий цвет:
Рис. 10. Итоговый цвет
4.1. Способы обработки цвета. ENUM_COLOR_FORMAT
При создании канваса можно задать один из трех способов обработки цвета (ENUM_COLOR_FORMAT):
Идентификатор | Описание |
---|---|
COLOR_FORMAT_XRGB_NOALPHA | Компонента альфа-канала игнорируется |
COLOR_FORMAT_ARGB_RAW | Компоненты цвета не обрабатываются терминалом (должны быть корректно заданы пользователем) |
COLOR_FORMAT_ARGB_NORMALIZE | Компоненты цвета обрабатываются терминалом |
Табл. 5. Способы обработки цвета при создании канваса
COLOR_FORMAT_ARGB_NORMALIZE позволяет получать более красивую картинку за счет учета правильного наложения компонентов RGB. Расчет результирующего цвета при наложении цвета с альфа-каналом происходит по формуле (1.3).
COLOR_FORMAT_ARGB_RAW не производит контроль над переполнением RGB компонентов цветов и поэтому COLOR_FORMAT_ARGB_RAW более быстрый метод по сравнению с COLOR_FORMAT_ARGB_NORMALIZE.
Формула расчета результирующего цвета при наложении цвета с альфа-каналом, нормализованном к единице, для метода COLOR_FORMAT_ARGB_RAW:
где:
- result - результирующее значение интенсивности цветового канала. Если полученное значение больше 255, то возвращается 255.
- background - значение цветового канала фона.
- foreground - значение цветового канала налагаемой картинки.
- alpha - значение альфа-канала, нормализованное к единице.
5. Иллюзия прозрачности
Теперь можно приступить к практической реализации прозрачности.
На графике рисуем несколько прямоугольников с заливкой (скрипт "xor.mq5"). Для наглядности иллюстрации разницы методов обработки цвета поверх графика накладываем по горизонтали три канваса без их взаимного перекрытия.
Первый имеет метод обработки COLOR_FORMAT_XRGB_NOALPHA, второй - COLOR_FORMAT_ARGB_RAW и третий - COLOR_FORMAT_ARGB_NORMALIZE. Затем постепенно меняем прозрачность от 255 (полная непрозрачность) до 0 (полная прозрачность). Назовем наш скрипт "Illusion.mq5".
Видео работы скрипта "Illusion.mq5":
Рис. 11. Работа скрипта illusion.mq5
5.1. Создание скрипта "Illusion.mq5"
Добавленные или измененные участки кода будут выделяться цветом.
Пока еще пустой шаблон скрипта:
//+------------------------------------------------------------------+ //| 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() { //--- }
Добавим описание скрипта, возможность вводить параметры при запуске скрипта и подключим класс CCanvas - класс, благодаря которому мы и будем рисовать:
#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>
Для работы скрипта нужны будут несколько переменных - высота и ширина графика, высота и ширина канваса, а также вспомогательные переменные для рисования координат канваса:
#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Для получения ширины и высоты графика воспользуемся стандартными функциями:
//+------------------------------------------------------------------+ //| 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); }
Переходим непосредственно в OnStart().
Для наглядности на рис. 12 приведена схема расположения канвасов на графике, а также обозначение вспомогательных переменных для координат канвасов:
Рис. 12. Координаты на графике
Получим высоту и ширину графика, а также рассчитаем вспомогательные переменные для координат канвасов:
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; }
Имея рассчитанные ширину и высоту канваса, а также вспомогательные координаты можно приступить к рисованию.
Дальше изменим тип void функции OnStart() на int и нарисуем на первом канвасе закрашенный прямоугольник, текст с названием метода обработки цвета на данном канвасе и закрашенную окружность:
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); }
Остановлюсь подробнее на последнем вставленном коде.
canvas_XRGB_NOALPHA.CreateBitmapLabel("canvas_XRGB_NOALPHA",can_x1,can_y1,can_width-1,can_height,COLOR_FORMAT_XRGB_NOALPHA)
canvas_XRGB_NOALPHA.CreateBitmapLabel - Здесь мы создали графический ресурс, привязанный к объекту чарта.
Первый канвас создан с режимом обработки изображения COLOR_FORMAT_XRGB_NOALPHA - компонента альфа-канала при рисовании будут игнорироваться.
canvas_XRGB_NOALPHA.Erase(ColorToARGB(colr,alpha));
Заполняем весь канвас цветом в формате ARGB c прозрачностью alpha.
Так как для данного канваса задан режим обработки изображений COLOR_FORMAT_XRGB_NOALPHA - канвас будет заполнен цветом без учета альфа-канала.
canvas_XRGB_NOALPHA.TextOut((can_width)/2,can_height/2,"canvas_XRGB_NOALPHA",ColorToARGB(clrBlue,255),TA_CENTER|TA_VCENTER);
Выводим текст - тип обработки изображения для данного канваса. Цвет текста в формате ARGB и альфа-каналом равным 255, то есть цвет выводимого текста полностью непрозрачен.
Выводимый текст привязывается и по горизонтали (TA_CENTER) и по вертикали (TA_VCENTER) по центру ограничивающего прямоугольника.
canvas_XRGB_NOALPHA.FillCircle((can_width)/2,can_height/2+50,25,ColorToARGB(clr_Circle,255));
Рисуем закрашенный круг. Круг будет рисоваться поверх цвета, которым мы заполнили канвас (canvas_XRGB_NOALPHA.Erase(ColorToARGB(colr,alpha));).
Это сделано для демонстрации того, что нарисованная на канвасе фигура (или область/точка) полностью стирает под собой нижележащий рисунок на канвасе. То есть, никакого перекрашивания на канвасе не будет, т.к. последний вывод рисунка стирает полностью область под собой.
canvas_XRGB_NOALPHA.Update();
Если мы хотим, чтобы все нарисованное отобразилось на экране, нужно обновить экран.
Аналогично рисуются остальные два канваса: второй канвас с режимом отображения COLOR_FORMAT_ARGB_RAW и третий канвас с режимом отображения 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); }
Канвасы и графика внутри канвасов нарисованы.
Теперь сделаем цикл, в котором будет изменяться прозрачность всего канваса:
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); }
Изменение прозрачности для всего канваса выполняется с помощью строчек вида:
.TransparentLevelSet(transparent)
После окончания рисования нужно убрать за собой - удалить графические ресурсы.
Так как мы создавали графический ресурс с привязкой к объекту чарта (метод CreateBitmapLabel), то удаление ресурса выполним с помощью метода Destroy() - заодно удалится и объект чарта (Bitmap Label):
canvas_XARGB_NORMALIZE.Update(); Sleep(6000); //--- finish canvas_XRGB_NOALPHA.Destroy(); canvas_ARGB_RAW.Destroy(); canvas_XARGB_NORMALIZE.Destroy(); return(0); }
Скрипт, плавно изменяющий прозрачность работает.
Отмечу, что отличие режимов отображения COLOR_FORMAT_ARGB_RAW и COLOR_FORMAT_ARGB_NORMALIZE особенно хорошо видно, если скрипт запустить сначала на белом фоне графика, а потом на черном фоне.
Заключение
В статье были рассмотрены основы работы со цветом, мы узнали, как рисовать в окне графика. Также рассмотрели основы работы с классом CCanvas Стандартной библиотеки, узнали про формат представления цвета с прозрачностью ARGB.
Это только начало на пути к созданию действительно красивых эффектов для графических объектов в терминале MetaTrader 5. Еще раз хочу остановиться на прозрачности: именно частичная прозрачность придает наиболее красивую форму для окантовок графических объектов. В силу двухмерности мониторов прозрачность в графике – это иллюзия, достигаемая обработкой накладываемого пискеля.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
10%
30%
Я просто на вскидку выдал решение. Возможно, все сложнее и я не прав.
10%
Первое задерживает 40 процентов света, второе - 50. Вместе они будут задерживать 90 процентов света. Значит, оба стекла вместе будут пропускать 10 процентов света.Можно рассудить так:
Первое стекло снижает интенсивность проходящего света на 40%. Второе снижает интенсивность на 50%, но поскольку в него проходит только 60 процентов изначального света, то оно будет уполовинивать его в двое. Тогда получается 30% от исходной интенсивности.
Cогласен.
Можно рассудить так:
Первое стекло снижает интенсивность проходящего света на 40%. Второе снижает интенсивность на 50%, но поскольку в него проходит только 60 процентов изначального света, то оно будет уполовинивать его в двое. Тогда получается 30% от исходной интенсивности.
Cогласен.