文章 "研究CCanvas类如何绘制透明的图形对象"

 

新文章 研究CCanvas类如何绘制透明的图形对象已发布:

你是不是想要更加好看的移动平均线?你想要在终端中绘制更加漂亮的而不是简单的实心矩形吗?终端中能够绘制出更有吸引力的图形。这可以通过CCanvas类来实现,该类用于创建自定义图形对象。用这个类你能够实现透明化,混合色以及通过重叠和混合颜色产生透明的效果。

在MetaTrader5中绘图很简单,你只需要知道一些细节就行。一个细节就是终端屏幕是如何设计的。跟准确的说,我们对图形在屏幕上的输出方式 感兴趣。例如,图表能够在前景或是背景上显示。在屏幕上输出的颜色取决于显示的图表。某些图表对象可能在重叠或者交叉区域产生颜色变化。

在用CCanvas类直接绘图前,让我们分析下和颜色而处理相关的定义。例如,让我们搞清楚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的运作方式

作者:Karputov Vladimir

 
弗拉基米尔,我不擅长画油画。我有个问题有一个画布。上面有一个文本标签。为什么终端会将点击标签的事件视为点击画布的事件?能否以某种方式解决这种冲突?
 
denkir:
弗拉基米尔,我不擅长画油画。我有个问题有一个画布。上面有一个文本标签。为什么终端会将点击标签的事件视为点击画布的事件?能否以某种方式解决这一冲突?
给我代码。让我们来看看。
 
denkir:
...

有一个属性可以为此设置优先级:

OBJPROP_ZORDER- 接收图表上鼠标点击事件(CHARTEVENT_CLICK)的图形对象的优先级。默认情况下,该值在创建时设置为零,但必要时可以提高优先级。当重叠对象接收 CHARTEVENT_CLICK 事件时,只有优先级高于其他对象的对象才会接收该事件。

 

我稍后会将代码发送给您。无法为 kanvas 设置OBJPROP_ZORDER...

我找到了导致处理错误的原因...有两个画布,一个叠加在另一个之上。顶部有一个文本标签。这就是 OnChartEvent() 没有看到的原因。

 
denkir:

我稍后会将代码发送给您。无法为 kanvas 设置OBJPROP_ZORDER...

我找到了导致处理错误的原因...有两个画布,一个叠加在另一个之上。顶部有一个文本标签。这就是 OnChartEvent() 看不到的地方。

不,它能看到。这是一个普通对象,如 OBJ_BITMAP_LABEL 或 OBJ_BITMAP。

 
tol64:

可以。这是一个类似 OBJ_BITMAP_LABEL 或 OBJ_BITMAP 的普通对象。

好的,谢谢。谢谢。

为此,您需要调出 绑定 图表对象 的名称并赋予其优先级。

就是这样(摘自初始化块):

//--- 创建第一块画布
   if(!myCanvas1.CreateBitmapLabel("My canvas1",_X,_Y,Width,Height,COLOR_FORMAT_ARGB_RAW)) 
     {
      Print("Error creating base canvas: ",GetLastError());
      return INIT_FAILED;
     }
//--- 显示
   myCanvas1.Erase(XRGB(0x1F,0x1F,0x1F)); 
   myCanvas1.Update();
   string obj_name=myCanvas1.ChartObjectName();
   if(!ObjectSetInteger(0,obj_name,OBJPROP_ZORDER,0))
      return INIT_FAILED;
 

嗨,弗拉基米尔、

感谢您撰写这篇有趣的文章。

表 3 中有一个小错误。

С'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 1111 1111 1111 0000 0000 0000
应为 :
0000 0000 1111 1111 0000 0000
绿色
 
angevoyageur:

嗨,弗拉基米尔、

感谢您撰写这篇有趣的文章。

表 3 中有一个小错误。

С'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 1111 1111 1111 0000 0000 0000
应为 :
0000 0000 1111 1111 0000 0000
绿色
Спасибо за найденную ошибку.
 

问题是这样的。在图形中移动画布的最佳实现方法是什么?某种方法:

bool CUserCanvas::Move(int _new_x,int _new_y);
 
denkir:

问题是这样的。在图形中移动画布的最佳实现方法是什么?某种方法:

移动的目的是什么?在画布上重绘图形是否更好?